第 1 步:配置 MFC 应用程序以使用 CLR 支持进行编译
在本机 C++ 和托管 .NET 代码之间实现互操作性的最佳方法是将应用程序编译为托管 C++ 而不是本机 C++。这是通过转到项目的配置属性来完成的。在 General 下有一个选项“Common Language Runtime support”。将此设置为“公共语言运行时支持 /clr”。
第 2 步:将 WPF 程序集添加到项目中
在解决方案资源管理器中右键单击项目并选择“参考”。单击“添加新引用”。在 .NET 选项卡下,添加 WindowsBase、PresentationCore、PresentationFramework 和 System。确保在添加任何引用后重建全部,以便它们被拾取。
第 3 步:在 MFC 应用程序上设置 STAThreadAttribute
WPF 要求在主 UI 线程上设置 STAThreadAttribute。通过转到项目的配置属性进行设置。在 Linker->Advanced 下有一个名为“CLR Thread Attribute”的选项。将此设置为“STA 线程属性”。
第 4 步:创建 HwndSource 实例以包装 WPF 组件
System::Windows::Interop::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) source->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;
现在我们可以通过 m_webBrowser 访问 WPF 组件上的属性和方法。