在DLL中使用资源
2009-10-06 20:29:53 来源:WEB开发网通过上面的讲解,相信你已经知道该语句的作用了。在函数ShowDlg的第一行加上这么一句后,每次调用DLL的应用程序使用该函数的时候,MFC库都会自动切换当前模块状态,这样就保证了资源读取的正确性。
AFX_MANAGE_STATE(AfxGetStaticModuleState());是自动切换当前模块状态,也可以通过使用AfxGetResourceHandle和AfxSetResourceHandle来手动切换当前模块状态。具体使用方法如下:
在上述例子的第三步的ShowDlg函数的第一条语句前加上如下语句(要确保该语句在函数实现的第一行):
HINSTANCE save_hInstance = AfxGetResourceHandle();
AfxSetResourceHandle(theApp.m_hInstance);
在调用对话框成功之后,也就是dlg.DoModal();之后,添加:
AfxSetResourceHandle(save_hInstance);
这种方法在进入ShowDlg函数之后,通过AfxGetResourceHandle来获得并保存当前状态模块的句柄。然后获得DLL模块的句柄theApp.m_hInstance(当然,也可以使用GetModuleHandle函数来获得DLL模块的句柄),并使用AfxSetResourceHandle函数来将其设置为当前状态状态。最后在调用对话框成功之后再用恢复AfxSetResourceHandle资源句柄,将当前模块状态恢复。
这样做有些麻烦,但是有一点好处是可以在完成使用资源的任务之后就可以立即恢复资源句柄。而AFX_MANAGE_STATE(AfxGetStaticModuleState());的方法只能等函数的作用空间结束之后才恢复资源句柄。由于可执行文件必须重画工具条等原因,因此建议只要有可能就必须恢复资源句柄,否则可能会遇到许多问题。比如说,如果用户移动DLL的对话框,而此时资源句柄仍然为DLL的资源,那么程序就会崩溃。最好的恢复句柄的时机在对话框响应WM_INITDIALOG消息的时候,因为这时对话框的模板等已经读出了。
对于MFC Extension DLL(using shared MFC DLL)类型的MFC DLL,切换当前模块状态的方法与Regular DLL using shared MFC DLL类型的MFC DLL所使用的方法很相似,这里不再举例实现。二者不同的地方如下:
在MFC扩展DLL中使用AFX_MANAGE_STATE(AfxGetStaticModuleState());时,会产生如下错误:
mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in dllextend.obj
mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in dllextend.obj
mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in dllextend.obj
因此在MFC扩展DLL中需要将AFX_MANAGE_STATE(AfxGetStaticModuleState());换成AFX_MANAGE_STATE(AfxGetAppModuleState());才能正确切换当前模块状态。
在MFC扩展DLL中使用AfxGetResourceHandle和AfxSetResourceHandle的方法与在Regular DLL using shared MFC DLL类型的MFC DLL中所使用的方法相同。并且,DLL模块的句柄可以通过MFC提供的DlgextentDLL这个结构的hModule成员来获得。即使用AfxSetResourceHandle(DlgextentDLL.hModule);语句。
当然,对于动态链接到MFC的DLL,也可以在调用该DLL的MFC应用程序中使用AfxGetResourceHandle和AfxSetResourceHandle两个函数来切换当前状态模块。该DLL模块的句柄可以用GetModuleHandle函数来获得。在此不再赘述。
更多精彩
赞助商链接