用于管理 DLL 的宏和函数

名称 描述
AFX_EXT_CLASS 导出类。
AFX_MANAGE_STATE 保护 DLL 中的导出函数。
AfxOleInitModule 从动态链接到 MFC 的常规 MFC DLL 提供 OLE 支持。
AfxNetInitModule 从动态链接到 MFC 的常规 MFC DLL 提供 MFC 套接字支持。
AfxGetAmbientActCtx 获取每个模块状态标志的当前状态。
AfxGetStaticModuleState 在初始化之前设置模块状态,并在清理后还原上一个模块状态。
AfxInitExtensionModule 初始化 DLL。
AfxSetAmbientActCtx 设置每个模块的状态标志,该标志影响 MFC 的 WinSxS 行为。
AfxTermExtensionModule 允许 MFC 在每个进程与 DLL 分离时清理 MFC 扩展 DLL。

AFX_EXT_CLASS

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 函数中需要执行两项操作:

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

要求

标头:<afxdll_.h>

AfxSetAmbientActCtx

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

语法

void AFXAPI AfxSetAmbientActCtx(BOOL bSet);

参数

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 结构的引用。

bAll
如果为 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 模块的状态数据