MFC 扩展 DLL 使用宏 AFX_EXT_CLASS 导出类;链接到 MFC 扩展 DLL 的可执行文件使用该宏导入类。

使用 AFX_EXT_CLASS 宏时,用于生成 MFC 扩展 DLL 的相同头文件可以与链接到 DLL 的可执行文件一起使用。

在 DLL 的头文件中,将 AFX_EXT_CLASS 关键字添加到类的声明中,如下所示:

class AFX_EXT_CLASS CMyClass : public CDocument
// <body of class>

有关详细信息,请参阅使用 AFX_EXT_CLASS 导出和导入

标头:<afxv_dll.h>

AFX_MANAGE_STATE

调用此宏以保护 DLL 中的导出函数。

AFX_MANAGE_STATE(AFX_MODULE_STATE* pModuleState )

pModuleState
指向 AFX_MODULE_STATE 结构的指针。

调用此宏时,pModuleState 是当前包含范围的其余部分的有效模块状态。 一旦离开此范围,之前的有效模块状态将会自动还原。

AFX_MODULE_STATE 结构包含模块的全局数据,即已推送或弹出的模块状态部分。

默认情况下,MFC 使用主应用程序的资源句柄来加载资源模板。 如果 DLL 中有导出的函数,例如在 DLL 中启动对话框的函数,资源模板将存储在 DLL 模块中。 请务必切换要使用的正确句柄的模块状态。 可以通过将以下代码添加到函数开头来切换状态:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

此宏会将当前模块状态与从 AfxGetStaticModuleState 返回的状态交换,直至当前范围的末尾。

有关模块状态和 MFC 的详细信息,请参阅管理 MFC 模块的状态数据技术说明 58

MFC 为程序集创建激活上下文时,使用 AfxWinInit 创建上下文,使用 AFX_MANAGE_STATE 激活和停用上下文。 另请注意,为静态 MFC 库以及 MFC DLL 启用了 AFX_MANAGE_STATE,以使 MFC 代码在用户 DLL 选择的正确激活上下文中执行。 有关详细信息,请参阅支持 MFC 模块状态中的激活上下文

标头:<afxstat_.h>

AfxOleInitModule

对于来自动态链接到 MFC 的常规 MFC DLL 的 OLE 支持,请在常规 MFC DLL 的 CWinApp::InitInstance 函数中调用此函数以初始化 MFC OLE DLL。

void AFXAPI AfxOleInitModule( );

MFC OLE DLL 是 MFC 扩展 DLL;若要使 MFC 扩展 DLL 连接到 CDynLinkLibrary 链中,它必须在将使用 MFC 扩展 DLL 的每个模块的上下文中创建一个 CDynLinkLibrary 对象。 AfxOleInitModule 在常规 MFC DLL 上下文中创建 CDynLinkLibrary 对象,以便将其连接到常规 MFC DLL 的 CDynLinkLibrary 对象链中。

如果你正在生成 OLE 控件并使用 COleControlModule,则不应调用 AfxOleInitModule,因为 COleControlModuleInitInstance 成员函数调用 AfxOleInitModule

标头:<afxdll_.h>

AfxNetInitModule

对于来自动态链接到 MFC 的常规 MFC DLL 的 MFC 套接字支持,请在常规 MFC DLL 的 CWinApp::InitInstance 函数中调用此函数以初始化 MFC 套接字 DLL。

void AFXAPI AfxNetInitModule( );

MFC 套接字 DLL 是 MFC 扩展 DLL;若要使 MFC 扩展 DLL 连接到 CDynLinkLibrary 链中,它必须在将使用 MFC 扩展 DLL 的每个模块的上下文中创建一个 CDynLinkLibrary 对象。 AfxNetInitModule 在常规 MFC DLL 上下文中创建 CDynLinkLibrary 对象,以便将其连接到常规 MFC DLL 的 CDynLinkLibrary 对象链中。

标头:<afxdll_.h>

AfxGetAmbientActCtx

使用以下函数可获取每个模块的状态标志的当前状态,该标志影响 MFC 的 WinSxS 行为。

BOOL AFXAPI AfxGetAmbientActCtx();

模块状态标志当前值。

当设置了该标志(默认值)并且线程进入了 MFC 模块时(请参阅 AFX_MANAGE_STATE),将激活模块的上下文。

