Fase 1: Configurare l'applicazione MFC per compilare con il supporto CLR
Il modo migliore per raggiungere l'interoperabilità tra nativo C++ e il codice .NET gestito è quello di compilare l'applicazione come gestita C++ piuttosto che C++ nativo. Questo viene fatto andando alle Proprietà di configurazione del progetto. Sotto Generale esiste un'opzione "Supporto Common Language Runtime". Impostare su "Common Language Runtime Support/clr".
Fase 2: Aggiungi gli assembly WPF al progetto
fare clic destro sul progetto in Solution Explorer e scegliere "Riferimenti". Fai clic su "Aggiungi nuovo riferimento". Nella scheda .NET, aggiungi WindowsBase, PresentationCore, PresentationFramework e System. Assicurati di ricostruire Tutto dopo aver aggiunto dei riferimenti per poterli raccogliere.
Passo 3: Impostare STAThreadAttribute sull'applicazione MFC
WPF richiede che STAThreadAttribute essere impostato sul thread principale dell'interfaccia utente. Impostalo andando su Proprietà di configurazione del progetto. Sotto Linker-> Advanced c'è un'opzione chiamata "Attributo Thread CLR". Impostalo su "Attributo di thread STA".
Fase 4: Creare un'istanza HwndSource per avvolgere la componente WPF
System :: di Windows :: :: Interop HwndSource è una classe .NET che gestisce l'interazione tra i componenti MFC e .NET. Creare uno che utilizza la seguente sintassi:
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;
Aggiungere una variabile membro HWND alla classe finestra di dialogo e quindi assegnare in questo modo: m_hWnd = (HWND) source-> Handle.ToPointer();
L'oggetto di origine e il contenuto WPF associato rimarrà in esistenza finché non si chiama :: DestroyWindow (m_hWnd).
Fase 5: Aggiungere il controllo WPF per l'involucro HwndSource
System::Windows::Controls::WebBrowser^ browser = gcnew System::Windows::Controls::WebBrowser();
browser->Height = height;
browser->Width = width;
source->RootVisual = browser;
Passo 6: Tenere un riferimento all'oggetto WPF
Poiché la variabile del browser andrà fuori portata dopo usciamo dalla funzione facendo la creazione, dobbiamo in qualche modo mantenere un riferimento ad essa.Gli oggetti gestiti non possono essere membri di oggetti non gestiti, ma puoi utilizzare un modello di wrapper chiamato gcroot per portare a termine il lavoro.
Aggiungere una variabile membro alla classe finestra di dialogo:
#include <vcclr.h>
gcroot<System::Windows::Controls::WebBrowser^> m_webBrowser;
quindi aggiungere la seguente riga al codice nel passaggio 5:
m_webBrowser = browser;
Ora possiamo accedere a proprietà e metodi sul componente WPF attraverso m_webBrowser.
molto bello. grazie per la pubblicazione – Gishu
source-> SizeToContent = System :: Windows :: SizeToContent :: WidthAndHeight; Questo era quello che mi mancava! +1 –
Un'ulteriore informazione, se non si imposta lo StaThreadModel, si romperà in modo misteriosamente profondo all'interno di MFC. Ed è necessario impostare il modello di thread sull'app eseguibile principale. Se tu, come me, avevi la finestra di dialogo che vuoi sostituire in un'altra DLL, non ** ti aiuterà se imposti l'attributo thread CLR sulla DLL non ancora eseguita. Potrebbe essere ovvio per gli altri, ma non era per me. – Dervall