Atl COM Dll工程中调用dll中资源的问题
2010-12-30 15:22
477 查看
在做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资源加载切换回去。
_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资源加载切换回去。
相关文章推荐
- win32 DLL中创建的的对话框资源被应用程序调用无法识别的问题
- RegAsm注册DLL组件使用jacob调用的问题com.jacob.com.ComFailException: Can't co-create object
- C#调用C++编写的COM DLL封装库的问题解决方案
- Eclipse中java工程中引用dll库的路径设置 && System.loadLibrary()调用Dll路径问题
- VC++6.0调用ATL COM DLL方式
- 调用 ATL COM DLL的几种方法
- ATL--创建简单的ATL之dll工程,添加类和类的接口并在MFC中调用
- Windows DLL中调用资源碰到的问题
- VC调用QT的dll 问题解决
- .Net调用Office Com组件的原理及问题:检索com类工厂组件检索 COM 类工厂中 CLSID 为 {XXX} 的组件失败
- 同一个C语言工程不同C文件之间的函数互相调用问题(二)
- VB.NET中制作COM_DLL在VBA、VB中调用
- Android工程中jni本地调用opencv时,某些函数不识别问题
- 关于C#与Delphi DLL调用及回调问题注意事项
- 解决DLL调用问题
- C#调用C++Dll封装时遇到的一系列问题
- 关于Java调用32/64位dll的问题
- 【转】Android将Activity打成jar包供第三方调用(解决资源文件不能打包的问题)
- MFC之调用DLL的问题:error C2664: “LoadLibraryW”: 不能将参数 1 从“const char *”转换为“LPCWSTR
- 在 C++Builder 工程里调用 DLL 函数