2010-02-10 19 views
6

Actualmente estoy explorando la opción de portar alguna aplicación VB6 más antigua a WPF con C#. El plan, en la fase uno, es portar varios formularios clave y no toda la aplicación. El objetivo teórico es abrir el formulario VB6 en un contenedor de algún tipo dentro de WPF a través de un dll ActiveX.¿Puede/cómo se aloja un formulario VB6 completo en una aplicación C# WPF?

¿Esto es posible? He intentado buscar en Interop y parece que no puedo encontrar un ejemplo sólido de cómo hacer que funcione con nada más que con los controles de Win32, no con un formulario completo. Tengo acceso completo al antiguo código VB6 y puedo modificarlo de todos modos.

La siguiente captura de pantalla de la aplicación principal WPF serviría como la envoltura/recipiente:

http://www.evocommand.com/junk_delete_me/main_menu_mockup.png

La pantalla de mantenimiento VB6 actual que se carga en la sección de “espacio en blanco” en el lado derecho de la pantalla anterior.

Respuesta

11

que era capaz de realizar la tarea con los siguientes pasos:

  1. creado un nuevo proyecto de control de VB6 activa X. Copió y pegó todo el contenido de los controles de formulario VB6 y el código en el nuevo control.Hay varios elementos que tienen que ser manejados de cambiar a un control:

    1. se pierde la capacidad de mostrar el título del formulario de la manera anterior . Puede trabajar alrededor de con controles alternativos (label/borderlesstextbox, etc) que realizan la misma funcionalidad si es necesario . Esta no era una prioridad desde cada pantalla se alojaba en un navegador como sistema de pestañas en nuestro nuevo proyecto .Net.

    2. Todas las referencias MousePointer tienen que ser cambiados de Me.Mousepointer a Screen.MousePointer

    3. No puede utilizar Me.Hide y tienen que eventos alternos para ocultar el contenedor .Net .

    4. Cualquiera y todas las referencias a Me. [Cualquier cosa] tienen que ser eliminado o reemplazado con UserControl. [Nada] si son aplicables.

    5. Si utiliza cualquiera de las funciones que referencia un [yourcontrol] .Contianer.Property en un formulario tendrán que ser modificadas para bucle a través de los UserControl.Controls recogida lugar y “contenedor” es inválida para VB6 ActiveX Control

    6. Todos los formularios no modales/cuadros de diálogo deben ser removidos de la proyecto como no hay ahora Hwnd de manejar en WPF. Se obtiene un error de 'Los formularios no modales no se pueden mostrar en esta aplicación de host de una DLL de ActiveX, Control ActiveX o página de propiedades'. En nuestro caso, teníamos una pantalla simple de salpicadura que se mostraba cuando ciertos procesos/informes largos mostrados en le permitían al usuario saber qué estaba funcionando.

  2. he podido añadir directamente el control de VB6 a través de la interoperabilidad a un proyecto de WPF. Como tal, se creó un nuevo proyecto .Net "Windows Form Control Library". Se agregó una referencia al VB6 OCX al proyecto. Los controles VB6 se agregaron luego a la caja de herramientas de .Net haciendo clic con el botón derecho en "Añadir elemento" y señalando una referencia de com al ocx de control de VB6. El control .Net se usó para alojar/servir el control VB6.

  3. Para mostrar un formulario en el VB6 y hacer que active la funcionalidad de inicialización necesaria, los controles VB6 OCX fueron predeterminados de manera Visible.Falta, por lo que se agregaron inicialmente al .Net OCX como controles invisibles. Cuando sea necesario, el control VB6 se establece en visible = True, que activa el evento UserControl_Show(). Todo el código anteriormente en Form_Load() se movió a este evento. El evento show fue el método más fácil de acceder a Form_Load según sea necesario. MSDN: "El control no recibe Mostrar eventos si el formulario está oculto y luego se vuelve a mostrar, o si el formulario se minimiza y luego se restaura. La ventana del control permanece en el formulario durante estas operaciones y su propiedad Visible no cambia. "

  4. Envolviendo los controles vb6 dentro de a.El control de Net Winform resolvió el problema con los botones de Radio/Opción que se mostraban negros como se indica en otra parte de una de mis respuestas a esta pregunta sin tener que convertir los cuadros en Cuadros de imagen como se sugirió.

  5. En la aplicación WPF, como se selecciona un menú, el código xaml se crea dinámicamente y se muestra a través de un contenedor con una etiqueta WindowsFormsHost. Un objeto de control creado dinámicamente desde la aplicación. Winform se inserta en la etiqueta WindowsFormsHost en el xaml y el control se hace visible en el proyecto .net que dispara vb6 UserControl_Show y luego carga y muestra el formulario vb6.

