2011-03-01 7 views
5

He podido envolver con éxito mi dll de Borland C++ no administrado y ejecutar sus formularios desde una aplicación C# .NET 4.0. ¿Es posible incrustar un formulario del dll directamente en una aplicación .NET?¿Cómo puedo incrustar un formulario de C++ no administrado en una aplicación .NET?

Para aclarar, el formulario original ya se está utilizando como control integrado en un proyecto de Borland C++. En esencia, parece un control personalizado, sentado en un panel dentro de la aplicación.

Cuando digo 'incrustar' me refiero a colocar en un formulario de la misma manera en que se sueltan botones, paneles, etc. en un formulario. No estoy buscando simplemente formar un niño.

Si esto no es posible, entonces quizás una mejor pregunta sería ¿cómo incribo un control personalizado no administrado en una aplicación .Net?

+1

¿Se refiere a incrustar como en una ventana infantil, o insertar como en el lugar el código dentro del proyecto .NET? –

Respuesta

4

Sí, solo necesita usar algunas funciones win32 de bajo nivel de user32.dll: SetParent, GetWindowLog, SetWindowLong, MoveWindow. Puede crear un control de contenedor .NET vacío, establecer el elemento principal de la ventana nativa en el control .NET, luego (opcionalmente) modificar el estilo de ventana (es decir, eliminar los bordes de la ventana nativa) y prestar atención para redimensionarlo junto con el Control de .NET Tenga en cuenta que, en un nivel administrado, el control .NET no tendrá en cuenta que tiene hijos.

En el control .NET hacer algo como

public void AddNativeChildWindow(IntPtr hWndChild){ 

     //adjust window style of child in case it is a top-level window 
     int iStyle = GetWindowLong(hWndChild, GWL_STYLE); 
     iStyle = iStyle & (int)(~(WS_OVERLAPPEDWINDOW | WS_POPUP)); 
     iStyle = iStyle | WS_CHILD; 
     SetWindowLong(hWndChild, GWL_STYLE, iStyle); 


     //let the .NET control be the parent of the native window 
     SetParent((IntPtr)hWndChild, this.Handle); 
     this._childHandle=hWndChild; 

     // just for fun, send an appropriate message to the .NET control 
     SendMessage(this.Handle, WM_PARENTNOTIFY, (IntPtr)1, (IntPtr)hWndChild); 

} 

Entonces anular el WndProc del control .NET para hacerla cambiar el tamaño de la forma nativa adecuada - por ejemplo, para llenar el área de cliente.

protected override unsafe void WndProc(ref Message m) 
    { 

     switch (m.Msg) 
     { 
      case WM_PARENTNOTIFY: 
        //... maybe change the border styles , etc 
        break; 
       case WM_SIZE: 
       iWid =(int)((int)m.LParam & 0xFFFF); 
       iHei= (int) (m.LParam) >> 16; 
       if (_childHandle != (IntPtr)0) 
       { 

        MoveWindow(_childHandle, 0, 0, iWid, iHei, true); 

       } 
       break; 

     } 

} 
+0

Esto ciertamente hace que la forma nativa sea una de las formas secundarias de la aplicación .NET, pero en realidad no aborda el problema de "incrustar" la ventana dentro de la aplicación .NET. Parece que estamos interpretando la pregunta de manera completamente diferente. –

+0

La pregunta es irremediablemente ambigua. –

+0

He tratado de aclarar la pregunta más. Básicamente, lo que estoy buscando es una forma de colocar el formulario dentro de un formulario .NET del mismo modo en que colocas botones y etiquetas en un formulario. Me gustaría incluirlo como un control de formulario y no solo como una ventana secundaria. – Everett

1

Notaescribí esta respuesta asumiendo que el PO quería incrustar literalmente la DLL que contiene la forma nativa en la aplicación .NET, no basta con modificar la forma en que se visualiza.

En resumen, no. Deberá empaquetar la DLL de C++ con su distribución e importar/ajustar sus funciones de la misma manera que lo está haciendo ahora.

Parece que recuerdo de mi Delphi (que utiliza el mismo servidor de compilación como Borland C++) días que el diseñador de formularios genera código C++ que crea un bucle winproc/message, etc. para cada uno de los activos en el formulario con Win32 API.

Dado que no se administra todo ese código, no se puede compilar en un ensamblaje administrado. Podría portarlo a C++ administrado, pero eso mataría la mayor parte de la ventaja de tenerlo en C++ para empezar, y está atascado con un modelo de excepción horrible y todas las demás partes maravillosas de C++. En ese caso, probablemente será mejor que lo reescribas en C#.

Pero, dado que esto es software, y casi todo es posible, aquí hay una solución realmente floja: insertar el DLL como un recurso binario en su aplicación .NET y, en tiempo de ejecución, extraer sus contenidos en una secuencia binaria, guardar en el disco y luego cargarlo (no estoy seguro de si hay una forma de ejecutar una DLL no administrada desde la memoria, que no sea hacer trampa colocándola en un disco RAM).

Lo único que obtiene es la capacidad de ocultar la DLL, pero realmente no veo el punto.

Editar Qué quiere decir incrustar como en el espectáculo como una ventana secundaria, o incrustar en su lugar como el código dentro del proyecto .NET?

Cuestiones relacionadas