Étape 1: Configurer l'application MFC pour compiler avec le support CLR
La meilleure façon de réaliser l'interopérabilité entre C++ natif et le code managé .NET est de compiler l'application comme géré C++ plutôt que C++ natif. Ceci est fait en allant dans les propriétés de configuration du projet. Sous Général, il y a une option "Common Language Runtime support". Réglez ceci sur "Common Language Runtime Support/clr".
Étape 2: Ajouter les ensembles de WPF au projet
Faites un clic droit sur le projet dans la solution Explorer et choisissez « Références ». Cliquez sur "Ajouter une nouvelle référence". Sous l'onglet .NET, ajoutez WindowsBase, PresentationCore, PresentationFramework et System. Assurez-vous de reconstruire tout après avoir ajouté des références afin qu'elles soient récupérées.
Étape 3: Définir STAThreadAttribute sur l'application MFC
WPF exige que STAThreadAttribute être réglé sur le thread principal de l'interface utilisateur. Définissez ceci en allant dans Propriétés de configuration du projet. Sous Linker-> Advanced, il y a une option appelée "CLR Thread Attribute". Définissez ceci sur "Attribut de thread STA".
Étape 4: Créer une instance de HwndSource pour envelopper le composant WPF
System :: :: Interop de Windows :: HwndSource est une classe .NET qui gère l'interaction entre les composants MFC et .NET. Créer une en utilisant la syntaxe suivante:
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;
Ajouter une variable membre HWND à la classe de dialogue puis attribuez-lui comme ceci: m_hWnd = (HWND) source-> Handle.ToPointer();
L'objet source et le contenu WPF associé resteront présents jusqu'à ce que vous appeliez :: DestroyWindow (m_hWnd).
Étape 5: Ajoutez le contrôle WPF à l'enveloppe HwndSource
System::Windows::Controls::WebBrowser^ browser = gcnew System::Windows::Controls::WebBrowser();
browser->Height = height;
browser->Width = width;
source->RootVisual = browser;
Étape 6: Gardez une référence à l'objet WPF
Depuis la variable du navigateur se sont hors de portée après nous quittons la fonction en faisant la création, nous devons en quelque sorte tenir une référence à celle-ci.Les objets gérés ne peuvent pas être membres d'objets non gérés, mais vous pouvez utiliser un modèle de wrapper appelé gcroot pour effectuer le travail.
Ajouter une variable membre à la classe de dialogue:
#include <vcclr.h>
gcroot<System::Windows::Controls::WebBrowser^> m_webBrowser;
Ensuite, ajoutez la ligne suivante au code à l'étape 5:
m_webBrowser = browser;
Maintenant, nous pouvons accéder aux propriétés et méthodes sur le composant WPF à travers m_webBrowser.
très agréable. Merci d'avoir posté. – Gishu
source-> SizeToContent = Système :: Windows :: SizeToContent :: WidthAndHeight; C'était ce qui me manquait! +1 –
Une information supplémentaire, si vous ne définissez pas le StaThreadModel, il va planter mystérieusement profondément dans MFC. Et vous devez définir le modèle de thread sur l'application exécutable principale. Si vous, comme moi, avez la boîte de dialogue que vous voulez remplacer dans une autre DLL, cela ne sera pas ** utile si vous définissez l'attribut de thread CLR sur la DLL non cliquée. Cela pourrait être évident pour les autres, mais ce n'était pas à moi. – Dervall