แก้ไข

แชร์ผ่าน


Macros and functions for managing DLLs

Name Description
AFX_EXT_CLASS] Exports classes.
AFX_MANAGE_STATE Protect an exported function in a DLL.
AfxOleInitModule Provides OLE support from a regular MFC DLL that is dynamically linked to MFC.
AfxNetInitModule Provides MFC Sockets support from a regular MFC DLL that is dynamically linked to MFC.
AfxGetAmbientActCtx Gets the current state of the per-module state flag.
AfxGetStaticModuleState Sets the module state before initialization and restores the previous module state after cleanup.
AfxInitExtensionModule Initializes the DLL.
AfxSetAmbientActCtx set the per-module state flag, which affects the WinSxS behavior of MFC.
AfxTermExtensionModule Allows MFC to clean up the MFC extension DLL when each process detaches from the DLL.

AFX_EXT_CLASS

MFC extension DLLs use the macro AFX_EXT_CLASS to export classes; the executables that link to the MFC extension DLL use the macro to import classes.

Remarks

With the AFX_EXT_CLASS macro, the same header file(s) used to build the MFC extension DLL can be used with the executables that link to the DLL.

In the header file for your DLL, add the AFX_EXT_CLASS keyword to the declaration of your class as follows:

class AFX_EXT_CLASS CMyClass : public CDocument
{
// <body of class>
};

For more information, see Export and import using AFX_EXT_CLASS.

Requirements

Header: <afxv_dll.h>

AFX_MANAGE_STATE

Call this macro to protect an exported function in a DLL.

Syntax

AFX_MANAGE_STATE(AFX_MODULE_STATE* pModuleState )

Parameters

pModuleState
A pointer to an AFX_MODULE_STATE structure.

Remarks

When this macro is invoked, pModuleState is the effective module state for the rest of the immediate containing scope. Upon leaving the scope, the previous effective module state will be automatically restored.

The AFX_MODULE_STATE structure contains global data for the module, that is, the portion of the module state that is pushed or popped.

By default, MFC uses the resource handle of the main application to load the resource template. If you have an exported function in a DLL, such as one that launches a dialog box in the DLL, the resource template is stored in the DLL module. Be sure to switch the module state for the correct handle to be used. You can switch the state by adding the following code to the beginning of the function:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

This macro swaps the current module state with the state returned from AfxGetStaticModuleState until the end of the current scope.

For more information on module states and MFC, see Managing the state data of MFC modules and Technical Note 58.

Note

When MFC creates an activation context for an assembly, it uses AfxWinInit to create the context and AFX_MANAGE_STATE to activate and deactivate it. Note also that AFX_MANAGE_STATE is enabled for static MFC libraries, as well as MFC DLLs, in order to allow MFC code to execute in the proper activation context selected by the User DLL. For more information, see Support for Activation Contexts in the MFC Module State.

Requirements

Header: <afxstat_.h>

AfxOleInitModule

For OLE support from a regular MFC DLL that is dynamically linked to MFC, call this function in your regular MFC DLL's CWinApp::InitInstance function to initialize the MFC OLE DLL.

Syntax

void AFXAPI AfxOleInitModule( );

Remarks

The MFC OLE DLL is an MFC extension DLL; in order for an MFC extension DLL to get wired into a CDynLinkLibrary chain, it must create a CDynLinkLibrary object in the context of every module that will be using it. AfxOleInitModule creates the CDynLinkLibrary object in your regular MFC DLL's context so that it gets wired into the CDynLinkLibrary object chain of the regular MFC DLL.

If you're building an OLE control and are using COleControlModule, you shouldn't call AfxOleInitModule because the InitInstance member function for COleControlModule calls AfxOleInitModule.

Requirements

Header: <afxdll_.h>

AfxNetInitModule

For MFC Sockets support from a regular MFC DLL that is dynamically linked to MFC, add a call to this function in your regular MFC DLL's CWinApp::InitInstance function to initialize the MFC Sockets DLL.

Syntax

void AFXAPI AfxNetInitModule( );

Remarks

The MFC Sockets DLL is an MFC extension DLL; in order for an MFC extension DLL to get wired into a CDynLinkLibrary chain, it must create a CDynLinkLibrary object in the context of every module that will be using it. AfxNetInitModule creates the CDynLinkLibrary object in your regular MFC DLL's context so that it gets wired into the CDynLinkLibrary object chain of the regular MFC DLL.

Requirements

Header: <afxdll_.h>

AfxGetAmbientActCtx

Use this function to get the current state of the per-module state flag, which affects the WinSxS behavior of MFC.

Syntax

BOOL AFXAPI AfxGetAmbientActCtx();

Return Value

Module state flag current value.

Remarks

When the flag is set (which is the default) and a thread enters an MFC module (see AFX_MANAGE_STATE), the context of the module is activated.

If the flag isn't set, the context of the module isn't activated on entry.

The context of a module is determined from its manifest, often embedded in module resources.

Requirements

Header: <afxcomctl32.h>

AfxGetStaticModuleState

Call this function to set the module state before initialization and to restore the previous module state after cleanup.

Syntax

AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );

Return Value

