Hola espero que esten bien, como puedo insertar un formulario dentro de un Picturebox, en Vb6 se podia hacer encontre el ejemplo pero lo paso a net no funciona marca error.
Agradezco de antemano su apoyo.
saludos.
Hola espero que esten bien, como puedo insertar un formulario dentro de un Picturebox, en Vb6 se podia hacer encontre el ejemplo pero lo paso a net no funciona marca error.
Agradezco de antemano su apoyo.
saludos.
Folanc
Hola Tino
Recuerdo que una vez lo hice utilizando las API's de Windows SetParent y ShowWindow. Al ser funciones API deberia trabajar tanto en VB.NET como en VB6.
No se si es esa la metodologia que estas tratando de implementar. Confirma si deseas usar estas API's y te posteo un ejemplo
Hola si me ayudaria si me das el post, mira este es el codigo que utilizaba para hacerlo en Vb6 solo que este no me funciona en .net
Insertar formulario dentro de un control PictureBox
agradezco tu apoyo.
Folanc
Esta es la manera como una vez lo hice y me funciono bastante bien en VB 2008 pero no lo he probado en las ultimas versiones de VS (2010 y 2012)
Código:
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Long, ByVal hWndParent As Long) As Long ' Declaración de la función Api ShowWindow Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long Const SHOWMAXIMIZED_eSW = 3& Sub Incrustar_Formulario(Formulario As Windows.Forms.Form, PictureBox As Windows.Forms.PictureBox) Dim Ret As Long Form2.Show SetParent(Formulario.Handle.ToInt32, PictureBox.Handle.ToInt32) Ret = ShowWindow(Formulario.Handle.ToInt32, SHOWMAXIMIZED_eSW) End Sub Sub Liberar_Formulario(Formulario As Windows.Forms.Form) SetParent(Formulario.Handle.ToInt32, 0) End Sub Private Sub Command1_Click(sender As Object, e As EventArgs) Handles Command1.Click Incrustar_Formulario(Form2, Picture1) End Sub Private Sub Command2_Click(sender As Object, e As EventArgs) Handles Command2.Click Liberar_Formulario(Form2) End Sub
Hola gracias por tu respuesta, efectivamente ese es el codigo que usaba pero me lanza el siguiente error:
Una llamada a la función PInvoke 'WindowsApplication1!WindowsApplication1.Form1::Se tParent' impidió la correspondencia de la pila. Es posible que la razón sea que la signatura PInvoke administrada no coincida con la signatura de destino no administrada. Compruebe que la convención y los parámetros de llamada de la signatura PInvoke coinciden con la signatura no administrada de destino.
en esta línea de codigo
SetParent(Formulario.Handle.ToInt32, PictureBox.Handle.ToInt32)
Gracias por tu apoyo
Folanc
La declaracion correcta de SetParent es esta:
<System.Runtime.InteropServices.DllImport("user32. dll", EntryPoint:="SetParent")> _
Public Shared Function SetParent(ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr
End Function
En plataformas 64-bit los "handle" son 64-bit, por lo tanto xxx.Handle.ToInt32 te dara problemas.
Efectivamente jar tiene razon. En parte. El problema es porque se esta haciendo una llamada a una funcion no administrada, y esto es provocado porque los tipos de datos estan fuera de contexto.
La solucion que da jar es aceptable pero un poco complicada, ya que con la estructura IntPrt se hace referencia a un puntero en una estructura, lo que nos obliga a utilizar espacio en memoria que realmente no estamos necesitando.
La solucion mas sencilla, en mi criterio seria esta:
Los parametros que le estamos pasando a las 2 funciones APIs (SetParent y ShowWindow) todos estan declarados como tipo Long, sin embargo cuando hacemos el llamado a la funcion le estamos pasando valores Int32. Entonces simplemente cambia el tipo de dato de estos parametros a Integer y deja el resto de la declaracion de las funciones igual.
Deberia quedar asi para que funcione:
Me parece que con ese pequeño cambio solucionas el problema.Código:
Private Declare Function SetParent Lib "user32" (ByVal hWndChild As Integer, ByVal hWndParent As Integer) As Long Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Integer, ByVal nCmdShow As Integer) As Long
Suerte
La solucion que he dado no tiene nada de complicada y es la solucion correcta. Si no se usa el tipo de datos IntPtr muchas funciones de la API de windows no funcionan si la aplicacion es 64-bit aparte de que se realizan conversiones de tipos que no son necesarias (¿acaso el tipo de datos de la propiedad Handle no es Intptr?).
El tipo de datos IntPtr representa a un puntero o a un controlador ("handle") y por lo tanto hace referencia a una region de memoria que ya esta asignada (toda las ventanas tienen un "handle"). En cualquier caso, lo que comentas sobre que "nos obliga a utilizar espacio en memoria que realmente no estamos necesitando" no tiene sentido ya que al asignar un valor a cualquier variable ya usamos un espacio de memoria, aunque para recuperar el valor no usemos punteros. Un puntero no es mas que una variable que contiene la dirección de memoria de un dato o de otra variable que contiene al dato y es la forma mas rapida de acceder al dato. Esto se nota cuando se trabaja con imagenes (accediendo a los pixeles) y en tareas similares.
.NET usa punteros aunque no lo veamos, por ejemplo en la clase BitConverter
En VB.NET no pueden usarse punteros pero si pueden usarse en C#.
Por ejemplo:
Aqui lo que se hace es crear la variable n (en VB seria Dim n As Integer = 1)
int n = 1;
Y aqui obtenemos la direccion (el puntero)
int* p = &n;
y aqui recuperamos el dato usando el puntero
int z = *P;
Volviendo a leer el tema me he dado cuenta que algunas personas no tienen claro que VB6 y VB.NET son muy diferentes aunque exista cierta compatibildad. La culpa de esto es de microso** y de ciertos usuarios que insisten en buscar una compatibilidad que no existe, o no deberia existir.
Sobre los tipos numericos, VB6 -> .NET
Integer en VB6 es un numero entero de 16 bit, en .NET es Int16 (Short en VB.NET) -> Numero entero 16-bit
Long en VB6 es un numero entero de 32-bit, en .NET es Int32 (Integer en VB.NET) -> Numero entero de 32 bit
Long en .NET es un numero entero de 64-bit (Int64)
Los "handle" pueden ser 32 o 64-bit, todo depende de la arquitectura de la maquina, y lo mismo ocurre con con el tipo de dato IntPtr (En maquinas 32-bit es 32-bit y en maquinas 64-bit es 64-bit, -> ver propiedad Size de IntPtr )