Atl COM Dll工程中調用dll中資源的問題

在做IE BHO插件dll的時候,需要打開一個模式對話框。當我添加了dialog資源,然後MyDialog dlg; dlg.DoModal();時,afxwin1.inl第23、26行出現斷言失敗:

_AFXWIN_INLINE HINSTANCE AFXAPI AfxGetInstanceHandle()
    { ASSERT(afxCurrentInstanceHandle != NULL);
        return afxCurrentInstanceHandle; }
_AFXWIN_INLINE HINSTANCE AFXAPI AfxGetResourceHandle()
    { ASSERT(afxCurrentResourceHandle != NULL);
        return afxCurrentResourceHandle; }

 

可以發現是afxCurrentInstanceHandle和afxCurrentResourceHandle這兩個爲NULL造成的。然後我想起來,dll中AfxGetInstanceHandle()方法默認返回的是.exe的資源訪問句柄。對此MSDN說明如下:

 

AfxGetInstanceHandle always returns the HINSTANCE of your executable file (.EXE) unless it is called from within a DLL linked with the USRDLL version of MFC. In this case, it returns an HINSTANCE to the DLL.

 

於是乎,我在MyDialog dlg; dlg.DoModal();之前加上

AFX_MANAGE_STATE(AfxGetAppModuleState());

心想着這下可以了吧?可是還是出現相同的問題。根據經驗,這是可以的啊。而且我的stdafx.h種已經包含了mfc的相關頭文件,比如:

//-----------------------------------------------------------------------------
#include <afxwin.h>                //----- MFC core and standard components
#include <afxext.h>                //----- MFC extensions
#ifndef _AFX_NO_OLE_SUPPORT
#include <afxole.h>                //----- MFC OLE classes
#include <afxodlgs.h>            //----- MFC OLE dialog classes
#include <afxdisp.h>            //----- MFC Automation classes
#endif //----- _AFX_NO_OLE_SUPPORT

 

檢查了DllMain()方法,原來沒有調用:

 if (!AfxWinInit(hInstance, NULL, _T(""), 0))
 {
           AfxWinTerm();
           return FALSE;
 }

加上這個一切正常了,測試了一下AFX_MANAGE_STATE(AfxGetAppModuleState()); 也可以去掉。

 

看來,exe或者dll中加載資源時候,一定要注意切換資源所在的HINSTANCE,同時在atl com dll中使用MFC,一定要調用AfxWinInit()初始化相關參數。

 

附加幾點:

1. 查閱資源,發現原來AFX_MANAGE_STATE(AfxGetAppModuleState());的用法是這樣的:

如果從外面調用dll裏面發佈出來的方法,在該方法中加載資源,比如加載該dll定義的對話框資源,應該在其方法實現裏,最前面加上這句,使得dll之外調用時,自動的切換MFC資源加載的句柄,方法調用完後會自動恢復成原來的。

 

2. 在dialog.DoModal();的前後這樣嘗試動態的自己設置ResourceHandle,資源加載完後恢復也不行。

 

AFX_MANAGE_STATE(AfxGetAppModuleState());  //DllMain()中AfxWinInit()以後,這句可以省略。
HINSTANCE hExeIns = AfxGetInstanceHandle();   //不調用AfxWinInit(),此句人就報錯。
AfxSetResourceHandle((HINSTANCE)_Module.m_hInstResource);// 切換MFC加載資源從當前exe到當前dll資源實例
MyDialog dialog(AfxGetMainWnd());
dialog.DoModal();
AfxSetResourceHandle(hExeIns);  // 將MFC資源加載切換回去。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章