2009-05-06 12 views
16

Voy a responder mi propia pregunta aquí porque pasé unas horas reconstruyendo esto y quería compartir lo que encontré con la esperanza de poder salvar a alguien más de la excavación.¿Cómo puedo alojar contenido WPF en aplicaciones MFC?

Hay un MSDN Walkthrough que te lleva la mayor parte del camino hasta allí, pero hay un par de piezas clave que encontré en otros lugares. Por ejemplo, el tutorial le dice que coloque la línea [System :: STAThreadAttribute] antes de la definición _tWinMain(), pero si está implementando una aplicación MFC estándar, entonces no tiene _tWinMain() en su código fuente.

Si algo aquí no está claro, siéntase libre de hacer preguntas y editaré la respuesta para que todo quede más claro.

Respuesta

22

Paso 1: Configurar la aplicación MFC compilar con el apoyo de CLR

La mejor manera de conseguir la interoperabilidad entre C++ nativo y el código administrado de .NET es compilar la aplicación como C++ administrada en lugar de C++ nativo. Esto se hace yendo a las propiedades de configuración del proyecto. En General hay una opción "Soporte de Common Language Runtime". Establezca esto en "Common Language Runtime Support/clr".

Paso 2: Agregar los montajes de WPF al proyecto

Haga clic derecho en el proyecto en el Explorador de soluciones y elegir la opción "Referencias". Haga clic en "Agregar nueva referencia". En la pestaña .NET, agregue WindowsBase, PresentationCore, PresentationFramework y System. Asegúrese de reconstruir todo después de agregar referencias para que puedan ser recogidos.

Paso 3: Conjunto STAThreadAttribute sobre la aplicación MFC

WPF requiere que STAThreadAttribute puede establecer en el hilo principal de interfaz de usuario. Establezca esto yendo a Propiedades de configuración del proyecto. En Linker-> Advanced hay una opción llamada "CLR Thread Attribute". Establezca esto como "atributo de subprocesamiento STA".

Paso 4: Crear una instancia de HwndSource para envolver el componente WPF

System :: Windows :: Interop :: HwndSource es una clase .NET que maneja la interacción entre los componentes de MFC y .NET. Crear una con la siguiente sintaxis:

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; 

Agregar una variable miembro HWND a la clase de diálogo y luego asignar así: m_hWnd = (HWND) fuente-> Handle.ToPointer();

El objeto de origen y el contenido de WPF asociado seguirán existiendo hasta que llame a :: DestroyWindow (m_hWnd).

Paso 5: Agregar el control de WPF a la envoltura HwndSource

System::Windows::Controls::WebBrowser^ browser = gcnew System::Windows::Controls::WebBrowser(); 

browser->Height = height; 
browser->Width = width; 
source->RootVisual = browser; 

Paso 6: Mantenga una referencia al objeto de WPF

Puesto que la variable navegador irá fuera de alcance después salimos de la función que realiza la creación, de alguna manera tenemos que hacer referencia a ella.Los objetos administrados no pueden ser miembros de objetos no administrados, pero puede usar una plantilla de envoltura llamada gcroot para realizar el trabajo.

Agregar una variable miembro de la clase de diálogo:

#include <vcclr.h> 
gcroot<System::Windows::Controls::WebBrowser^> m_webBrowser; 

A continuación, agregue la siguiente línea al código en el Paso 5:

m_webBrowser = browser; 

Ahora podemos acceder a las propiedades y métodos en el componente de WPF a través de m_webBrowser.

+0

muy agradable. gracias por publicar. – Gishu

+1

fuente-> SizeToContent = Sistema :: Windows :: SizeToContent :: WidthAndHeight; ¡Esto era lo que me estaba perdiendo! +1 –

+2

Una información adicional, si no configuras el StaThreadModel, colapsará bastante misteriosamente dentro de MFC. Y necesita configurar el modelo de hilo en la aplicación ejecutable principal. Si usted, como yo, tenía el cuadro de diálogo que desea reemplazar en otra DLL, ** ** no le ayudará si establece el atributo de cadena CLR en la DLL no incluida. Puede ser obvio para otros, pero no para mí. – Dervall

Cuestiones relacionadas