我们将DLL中的接口函数ShowDlg改为:
void ShowDlg(void)
{
//方法1:在函数开始处变更,在函数结束时恢复
//将AFX_MANAGE_STATE(AfxGetStaticModuleState());作为接口函数的第一//条语句进行模块状态切换
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CDialog dlg(IDD_DLL_DIALOG);//打开ID为2000的对话框
dlg.DoModal();
}
这次我们再点击EXE程序中的“调用DLL”按钮,弹出的是DLL中的如图13的对话框!嘿嘿,弹出了正确的对话框资源。
AfxGetStaticModuleState是一个函数,其原型为:
AFX_MODULE_STATE* AFXAPI AfxGetStaticModuleState( );
该函数的功能是在栈上(这意味着其作用域是局部的)创建一个AFX_MODULE_STATE类(模块全局数据也就是模块状态)的实例,对其进行设置,并将其指针pModuleState返回。
AFX_MODULE_STATE类的原型如下:
// AFX_MODULE_STATE (global data for a module)
class AFX_MODULE_STATE : public CNoTrackObject
{
public:
#ifdef _AFXDLL
AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion);
AFX_MODULE_STATE(BOOL bDLL, WNDPROC pfnAfxWndProc, DWORD dwVersion,BOOL bSystem);
#else
AFX_MODULE_STATE(BOOL bDLL);
#endif
~AFX_MODULE_STATE();
CWinApp* m_pCurrentWinApp;
HINSTANCE m_hCurrentInstanceHandle;
HINSTANCE m_hCurrentResourceHandle;
LPCTSTR m_lpszCurrentAppName;
… //省略后面的部分
}
AFX_MODULE_STATE类利用其构造函数和析构函数进行存储模块状态现场及恢复现场的工作,类似汇编中call指令对pc指针和sp寄存器的保存与恢复、中断服务程序的中断现场压栈与恢复以及操作系统线程调度的任务控制块保存与恢复。
许多看似不着边际的知识点居然有惊人的相似!