要实现在DLL库中创建MFC的窗口,必须创建一个扩展DLL,Extension Dll
在DLL中配置好窗口资源,如:IDD_DIALOG这种模板资源。
在外部调用的时候只需要通过一个接口来创建窗体。
例子代码:
class __declspec(dllexport) CIeDlg : public CDialog
{
//内容省略
............
}
CIeDlg为外部需要调用的窗体类。
在DLL中创建一个函数接口,创建该窗体
CIeDlg *CreateIeDlg(HWND hWndParent)
{
CIeDlg * g_MainDlg=new CIeDlg ();
CWnd *pWndParent = CWnd::FromHandle(hWndParent);
g_MainDlg->Create(IDD_IEDLG,pWndParent);
g_MainDlg->ShowWindow(SW_SHOW);
return g_MainDlg;
}
外部直接调用CreateIeDlg来创建窗口
注意:
非模态对话框显示的时候程序不会暂停等待用户操作,会继续执行后续的代码,如果使用临时变量的话,对象的生命周期在调用函数执行完之后就结束,这样就无法正常显示(显示了又瞬间消失),所以可采用创建对象指针的方式,由于动态创建的指针对象是分配在堆内存上,堆内存上的变量周期可应用程序相同。
而模态对话框,要想在显示前做些事情,可以响应OnShow 消息去处理。
exe动态加载dll,在扩展dll中CreateIeDlg接口create窗口时出错。执行过程中出现AfxGetResourceHandle()断言错误。
上网查了很多资料很多都说是因为资源切换的问题,但是我在应用程序中,已经进行了资源切换,应该不存在这个问题了啊!!所以我又在dllmain中定义了变量HINSTANCE theInstance,重新设置了资源,但是又出现了新的问题:
BOOL CObject::IsKindOf(const CRuntimeClass* pClass) const
{
ENSURE(this != NULL);//在这里错误
。。。。。。。。。
}
很多网友也遇见了这样的问题,主要是我原来有个可以正常调用的demo,这个demo调用方式和上面的一模一样,所以我就想可能是我哪里设置的问题,所以我仔细对比了两个DLL,也没有不一样的地方。经过多次查找资料,将exe和dll的编译选项中关于mfc库的选择设为一样的,因为exe工程中还依赖了一些lib静态库(有自己开发的,也有第三方的),一起编译时还是编译出错。
经分析原因如下:
主要原因是编译选项中关于mfc库的选择。第三方库recognizer.lib和你的工程选择不同造成的。
打开Property Pages。在Configureation Properties->General->Use of MFC中改变选项
再编译执行,问题就不再出现了。