用于管理 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
,因为 COleControlModule
的 InitInstance
成员函数调用 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);
参数
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>