Application Control

OLE requires substantial control over applications and their objects. The OLE system DLLs must be able to launch and release applications automatically, coordinate their production and modification of objects, and so on. The functions in this topic meet those requirements. In addition to being called by the OLE system DLLs, these functions must sometimes be called by applications as well.

Application Control

Name Description
AfxOleCanExitApp Indicates whether the application can terminate.
AfxOleGetMessageFilter Retrieves the application's current message filter.
AfxOleGetUserCtrl Retrieves the current user-control flag.
AfxOleSetUserCtrl Sets or clears the user-control flag.
AfxOleLockApp Increments the framework's global count of the number of active objects in an application.
AfxOleLockControl Locks the class factory of the specified control.
AfxOleUnlockApp Decrements the framework's count of the number of active objects in an application.
AfxOleUnlockControl Unlocks the class factory of the specified control.
AfxOleRegisterServerClass Registers a server in the OLE system registry.
AfxOleSetEditMenu Implements the user interface for the typename Object command.

AfxOleCanExitApp

Indicates whether the application can terminate.

BOOL AFXAPI AfxOleCanExitApp();

Return Value

Nonzero if the application can exit; otherwise 0.

Remarks

An application should not terminate if there are outstanding references to its objects. The global functions AfxOleLockApp and AfxOleUnlockApp increment and decrement, respectively, a counter of references to the application's objects. The application should not terminate when this counter is nonzero. If the counter is nonzero, the application's main window is hidden (not destroyed) when the user chooses Close from the system menu or Exit from the File menu. The framework calls this function in CFrameWnd::OnClose.

Example

// Helper exit function for automation server
BOOL CMainFrame::CanExit()
{
   if (AfxOleCanExitApp())
   {
      // No outstanding object counts - go ahead and exit
      return TRUE;
   }
   else
   {
      // There are outstanding OLE object counts...
      // hide app to give user impression that application has exited.
      ShowWindow(SW_HIDE);
      // take user out of control of the app
      AfxOleSetUserCtrl(FALSE);
      return FALSE;
   }
}

Requirements

Header: afxdisp.h

AfxOleGetMessageFilter

Retrieves the application's current message filter.

COleMessageFilter* AFXAPI AfxOleGetMessageFilter();

Return Value

A pointer to the current message filter.

Remarks

Call this function to access the current COleMessageFilter-derived object, just as you would call AfxGetApp to access the current application object.

Example

COleMessageFilter *pFilter = AfxOleGetMessageFilter();
ASSERT_VALID(pFilter);
pFilter->BeginBusyState();
// do things requiring a busy state
pFilter->EndBusyState();

 

// Another example
//CWinApp-derived class
BOOL CCMFCAutomationApp::InitInstance()
{
   CWinApp::InitInstance();

   // Initialize OLE libraries
   if (!AfxOleInit())
   {
      AfxMessageBox(IDP_OLE_INIT_FAILED);
      return FALSE;
   }

   CWinThread *pThread = AfxGetThread();
   if (pThread != NULL)
   {
      // Destroy message filter, thereby unregistering it.
      delete pThread->m_pMessageFilter;
      pThread->m_pMessageFilter = NULL;

      // Create the new message filter object.
      //CMyMessageFilter is derived from COleMessageFilter
      pThread->m_pMessageFilter = new CMyMessageFilter;
      ASSERT(AfxOleGetMessageFilter() != NULL);

      // Register the new message filter object.
      AfxOleGetMessageFilter()->Register();
   }
   //...
   //...
   //...
}

Requirements

Header: afxwin.h

AfxOleGetUserCtrl

Retrieves the current user-control flag.

BOOL AFXAPI AfxOleGetUserCtrl();

Return Value

Nonzero if the user is in control of the application; otherwise 0.

Remarks

The user is in control of the application when the user has explicitly opened or created a new document. The user is also in control if the application was not launched by the OLE system DLLs — in other words, if the user launched the application with the system shell.

Requirements

Header: afxdisp.h

AfxOleSetUserCtrl

Sets or clears the user-control flag, which is explained in the reference for AfxOleGetUserCtrl.

void AFXAPI AfxOleSetUserCtrl(BOOL bUserCtrl);

Parameters

bUserCtrl
Specifies whether the user-control flag is to be set or cleared.

Remarks

The framework calls this function when the user creates or loads a document, but not when a document is loaded or created through an indirect action such as loading an embedded object from a container application.

Call this function if other actions in your application should put the user in control of the application.

Requirements

Header: afxdisp.h

AfxOleLockApp

Increments the framework's global count of the number of active objects in the application.

void AFXAPI AfxOleLockApp();

Remarks

The framework keeps a count of the number of objects active in an application. The AfxOleLockApp and AfxOleUnlockApp functions, respectively, increment and decrement this count.

When the user attempts to close an application that has active objects — an application for which the count of active objects is nonzero — the framework hides the application from the user's view instead of completely shutting it down. The AfxOleCanExitApp function indicates whether the application can terminate.

Call AfxOleLockApp from any object that exposes OLE interfaces, if it would be undesirable for that object to be destroyed while still being used by a client application. Also call AfxOleUnlockApp in the destructor of any object that calls AfxOleLockApp in the constructor. By default, COleDocument (and derived classes) automatically lock and unlock the application.

Example

// Below is a code sample from an  Application Wizard-generated SDI
// Application with Automation support. The Application Wizard adds a
// dispatch interface to the document class. AfxOleLockApp() and
// AfxOleUnlockApp() respectively increment and decrement the
// application's object count. When the object count is equal to
// zero and if the user has not taken control of the application,
// the server is terminated.

CCMFCAutomationDoc::CCMFCAutomationDoc()
{
   EnableAutomation();
   AfxOleLockApp();
}

CCMFCAutomationDoc::~CCMFCAutomationDoc()
{
   AfxOleUnlockApp();
}

Requirements

Header: afxdisp.h

AfxOleUnlockApp

Decrements the framework's count of active objects in the application.

void AFXAPI AfxOleUnlockApp();

Remarks

See AfxOleLockApp for further information.

When the number of active objects reaches zero, AfxOleOnReleaseAllObjects is called.

Example

See the example for AfxOleLockApp.

Requirements

Header: afxdisp.h

AfxOleLockControl

Locks the class factory of the specified control so that dynamically created data associated with the control remains in memory.

Syntax

BOOL AFXAPI AfxOleLockControl(  REFCLSID clsid  );
BOOL AFXAPI AfxOleLockControl( LPCTSTR lpszProgID );

Parameters

clsid
The unique class ID of the control.

lpszProgID
The unique program ID of the control.

Return Value

Nonzero if the class factory of the control was successfully locked; otherwise 0.

Remarks

This can significantly speed up display of the controls. For example, once you create a control in a dialog box and lock the control with AfxOleLockControl, you do not need to create and kill it again every time the dialog is shown or destroyed. If the user opens and closes a dialog box repeatedly, locking your controls can significantly enhance performance. When you are ready to destroy the control, call AfxOleUnlockControl.

Example

// Starts and locks control's (Microsoft Calendar) class factory.
// Control will remain in memory for lifetime of
// application or until AfxOleUnlockControl() is called.

AfxOleLockControl(_T("MSCAL.Calendar"));

Requirements

Header: afxwin.h

AfxOleRegisterServerClass

This function allows you to register your server in the OLE system registry.

BOOL AFXAPI AfxOleRegisterServerClass(
    REFCLSID clsid,
    LPCTSTR lpszClassName,
    LPCTSTR lpszShortTypeName,
    LPCTSTR lpszLongTypeName,
    OLE_APPTYPE nAppType = OAT_SERVER,
    LPCTSTR* rglpszRegister = NULL,
    LPCTSTR* rglpszOverwrite = NULL);