如果未设置该标志,则线程进入时不会激活模块的上下文。

模块的上下文从其清单确定,通常会嵌入模块资源。

标头:<afxcomctl32.h>

AfxGetStaticModuleState

调用此函数以在初始化之前设置模块状态,并在清理后还原上一个模块状态。

AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );

指向 AFX_MODULE_STATE 结构的指针。

AFX_MODULE_STATE 结构包含模块的全局数据,即已推送或弹出的模块状态部分。

默认情况下,MFC 使用主应用程序的资源句柄来加载资源模板。 如果 DLL 中有导出的函数,例如在 DLL 中启动对话框的函数,资源模板将存储在 DLL 模块中。 请务必切换要使用的正确句柄的模块状态。 可以通过将以下代码添加到函数开头来切换状态:

AFX_MANAGE_STATE(AfxGetStaticModuleState( ));

此宏会将当前模块状态与从 AfxGetStaticModuleState 返回的状态交换,直至当前范围的末尾。

有关模块状态和 MFC 的详细信息,请参阅管理 MFC 模块的状态数据技术说明 58

标头:<afxstat_.h>

AfxInitExtensionModule

在 MFC 扩展 DLL 的 DllMain 中调用此函数以初始化 DLL。

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

state
AFX_EXTENSION_MODULE Structure 结构的引用,该结构将包含初始化后 MFC 扩展 DLL 模块的状态。 该状态包括已由 MFC 扩展 DLL 初始化的运行时类对象的副本,作为在进入 DllMain 之前执行的正常静态对象构造的一部分。

hModule
MFC 扩展 DLL 模块的句柄。

如果成功初始化 MFC 扩展 DLL,则返回 TRUE;否则返回 FALSE

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 创建 DLL 的 HMODULE 的副本,并捕获 DLL 的运行时类(CRuntimeClass 结构),以及其对象工厂(COleObjectFactory 对象),以便稍后在创建 CDynLinkLibrary 对象时使用。 MFC 扩展 DLL 在其 DllMain 函数中需要执行两项操作:

  • 调用 AfxInitExtensionModule 并检查返回值。

  • 如果 DLL 将导出 CRuntimeClass Structure 对象或有自己的自定义资源,请创建一个 CDynLinkLibrary 对象。

    可以调用 AfxTermExtensionModule 以在每个进程从 MFC 扩展 DLL 分离时清理 MFC 扩展 DLL(进程退出时或通过 AfxFreeLibrary 调用卸载 DLL 时发生)。

    标头:<afxdll_.h>

    AfxSetAmbientActCtx

    使用以下函数可设置每个模块的状态标志,该标志影响 MFC 的 WinSxS 行为。

    void AFXAPI AfxSetAmbientActCtx(BOOL bSet);
    模块状态标志的新值。

    当设置了该标志(默认值)并且线程进入了 MFC 模块时(请参阅 AFX_MANAGE_STATE),将激活模块的上下文。 如果未设置该标志,则线程进入时不会激活模块的上下文。 模块的上下文从其清单确定,通常会嵌入模块资源。

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

    标头:<afxcomctl32.h>

    AfxTermExtensionModule

    调用此函数以允许 MFC 在每个进程从 DLL 分离时清理 MFC 扩展 DLL(进程退出时或通过 AfxFreeLibrary 调用卸载 DLL 时发生)。

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

    state
    对包含 MFC 扩展 DLL 模块状态的 AFX_EXTENSION_MODULE 结构的引用。

    如果为 TRUE,则清理所有 MFC 扩展 DLL 模块。 否则,仅清理当前 DLL 模块。

    AfxTermExtensionModule 将删除附加到模块的所有本地存储,并从消息映射缓存中移除所有条目。 例如:

    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
    

    如果应用程序动态加载并释放 MFC 扩展 DLL,请务必调用 AfxTermExtensionModule。 由于大多数 MFC 扩展 DLL 不会动态加载(它们通常通过导入库链接),因此通常不需要调用 AfxTermExtensionModule

    MFC 扩展 DLL 需要在其 DllMain 中调用 AfxInitExtensionModule。 如果 DLL 导出 CRuntimeClass 对象或有自己的自定义资源,则还需要在 DllMain 中创建 CDynLinkLibrary 对象。

    标头:<afxdll_.h>

    宏和全局函数
    AfxMessageBox
    管理 MFC 模块的状态数据

  •