Visual Basic.NET - Problemas con la api SetParent

 
Vista:
Imágen de perfil de Evan Hailey
Val: 100
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Problemas con la api SetParent

Publicado por Evan Hailey (49 intervenciones) el 04/01/2020 21:11:40
Saludos, hoy escribo con idea de encontrar a alguien que entienda de apis de windows porque resulta que intento incrustar una ventana de emulador (Emulador Mame32) en un formulario y al parecer se incrusta, pero se queda congelada perdiendo su funcionalidad y no entiendo porque pasa esto.

Dejo el código que tengo mas una captura para que vean el problemas, desde ya agradeceré cualquier orientación al respecto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
Imports System.Runtime.InteropServices
Imports System.Threading
 
Public Class Formulario
 
    Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String,
                                                                             ByVal lpWindowName As String) As Int32
 
    Declare Auto Function SendMessage Lib "user32" (ByVal hwnd As IntPtr,
                                                    ByVal msg As Integer,
                                                    ByVal wParam As Integer,
                                                    ByVal lParam As Integer) As Integer
 
    Const WM_SYSCOMMAND As Integer = &H112
    Const SC_MINIMIZE As Integer = &HF020
    Const SC_MAXIMIZE As Integer = &HF030
 
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Public Shared Function SetParent(ByVal hWndChild As IntPtr,
                                     ByVal hWndNewParent As IntPtr) As IntPtr
    End Function
 
    Private myHWND As IntPtr = IntPtr.Zero
 
 
    Private Sub scene_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        myHWND = FindWindow("ClassMAME32", "Mortal Kombat (rev 5.0 T-Unit 03/19/93)")
        Me.Text = myHWND.ToString
    End Sub
 
    Private Sub scene_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        Thread.Sleep(500)
        SetParent(myHWND, Me.Handle)
        My.Application.DoEvents()
        Thread.Sleep(500)
        SendMessage(myHWND, WM_SYSCOMMAND, SC_MAXIMIZE, 0)
    End Sub
 
End Class


Resultado:


Preview001
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Evan Hailey
Val: 100
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Problemas con la api SetParent

Publicado por Evan Hailey (49 intervenciones) el 06/01/2020 16:32:28
Nadie saber porque podría estar pasando esto?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Problemas con la api SetParent

Publicado por Nacho (43 intervenciones) el 07/01/2020 06:03:26
Incrustar así una ventana en otra funciona peor cuanto más complejo es el proceso de la ventana incrustada, y un emulador no es un proceso sencillo.

SetParent sirve para cambiar de padre una ventana que ya es hija de otro padre. Una ventana que no es hija no tiene el estilo WS_CHILD, por ejemplo, y tampoco se lo pones. Una ventana que no es hija tiene su propio hilo de ejecución. Si la incrustas en otra, ese otro proceso ya tendrá dos hilos, pero a uno nunca le llegarán las entradas del usuario porque nunca le serán asignadas (AttachThreadInput). También tendrá su propia función de ventanas que ahora nunca se llama, por lo que se queda colgada, y quizá con asignarle al hilo las entradas ya se llame, o igual tienes que buscarla con SetWindowLong y llamarla tú mismo.

Con eso resolverás algunos problemas, y siempre quedarán otros.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Evan Hailey
Val: 100
Ha mantenido su posición en Visual Basic.NET (en relación al último mes)
Gráfica de Visual Basic.NET

Problemas con la api SetParent

Publicado por Evan Hailey (49 intervenciones) el 10/01/2020 14:06:35
Hu muchas gracias por tu respuesta, al menos ahora ya tengo una pista del problema, me podrías guiar para acomodar el hilo del emulador con la ventana del formulario, esta es la primera vez que lió con este tipo de cosas. Intento hacer algo para otros se beneficien.

Gracias!
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Problemas con la api SetParent

Publicado por Nacho (43 intervenciones) el 11/01/2020 07:04:10
Funciona perfectamente hasta donde funciona.

https://ibb.co/mSGTQbF

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public partial class Form1 : Form
{
    [DllImport("user32.dll", SetLastError = true)] static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll")] static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
    [DllImport("user32.dll", SetLastError = true)] static extern bool GetWindowRect(IntPtr hwnd, ref RECT lpRect);
    [DllImport("user32.dll", SetLastError = true)] static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
    [DllImport("user32.dll")] static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);
    [DllImport("user32.dll", SetLastError = true)] static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
    [DllImport("user32.dll")] static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
    [DllImport("kernel32.dll")] static extern uint GetCurrentThreadId();
    [DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
    [DllImport("user32.dll", EntryPoint = "GetWindowLong")] static extern int GetWindowLongPtr(IntPtr hWnd, int nIndex);
    [DllImport("user32.dll", EntryPoint = "SetWindowLong")] private static extern int SetWindowLongPtr64(IntPtr hWnd, int nIndex,int dwNewLong);
 
 
 
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
 
    public Form1()
    {
        InitializeComponent();
    }
 
    private void Form1_Load(object sender, EventArgs e)
    {
         IntPtr h = FindWindow(null, "MAME: Amstrad CPC6128+ [cpc6128p]");
         if (h != IntPtr.Zero)
         {
            RECT r = new RECT();
            GetWindowRect(h, ref r);
            SetParent(h, Handle);
            MoveWindow(h, 10, 10, r.Right-r.Left, r.Bottom-r.Top, false);
            uint hOtroThread = GetWindowThreadProcessId(h, IntPtr.Zero);
            uint hEsteThread = GetCurrentThreadId();
           AttachThreadInput(hOtroThread, hEsteThread, true);
 
 
        }
    }
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar