AFX_MANAGE_STATE(AfxGetStaticModuleState());问题

 

写一个MFC规则动态链接库(regularDll.dll),在这个里面写一个函数
extern "C " _declspec(dllexport) void ShowDlg(void)
{
CMyDlg dlg;
dlg.DoModal();
AfxMessageBox( "hello ");
}
建立一个基于对话框的应用程序CallDll,添加一个按钮,在OnBtn1(){}里调用
ShowDlg函数,可以成功显示hello消息框,但是不能显示对话框,这是为什么啊,
断点调试,发现对话框执行了:if (lpDialogTemplate == NULL) return -1;可见对话框资源加载失败,这是为什么啊?高手请指教。

使用的资源不对,应该用的是DLL资源,但用了应用程序的,
加 AFX_MANAGE_STATE(AfxGetStaticModuleState());
extern "C " _declspec(dllexport) void ShowDlg(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CMyDlg dlg;
dlg.DoModal();
AfxMessageBox( "hello ");
}使用的资源不对,应该用的是DLL资源,但用了应用程序的,
加 AFX_MANAGE_STATE(AfxGetStaticModuleState());
extern "C " _declspec(dllexport) void ShowDlg(void)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
CMyDlg dlg;
dlg.DoModal();
AfxMessageBox( "hello ");
}

PS:

我今天也写了个dll,采用类似的方式,出现了类似的结果。一点崩溃了,加上AFX_MANAGE_STATE(AfxGetStaticModuleState()); 就好使了。

这个是什么原因?

在我这个博客的《(转了多次不知道几转了)在DLL中使用资源(CDialog)》这篇文章里有个解释,

“……在函数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消息的时候,因为这时对话框的模板等已经读出了。”

看来我自己博客的东西太多我自己也记不清了。还是好好整理一下吧。

你可能感兴趣的:(c,null,mfc,dll,工具,任务)