Parameters

clsid
Reference to the server's OLE class ID.

lpszClassName
Pointer to a string containing the class name of the server's objects.

lpszShortTypeName
Pointer to a string containing the short name of the server's object type, such as "Chart."

lpszLongTypeName
Pointer to a string containing the long name of the server's object type, such as "Microsoft Excel 5.0 Chart."

nAppType
A value, taken from the OLE_APPTYPE enumeration, specifying the type of OLE application. Possible values are the following:

  • OAT_INPLACE_SERVER Server has full server user-interface.

  • OAT_SERVER Server supports only embedding.

  • OAT_CONTAINER Container supports links to embeddings.

  • OAT_DISPATCH_OBJECT IDispatch-capable object.

rglpszRegister
Array of pointers to strings representing the keys and values to be added to the OLE system registry if no existing values for the keys are found.

rglpszOverwrite
Array of pointers to strings representing the keys and values to be added to the OLE system registry if the registry contains existing values for the given keys.

Return Value

Nonzero if the server class is successfully registered; otherwise 0.

Remarks

Most applications can use COleTemplateServer::Register to register the application's document types. If your application's system-registry format does not fit the typical pattern, you can use AfxOleRegisterServerClass for more control.

The registry consists of a set of keys and values. The rglpszRegister and rglpszOverwrite arguments are arrays of pointers to strings, each consisting of a key and a value separated by a NULL character ( '\0'). Each of these strings can have replaceable parameters whose places are marked by the character sequences %1 through %5.

The symbols are filled in as follows:

Symbol Value
%1 Class ID, formatted as a string
%2 Class name
%3 Path to executable file
%4 Short type name
%5 Long type name

Requirements

Header: afxdisp.h

AfxOleSetEditMenu

Implements the user interface for the typename Object command.

void AFXAPI AfxOleSetEditMenu(
    COleClientItem* pClient,
    CMenu* pMenu,
    UINT iMenuItem,
    UINT nIDVerbMin,
    UINT nIDVerbMax = 0,
    UINT nIDConvert = 0);

Parameters

pClient
A pointer to the client OLE item.

pMenu
A pointer to the menu object to be updated.

iMenuItem
The index of the menu item to be updated.

nIDVerbMin
The command ID that corresponds to the primary verb.

nIDVerbMax
The command ID that corresponds to the last verb.

nIDConvert
ID for the Convert menu item.

Remarks

If the server recognizes only a primary verb, the menu item becomes "verb typename Object" and the nIDVerbMin command is sent when the user chooses the command. If the server recognizes several verbs, then the menu item becomes " typename Object" and a submenu listing all the verbs appears when the user chooses the command. When the user chooses a verb from the submenu, nIDVerbMin is sent if the first verb is chosen, nIDVerbMin + 1 is sent if the second verb is chosen, and so forth. The default COleDocument implementation automatically handles this feature.

You must have the following statement in your client's application resource script (.RC) file:

#include <afxolecl.rc>

Requirements

Header: afxole.h

AfxOleUnlockControl

Unlocks the class factory of the specified control.

Syntax

BOOL AFXAPI AfxOleUnlockControl( REFCLSID clsid );
BOOL AFXAPI AfxOleUnlockControl( LPCTSTR lpszProgID );

Parameters

clsid
The unique class ID of the control.

lpszProgID
The unique program ID of the control.

Return Value

Nonzero if the class factory of the control was successfully unlocked; otherwise 0.

Remarks

A control is locked with AfxOleLockControl, so that dynamically created data associated with the control remains in memory. This can significantly speed up display of the control because the control need not be created and destroyed every time it is displayed. When you are ready to destroy the control, call AfxOleUnlockControl.

Example

// Unlock control's (Microsoft Calendar Control) class factory.

AfxOleUnlockControl(_T("MSCAL.Calendar"));

Requirements

Header: afxwin.h

See also

Macros and Globals