Habillage d’Interop HwndSource dans c ++ / cli pour utilisation dans une application native c ++ / MFC

J’ai une application MFC en c ++ natif, qui ne peut pas utiliser \ clr. Je dois afficher une fenêtre WPF à l’intérieur d’un cadre de cette application MFC. Par conséquent, j’essaie de créer un wrapper en C ++ mixte (cli) contenant cette page WPF et pouvant être utilisé par mon programme MFC.

Jusqu’ici, j’ai obtenu que HwndSource contienne ma fenêtre 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 myPage = gcnew Frame(); myPage->Height = height; myPage->Width = width; myPage->Background = gcnew SolidColorBrush(Colors::LightGray); gcroot newWindow = gcnew MyWindow; myPage->Content = newWindow->Content; source->RootVisual = myPage; return (HWND) source->Handle.ToPointer(); } 

le H:

 #pragma once #include "resource.h" #include  #include  #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 source; HWND GetHwnd(HWND parent, int x, int y, int width, int height); 

Maintenant, j’ai besoin d’un moyen de l’envelopper afin que je puisse appeler cela pour l’append dans la fenêtre MFC. Est-ce que quelqu’un sait comment le faire? Je ne suis pas sûr si le code que j’ai est assez légitime aussi, alors corrigez-moi si je me trompe.

Merci!

OK, cela a pris du temps et j’ai toujours des problèmes de performances, mais voici une façon de le faire.

Tout d’abord, j’ai 2 nouveaux projets. L’un est un MFC avec \ clr et l’autre est un MFC natif.

Dans le projet CLR, vous créez une nouvelle classe. Voici le .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 windowHandle; #else intptr_t windowHandle; #endif protected: DECLARE_MESSAGE_MAP() }; 

Dans le fichier .cpp, vous générez le 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; } 

Dans le projet MFC natif, il vous suffit de créer un CDialog normal (ou celui que vous souhaitiez) et d’append un object WpfHostWindow (n’oubliez pas de faire référence à et référence). Dans OnInitDialog (), vous pouvez maintenant utiliser la fonction .Create de l’object WpfHostWindow pour que WpfHostWindow devienne un enfant. Vous pouvez maintenant utiliser (théoriquement) la classe MFC native pour créer une instance WPF dans votre hôte MFC natif.