在 c++/cli 中包装 Interop HwndSource 以在本机 c++/MFC 应用程序中使用
Wrapping Interop HwndSource in c++/cli to be used in native c++ / MFC application
我在本机 C++ 中得到了一个 MFC 应用程序,它不能使用 \clr。我需要在这个 MFC 应用程序的框架内显示一个 WPF Window,所以我试图在混合 C++(cli) 中制作一个包装器,它包含这个 WPF 页面并且可以被我的 MFC 程序使用。
到目前为止,我得到了包含我的 WPF 的 HwndSource window:
WPFPageHost::WPFPageHost(){}
HWND GetHwnd(HWND parent, int x, int y, int width, int height)
{
System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters(
"hi" // NAME
);
sourceParams->PositionX = x;
sourceParams->PositionY = y;
sourceParams->Height = height;
sourceParams->Width = width;
sourceParams->ParentWindow = IntPtr(parent);
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; // style
source = gcnew System::Windows::Interop::HwndSource(*sourceParams);
gcroot<Frame^> myPage = gcnew Frame();
myPage->Height = height;
myPage->Width = width;
myPage->Background = gcnew SolidColorBrush(Colors::LightGray);
gcroot<MyWindow^> newWindow = gcnew MyWindow;
myPage->Content = newWindow->Content;
source->RootVisual = myPage;
return (HWND) source->Handle.ToPointer();
}
.h:
#pragma once
#include "resource.h"
#include <vcclr.h>
#include <string.h>
#include "stdafx.h"
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;
using namespace System::Windows::Interop;
using namespace System::Windows::Media;
using namespace MyAPP::WPF;
public class WPFPageHost
{
public:
WPFPageHost();
};
gcroot<HwndSource^> source;
HWND GetHwnd(HWND parent, int x, int y, int width, int height);
现在我需要一种包装它的方法,这样我就可以将其添加到 MFC 中 Window。
有人知道怎么做吗?
我不确定我的代码是否也足够合法,所以如果我错了请纠正我。
谢谢!
好的,这花了一些时间,我仍然遇到性能问题,但这是一种方法。
首先我得到了 2 个新项目。一种是带 \clr 的 MFC,一种是本机 MFC。
在 clr 项目中新建一个 class。
这里的 .h :
#pragma once
class AFX_EXT_CLASS WpfHostWindow : public CWnd
{
DECLARE_DYNAMIC(WpfHostWindow)
public:
WpfHostWindow();
virtual ~WpfHostWindow();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
#ifdef _MANAGED
gcroot<System::Windows::Controls::Frame^> windowHandle;
#else
intptr_t windowHandle;
#endif
protected:
DECLARE_MESSAGE_MAP()
};
在您生成 hwndsource 的 .cpp 文件中:
int WpfHostWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rect;
GetClientRect(&rect);
HwndSourceParameters^ sourceParams= gcnew HwndSourceParameters("CustomHost");
sourceParams->PositionX = 0;
sourceParams->PositionY = 0;
//sourceParams.Height = rect.Height();
//sourceParams.Width = rect.Width();
sourceParams->ParentWindow = (IntPtr)m_hWnd;
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD;
System::Windows::Interop::HwndSource^ source = gcnew HwndSource(*sourceParams);
source->SizeToContent = System::Windows::SizeToContent::WidthAndHeight;
Frame^ mainFrame = gcnew Frame();
mainFrame->UpdateLayout();
windowHandle = mainFrame;
source->RootVisual = windowHandle;
return 0;
}
在原生MFC项目中你只需要做一个普通的CDialog(或者任何你想要的)和添加一个WpfHostWindow对象(不要忘记引用和东西)。
在 OnInitDialog() 中,您现在可以使用 WpfHostWindow 对象的 .Create Funktion 将 WpfHostWindow 作为子对象。
现在您可以(理论上)使用本机 MFC class 在本机 MFC 主机中创建 WPF 实例。
我在本机 C++ 中得到了一个 MFC 应用程序,它不能使用 \clr。我需要在这个 MFC 应用程序的框架内显示一个 WPF Window,所以我试图在混合 C++(cli) 中制作一个包装器,它包含这个 WPF 页面并且可以被我的 MFC 程序使用。
到目前为止,我得到了包含我的 WPF 的 HwndSource window:
WPFPageHost::WPFPageHost(){}
HWND GetHwnd(HWND parent, int x, int y, int width, int height)
{
System::Windows::Interop::HwndSourceParameters^ sourceParams = gcnew System::Windows::Interop::HwndSourceParameters(
"hi" // NAME
);
sourceParams->PositionX = x;
sourceParams->PositionY = y;
sourceParams->Height = height;
sourceParams->Width = width;
sourceParams->ParentWindow = IntPtr(parent);
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD; // style
source = gcnew System::Windows::Interop::HwndSource(*sourceParams);
gcroot<Frame^> myPage = gcnew Frame();
myPage->Height = height;
myPage->Width = width;
myPage->Background = gcnew SolidColorBrush(Colors::LightGray);
gcroot<MyWindow^> newWindow = gcnew MyWindow;
myPage->Content = newWindow->Content;
source->RootVisual = myPage;
return (HWND) source->Handle.ToPointer();
}
.h:
#pragma once
#include "resource.h"
#include <vcclr.h>
#include <string.h>
#include "stdafx.h"
using namespace System;
using namespace System::Windows;
using namespace System::Windows::Controls;
using namespace System::Windows::Interop;
using namespace System::Windows::Media;
using namespace MyAPP::WPF;
public class WPFPageHost
{
public:
WPFPageHost();
};
gcroot<HwndSource^> source;
HWND GetHwnd(HWND parent, int x, int y, int width, int height);
现在我需要一种包装它的方法,这样我就可以将其添加到 MFC 中 Window。 有人知道怎么做吗? 我不确定我的代码是否也足够合法,所以如果我错了请纠正我。
谢谢!
好的,这花了一些时间,我仍然遇到性能问题,但这是一种方法。
首先我得到了 2 个新项目。一种是带 \clr 的 MFC,一种是本机 MFC。
在 clr 项目中新建一个 class。 这里的 .h :
#pragma once
class AFX_EXT_CLASS WpfHostWindow : public CWnd
{
DECLARE_DYNAMIC(WpfHostWindow)
public:
WpfHostWindow();
virtual ~WpfHostWindow();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
#ifdef _MANAGED
gcroot<System::Windows::Controls::Frame^> windowHandle;
#else
intptr_t windowHandle;
#endif
protected:
DECLARE_MESSAGE_MAP()
};
在您生成 hwndsource 的 .cpp 文件中:
int WpfHostWindow::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CWnd::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rect;
GetClientRect(&rect);
HwndSourceParameters^ sourceParams= gcnew HwndSourceParameters("CustomHost");
sourceParams->PositionX = 0;
sourceParams->PositionY = 0;
//sourceParams.Height = rect.Height();
//sourceParams.Width = rect.Width();
sourceParams->ParentWindow = (IntPtr)m_hWnd;
sourceParams->WindowStyle = WS_VISIBLE | WS_CHILD;
System::Windows::Interop::HwndSource^ source = gcnew HwndSource(*sourceParams);
source->SizeToContent = System::Windows::SizeToContent::WidthAndHeight;
Frame^ mainFrame = gcnew Frame();
mainFrame->UpdateLayout();
windowHandle = mainFrame;
source->RootVisual = windowHandle;
return 0;
}
在原生MFC项目中你只需要做一个普通的CDialog(或者任何你想要的)和添加一个WpfHostWindow对象(不要忘记引用和东西)。 在 OnInitDialog() 中,您现在可以使用 WpfHostWindow 对象的 .Create Funktion 将 WpfHostWindow 作为子对象。 现在您可以(理论上)使用本机 MFC class 在本机 MFC 主机中创建 WPF 实例。