MFC资源句柄切换

时间:2021-08-12 05:05:02

1.问题引人:

Regular DLL分为两类:

  (1)静态链接到MFC 的规则DLL

  静态链接到MFC的规则DLL与MFC库(包括MFC扩展 DLL)静态链接,将MFC库的代码直接生成在.dll文件中。在调用这种DLL的接口时,MFC使用DLL的资源。因此,在静态链接到MFC 的规则DLL中不需要进行模块状态的切换。

  使用这种方法生成的规则DLL其程序较大,也可能包含重复的代码。

  (2)动态链接到MFC 的规则DLL(shared dll)

  动态链接到MFC 的规则DLL 可以和使用它的可执行文件同时动态链接到 MFC DLL 和任何MFC扩展 DLL。在使用了MFC共享库的时候,默认情况下,MFC使用主应用程序的资源句柄来加载资源模板。这样,当DLL和应用程序中存在相同ID的资源时(即所谓的资源重复问题),系统可能不能获得正确的资源。因此,对于共享MFC DLL的规则DLL,我们必须进行模块切换以使得MFC能够找到正确的资源模板。

2.问题解决:

方法一 在DLL接口函数中使用:

AFX_MANAGE_STATE(AfxGetStaticModuleState());

方法二 在DLL接口函数中使用:

AfxGetResourceHandle();

AfxSetResourceHandle(HINSTANCE xxx);


AfxGetResourceHandle用于获取当前资源模块句柄,而AfxSetResourceHandle则用于设置程序目前要使用的资源模块句柄。


通过AfxGetResourceHandle和AfxSetResourceHandle的合理变更,我们能够灵活地设置程序的资源模块句柄,而方法一则只能在DLL接口函数退出的时候才会恢复模块句柄。方法二则不同


方法三 由应用程序自身切换

资源模块的切换除了可以由DLL接口函数完成以外,由应用程序自身也能完成

方法三中的Win32函数GetModuleHandle可以根据DLL的文件名获取DLL的模块句柄。如果需要得到EXE模块的句柄,则应调用带有Null参数的GetModuleHandle。

而将应用程序的OnCalldllButton函数改为:

void CSharedDllCallDlg::OnCalldllButton()

{

//方法3:由应用程序本身进行状态切换


//获取EXE模块句柄

HINSTANCE exe_hInstance = GetModuleHandle(NULL);

//或者HINSTANCE exe_hInstance = AfxGetResourceHandle();


//获取DLL模块句柄

HINSTANCE dll_hInstance = GetModuleHandle("SharedDll.dll");


AfxSetResourceHandle(dll_hInstance); //切换状态

ShowDlg(); //此时显示的是DLL的对话框

AfxSetResourceHandle(exe_hInstance); //恢复状态


//资源模块恢复后再调用ShowDlg

ShowDlg(); //此时显示的是EXE的对话框


}

原文: http://pcedu.pconline.com.cn/empolder/gj/vc/0509/703607.html