现在的位置: 首页 > 综合 > 正文

wpf中调用w32的mfc dll 对话框

2013年12月03日 ⁄ 综合 ⁄ 共 1536字 ⁄ 字号 评论关闭

          最近这个工程一直困扰了我很久。现在终于解决了,给经验跟大家分享一下。

          我有个dll的控件,是一个第三方库。需要传递一个父窗口句柄,然后他会返回一个该控件的对象指针。此时,要想在wpf上面显示该控件,如果这个控件是简单的控件的话,就是简单的mfc窗口,只是一些简单的对话框的话,直接访问就行了。但是如果你的这个第三方控件很复杂,那么你就得使用wpf中hwndhost类了。

          继承hwndhost类,创建一个子类,然后在子类中实现buildwindowcore、destroywindowcore、wndproc。你就可以在该类中创建你的win32控件了。但是,你会发现你创建之后,消息并不能正常的投递到控件中,控件中的一些自定义的消息还是不能够正常响应。这时候我们该怎么办了。

          我的方法是,将那个第三方控件,再封装一层,封装成一个mfc dll。

          其实主要是这个mfc dll如何封装。这里一定要注意,刚开始做这个的时候,可能会被各种问题所迷惑。

          首先,创建一个mfc dll的工程,当创建完工程后,需要向该工程中,添加一个对话框资源,然后为该资源通过类向导添加一个类,这里选择的是继承CDialog的对话框类,此时为该类创建OnSize、OnInitial的方法。这时候,在OnInitial函数中,就可以加载第三方dll了,然后,获取第三方dll控件句柄,将该控件句柄在OnSize函数中通过MoveWindow函数改变在窗口中的位置。这时候在XXXApp文件中,OnInstance函数中创建该对话框这。时候创建这个对话框就有学问了,以前我没有这样创建过非模式对话框,一直出现问题。

         通过刚才创建的对话框窗口类对象,用Create的方法创建窗口,此时Create的第一个参数,填写CXXXDlg::IDD,即为创建对话框的资源ID。如果创建的窗口是child类型窗口的话,那么必须制定第二个参数父窗口指针(CWnd*类型)。如果这时候你只知道该窗口的句柄,怎么得到它的窗口指针了,CWnd* pWnd = CWnd::FromHandle(hwnd);这样就可以了。为什么要创建这个窗口了,其实创建这个窗口对象,只是在内存中拥有了这个窗口的资源,但是如果不创建这个窗口的话,这个窗口是不存在的(看不见的窗口),因为没有句柄,所以只有创建了窗口之后才会有窗口句柄。

        然后,就在导出函数中,导出这个窗口句柄,这时候如果你的导出函数接收有输入时,那么可以接收父窗口句柄,然后这时候通过SetParent函数,为创建的窗口添加父窗口句柄。这时候基本的操作就完成了。

        但就我这个工程中,还有几个问题要注意的。一,由于控件内部的原因,我在创建窗口的时候总是有个markmanager.cpp的错误,这时候,得加载ole库(不是很准确,不太清楚原理),::COInitial()这个加载com库,听说那个第三方控件库总是用MSXML的Com库,所以必须这样操作才不会出错,同时,需要加载Gdiplus库。当我用startupGuiplus函数加载gdiplus库时,提示一个链接错误,这个问题,是在工程属性中---编译器---附加库--添加gdiplus.lib就好了。

这时候,再在wpf中调用这个被mfc dll封装的自己开发的dll时,就万事ok了。这时候在调用导出函数的时候,会有个提示LockXXX的异常,以及在MoveWindow的时候也有个异常,具体记不清了。这时候在debug(调试)---异常,将相应的异常对号取消,然后再编译就没问题了。

        在家,回忆着写了些,等有空,再好好完善一下,贴些代码,详细说说。

【上篇】
【下篇】

抱歉!评论已关闭.