Trucos Activar aplicación abierta con Shell

En alguna ocasión podemos necesitar que un botón de nuestra aplicación arranque otra. Esto de puede hacer de varias maneras, una de ellas mediante el comando Shell de Visual Basic. También es posible que queramos que si volvemos a pulsar dicho botón no se arranque una nueva instancia de la aplicación sino que se active la que arrancamos con anterioridad.
Para ello podemos guardar en una variable long (por ejemplo PId) el valor que devuelve el shell. Si es distinto de cero es que abrió la aplicación.
Luego guardamos en otra el hwnd de la aplicación. Para obtener el hWnd a partir del PId emplearemos una función que se muestra a continuación.
Luego, cuando vayamos a ejecutar la aplicación por segunda vez comprobamos primero si todavía existe el PId (con una función muy similar a la obtener el hWnd del PId) y si existe utilizamos Showwindow para ponerla en primer plano :

Uso de SHowWindow :
Private Declare Function ShowWindow Lib "user32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long
Const SW_SHOW = 5
Const SW_SHOWDEFAULT = 10
Const SW_SHOWMAXIMIZED = 3
Const SW_SHOWMINIMIZED = 2
Const SW_SHOWMINNOACTIVE = 7
Const SW_SHOWNA = 8
Const SW_SHOWNOACTIVATE = 4
Const SW_SHOWNORMAL = 1

Y para activar la aplicación :

Dim res as long

res = ShowWindow(hwnd, SW_SHOW)


Para obtener el hWnd a partir del PId :

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal
lpClassName As Long, ByVal lpWindowName As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd
As Long, lpdwProcessId As Long) As Long
Private Declare Function GetWindow Lib "user32" (ByVal hwnd As Long, ByVal
wCmd As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function Putfocus Lib "user32" Alias "SetFocus" (ByVal hwnd
As Long) As Long
Const GW_HWNDNEXT = 2
Dim mWnd As Long
Function InstanceToWnd(ByVal target_pid As Long) As Long
    Dim test_hwnd As Long, test_pid As Long, test_thread_id As Long
    'Find the first window
    test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
    Do While test_hwnd <> 0
        'Check if the window isn't a child
        If GetParent(test_hwnd) = 0 Then
            'Get the window's thread
            test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
            If test_pid = target_pid Then
                InstanceToWnd = test_hwnd
                Exit Do
            End If
        End If
        'retrieve the next window
        test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
    Loop
End Function

Para buscar si existe todavía el PId podemos hacer algo como :

Function ExistePId(ByVal target_pid As Long) As boolean
    Dim test_hwnd As Long, test_pid As Long, test_thread_id As Long
    Dim Existe as boolean

    Existe = false
    'Find the first window
    test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
    Do While test_hwnd <> 0
        'Check if the window isn't a child
        If GetParent(test_hwnd) = 0 Then
            'Get the window's thread
            test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
            If test_pid = target_pid Then
                Existe = true
                Exit Do
            End If
        End If
        'retrieve the next window
        test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
    Loop
    ExistePId = Existe
End Function



Trucos Trucos

Visual Basic Página de Visual Basic

Página principal Página principal

www.jrubi.com