2009-05-06 35 views
16

我在这里回答我自己的问题,因为我花了几个小时将它们拼凑在一起,并希望分享我发现的内容,希望能够拯救别人。如何在MFC应用程序中托管WPF内容?

有一个MSDN Walkthrough可以让你在那里的大部分路上,但有一些我在其他地方找到的关键部分。例如,演练告诉你在_tWinMain()定义之前放置[System :: STAThreadAttribute]行,但如果你正在实现一个标准的MFC应用程序,那么你的源代码中没有_tWinMain()。

如果这里有什么不清楚的地方,随时提问,我会编辑答案,使事情更清楚。

回答

22

步骤1:配置MFC应用程序来编译与CLR支持

实现本地C++和管理的.NET代码之间的互操作性的最好方法是将应用程序编译为托管C++,而不是本地C++。这通过转到项目的配置属性来完成。在常规下,有一个选项“公共语言运行时支持”。将其设置为“Common Language Runtime Support/clr”。

第2步:WPF组件添加到项目在Solution Explorer中的项目

单击鼠标右键,选择“参考”。点击“添加新参考”。在.NET选项卡下,添加WindowsBase,PresentationCore,PresentationFramework和System。确保在添加任何引用以便让他们获取后重建所有内容。

第3步:设置请将STAThreadAttribute在MFC应用程序

WPF要求请将STAThreadAttribute可以在主UI线程上设置。通过转到项目的配置属性进行设置。在链接器 - >高级下,有一个名为“CLR线程属性”的选项。将其设置为“STA线程属性”。

步骤4:创建HwndSource的实例,以包裹WPF部件

系统:视窗::互操作:: HwndSource是一个.NET类来处理MFC和.NET组件之间的交互。

System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew  System::Windows::Interop::HwndSourceParameters("MyWindowName"); 
sourceParams->PositionX = x; 
sourceParams->PositionY = y; 
sourceParams->ParentWindow = System::IntPtr(hWndParent); 
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; 

System::Windows::Interop::HwndSource^ source = gcnew System::Windows::Interop::HwndSource(*sourceParams); 
source->SizeToContent = System::Windows::SizeToContent::WidthAndHeight; 

添加HWND成员变量到对话框类,然后将其指定这样的::使用以下语法创建一个 m_hWnd =(HWND)源 - > Handle.ToPointer();

源对象和关联的WPF内容将保持存在状态,直到调用:: DestroyWindow(m_hWnd)。

步骤5:将WPF控件添加到HwndSource包装

System::Windows::Controls::WebBrowser^ browser = gcnew System::Windows::Controls::WebBrowser(); 

browser->Height = height; 
browser->Width = width; 
source->RootVisual = browser; 

步骤6:保持到WPF对象

基准由于浏览器变量会走出范围后我们退出创建的函数,我们需要以某种方式对其进行引用。托管对象不能是非托管对象的成员,但可以使用名为gcroot的包装模板来完成工作。

一个成员变量添加到对话框类:

#include <vcclr.h> 
gcroot<System::Windows::Controls::WebBrowser^> m_webBrowser; 

以下行然后添加到代码中第5步:

m_webBrowser = browser; 

现在,我们可以在WPF部件上访问的属性和方法通过m_webBrowser。

+0

非常好。感谢张贴。 – Gishu 2009-05-06 14:47:12

+1

source-> SizeToContent = System :: Windows :: SizeToContent :: WidthAndHeight;这就是我错过的! +1 – 2010-07-22 16:02:41

+2

另外一条信息,如果你没有设置StaThreadModel,它会在MFC内部非常神秘地崩溃。你需要在主可执行应用上设置线程模型。如果你像我一样,想在另一个DLL中替换对话框,那么如果你在未包含的DLL上设置了CLR线程属性,它将不会**帮助。对其他人可能是显而易见的,但它不是我。 – Dervall 2012-02-21 12:19:38

相关问题