我将在这里回答我自己的问题,因为我花了几个小时拼凑起来,并想分享我发现的东西,希望我能拯救别人的挖掘。
有一个MSDN Walkthrough可以帮助您了解大部分情况,但是我在其他地方找到了一些关键部分。例如,演练告诉您将行 [System::STAThreadAttribute] 放在 _tWinMain() 定义之前,但如果您正在实现标准 MFC 应用程序,则源代码中没有 _tWinMain()。
如果这里有任何不清楚的地方,请随时提出问题,我将编辑答案以使事情更清楚。
我将在这里回答我自己的问题,因为我花了几个小时拼凑起来,并想分享我发现的东西,希望我能拯救别人的挖掘。
有一个MSDN Walkthrough可以帮助您了解大部分情况,但是我在其他地方找到了一些关键部分。例如,演练告诉您将行 [System::STAThreadAttribute] 放在 _tWinMain() 定义之前,但如果您正在实现标准 MFC 应用程序,则源代码中没有 _tWinMain()。
如果这里有任何不清楚的地方,请随时提出问题,我将编辑答案以使事情更清楚。
步骤 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 组件上的属性和方法。