在c ++ / cli中包装Interop HwndSource以在本机c ++ / MFC应用程序中使用

时间:2015-04-28 11:26:43

标签: c# c++ wpf mfc wrapping

我在本机c ++中获得了一个不能使用\ clr的MFC应用程序。我需要在这个MFC应用程序的框架内显示一个WPF窗口,所以我试图在混合C ++(cli)中创建一个包装器,它包含这个WPF页面,可以被我的MFC程序使用。

到目前为止,我得到了HwndSource来包含我的WPF窗口:

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窗口中。 有人知道怎么做吗? 我不确定我的代码是否也足够合法,所以如果我错了请纠正我。

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,这花了一些时间,我仍然遇到性能问题,但这是一种方法。

首先,我有2个新项目。一个是带有\ clr的MFC,一个是本机MFC。

在clr项目中,您创建了一个新类。 这里是.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()
};

在.cpp文件中生成hwndsource:

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设置为Child。 现在,您可以(理论上)使用本机MFC类在您的本机MFC主机中创建WPF实例。