A pointer to an AFX_MODULE_STATE structure.

Remarks

The AFX_MODULE_STATE structure contains global data for the module, that is, the portion of the module state that is pushed or popped.

By default, MFC uses the resource handle of the main application to load the resource template. If you have an exported function in a DLL, such as one that launches a dialog box in the DLL, the resource template is stored in the DLL module. Be sure to switch the module state for the correct handle to be used. You can switch the state by adding the following code to the beginning of the function:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

This macro swaps the current module state with the state returned from AfxGetStaticModuleState until the end of the current scope.

For more information on module states and MFC, see Managing the state data of MFC modules and Technical Note 58.

Requirements

Header: <afxstat_.h>

AfxInitExtensionModule

Call this function in an MFC extension DLL's DllMain to initialize the DLL.

Syntax

BOOL AFXAPI AfxInitExtensionModule( AFX_EXTENSION_MODULE& state,  HMODULE hModule );

Parameters

state
A reference to the AFX_EXTENSION_MODULE Structure structure that will contain the state of the MFC extension DLL module after the initialization. The state includes a copy of the runtime class objects that have been initialized by the MFC extension DLL as part of normal static object construction executed before DllMain is entered.

hModule
A handle of the MFC extension DLL module.

Return Value

TRUE if the MFC extension DLL is successfully initialized; otherwise, FALSE.

Remarks

For example:

static AFX_EXTENSION_MODULE NVC_MFC_DLLDLL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    // Remove this if you use lpReserved
    UNREFERENCED_PARAMETER(lpReserved);

    if (dwReason == DLL_PROCESS_ATTACH)
    {
        TRACE0("NVC_MFC_DLL.DLL Initializing!\n");

        // MFC extension DLL one-time initialization
        if (!AfxInitExtensionModule(NVC_MFC_DLLDLL, hInstance))
            return 0;
...

AfxInitExtensionModule makes a copy of the DLL's HMODULE and captures the DLL's runtime-classes (CRuntimeClass structures) and also its object factories (COleObjectFactory objects) for use later when the CDynLinkLibrary object is created. MFC extension DLLs need to do two things in their DllMain function:

You can call AfxTermExtensionModule to clean up the MFC extension DLL when each process detaches from the MFC extension DLL (which happens when the process exits, or when the DLL is unloaded by an AfxFreeLibrary call).

Requirements

Header: <afxdll_.h>

AfxSetAmbientActCtx

Use this function to set the per-module state flag, which affects the WinSxS behavior of MFC.

Syntax

void AFXAPI AfxSetAmbientActCtx(BOOL bSet);

Parameters

bSet
New value of the module state flag.

Remarks

When the flag is set (which is the default) and a thread enters an MFC module (see AFX_MANAGE_STATE), the context of the module is activated. If the flag isn't set, the context of the module isn't activated on entry. The context of a module is determined from its manifest, often embedded in module resources.

Example

BOOL CMFCListViewApp::InitInstance()
{
   AfxSetAmbientActCtx(FALSE);
   // Remainder of function definition omitted.
}

Requirements

Header: <afxcomctl32.h>

AfxTermExtensionModule

Call this function to allow MFC to clean up the MFC extension DLL when each process detaches from the DLL (which happens when the process exits, or when the DLL is unloaded by an AfxFreeLibrary call).

Syntax

void AFXAPI AfxTermExtensionModule( AFX_EXTENSION_MODULE& state, BOOL bAll = FALSE );

Parameters

state
A reference to the AFX_EXTENSION_MODULE structure that contains the state of MFC extension DLL module.

bAll
If TRUE, clean up all MFC extension DLL modules. Otherwise, clean up only the current DLL module.

Remarks

AfxTermExtensionModule will delete any local storage attached to the module and remove any entries from the message map cache. For example:

static AFX_EXTENSION_MODULE NVC_MFC_DLLDLL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    // Remove this if you use lpReserved
    UNREFERENCED_PARAMETER(lpReserved);

    if (dwReason == DLL_PROCESS_ATTACH)
    {
        TRACE0("NVC_MFC_DLL.DLL Initializing!\n");

        // MFC extension DLL one-time initialization
        if (!AfxInitExtensionModule(NVC_MFC_DLLDLL, hInstance))
            return 0;

        new CMyDynLinkLibrary(NVC_MFC_DLLDLL);

    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        TRACE0("NVC_MFC_DLL.DLL Terminating!\n");

        // Terminate the library before destructors are called
        AfxTermExtensionModule(NVC_MFC_DLLDLL);
    }
    return 1;   // ok
}

If your application loads and frees MFC extension DLLs dynamically, be sure to call AfxTermExtensionModule. Since most MFC extension DLLs aren't dynamically loaded (normally, they're linked via their import libraries), the call to AfxTermExtensionModule usually isn't necessary.

MFC extension DLLs need to call AfxInitExtensionModule in their DllMain. If the DLL exports CRuntimeClass objects or has its own custom resources, you also need to create a CDynLinkLibrary object in DllMain.

Requirements

Header: <afxdll_.h>

See also

Macros and globals
AfxMessageBox
Managing the state data of MFC modules