+0

Guau, eso es increíblemente completo. –

+0

Estoy tratando de salvar a un pobre alma de algunos moretones craneales, de golpearse la cabeza, que he tenido durante las últimas dos semanas para resolverlo. – jasonk

1

¿Puede incluso cargar ese formulario VB6 en otro formulario VB6? Te sugiero que entiendas eso primero.

+0

Quiero cargar el formulario VB6 en formato WPF. – jasonk

+1

@jasonk: Sé lo que quieres hacer. Le sugiero que primero obtenga el formulario VB6 cargado en un formulario VB6. Una vez hecho esto, sabrá que el formulario se puede cargar en algún tipo de formulario. _Then_ trabajo para que se cargue en un formulario WPF. Es posible que deba cambiar el formulario para permitir que se cargue en otra forma. Haría bien en trabajar en VB6, con lo cual está familiarizado. –

0

No hay una manera confiable de configurar el elemento principal de un formulario VB6. Siempre puede hackearlo o usar un control ActiveX simple (UserControl en VB6) como contenedor de UI en lugar de formularios VB6.

+0

No estoy muy familiarizado con la construcción de controles OCX. ¿Eso significa que cada pantalla en VB6 tendría que ser su propio control o hay una manera de alojar múltiples pantallas dentro del único control? – jasonk

3

Creo que lo que tendrá que hacer es extraer el contenido del formulario VB6 en un control ActiveX. A continuación, puede exponer esto en su dll ActiveX y colocarlo en su formulario WPF. Dudo que sea posible alojar un formulario VB6 dentro de cualquier otro tipo de formulario.

+0

+1, aunque el control debería estar expuesto en un ActiveX OCX en lugar de una DLL. – MarkJ

+0

No estoy muy familiarizado con la construcción de controles OCX. ¿Eso significa que cada pantalla en VB6 tendría que ser su propio control? – jasonk

+1

Sí, esencialmente saca todo de la pantalla y lo coloca en un control ActiveX. Luego puede colocar este control en su formulario VB6 (o alojarlo en su aplicación .NET). Acabo de encontrar este artículo de MSDN que podría ayudarte. http://msdn.microsoft.com/en-us/library/ms742735.aspx –

0

Encontré un método para hacer lo que se necesitaba dentro de WinForms en lugar de WPF en este momento. http://www.codeproject.com/KB/vb-interop/VB6formsinNET.aspx Me imagino que si puedo hacerlo funcionar al 100%, puedo transferirlo a WPF o, peor aún, alojar el elemento WinForm en el formulario WPF si tengo absolutamente (U-G-L-Y).

De todos modos, me he acercado un poco, pero estoy teniendo un problema muy extraño con ciertos controles que también pintan la pantalla. botones de radio/Opción prestan negro como sólido:

http://www.evocommand.com/junk_delete_me/optionbuttons.png

He intentado cambiar el color de fondo de manera explícita los controles de ButtonFace a un color fijo y todavía lo hace. Supongo que es un problema de capas con los botones de opción dentro del control de marco. Estoy un poco perdido sobre cómo proceder sin una revisión masiva del contenido de VB6 para cambiar los botones de opciones a casillas de verificación. Es una aplicación robusta y hay más de 600 controles de botón de opción en la aplicación que no quiero tratar exactamente.

EDIT: Pude confirmar que tiene algo que ver con la estratificación de la opción dentro de un control Frame. Si tira de ella a la forma base del problema no se produce: http://www.evocommand.com/junk_delete_me/optionbuttons2.png

+0

Encontré una solución alternativa que si coloca los OptionButtons dentro de un PictureBox en lugar de un Frame, se mostrará sin el fondo negro. – jasonk

Cuestiones relacionadas