对于 DLL 的导出函数,使用 AFX_MANAGE_STATE 宏在从 DLL 模块切换到调用应用程序的 DLL 时保持适当的全局状态。
调用时,此宏会设置 pModuleState
一个指向包含模块全局数据的结构的指针 AFX_MODULE_STATE
,作为函数包含作用域的其余部分的有效模块状态。 离开包含宏的范围后,将自动还原以前的有效模块状态。
此切换是通过在堆栈上构造类的 AFX_MODULE_STATE
实例来实现的。 在其构造函数中,此类获取指向当前模块状态的指针,并将其存储在成员变量中,然后将它设置为 pModuleState
新的有效模块状态。 在其析构函数中,此类将存储在其成员变量中的指针还原为有效模块状态。
如果有导出的函数(例如在 DLL 中启动对话框的函数),则需要将以下代码添加到函数的开头:
AFX_MANAGE_STATE(AfxGetStaticModuleState())
这会将当前模块状态与从 AfxGetStaticModuleState 返回的状态交换到当前作用域的末尾。
如果未使用宏, AFX_MANAGE_STATE
则 DLL 中的资源出现问题。 默认情况下,MFC 使用主应用程序的资源句柄来加载资源模板。 此模板实际上存储在 DLL 中。 根本原因是宏尚未切换 AFX_MANAGE_STATE
MFC 的模块状态信息。 资源句柄从 MFC 的模块状态恢复。 不切换模块状态会导致使用错误的资源句柄。
AFX_MANAGE_STATE
不需要放入 DLL 中的每个函数中。 例如,可以在应用程序中AFX_MANAGE_STATE
由 MFC 代码调用,InitInstance
而无需因为 MFC 会在返回后InitInstance
自动移动模块状态,然后在返回后切换它InitInstance
。 所有消息映射处理程序也是如此。 常规 MFC DLL 实际上具有特殊的主窗口过程,用于在路由任何消息之前自动切换模块状态。