CISA FotoGallery

Statistiche

Tot. visite contenuti : 927938
Home Articoli tecnici API Lanciare un Processo con Shell e recuperare l'Hwnd

Lanciare un Processo con Shell e recuperare l'Hwnd

L'istruzione Shell usata per lanciare un processo non restituisce l'Hwnd ma il Process ID.
La conversione dal PID all'Hwnd non è diretta, ma serve passare per l'Enum dei processi ed alla funzione GetWindowThreadProcessId.
Questo codice è abbastanza complesso anche per l'uso della funzione di Callback per l'accesso all'Enum dei processi.

Una volta ricavato l'Hwnd del processo è possibile sfruttare SendMessage o PostMessage per gestirlo, magari passando un WM_CLOSE per chiuderlo oppure inviare a ShowWindow per modificare l'aspetto...!

CODICE

Option Compare Database
Option Explicit

Declare Function
GetParent Lib "user32" _
(ByVal hwnd As Long) As Long
Declare Function
EnumWindows Lib "user32.dll" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function
GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long

Private Type
EnumWindowsData
      ProcessID As Long
      
hwnd As Long
End Type
  
'******************************************************************
' Esegue il nuovo processo e restituisce l'Hwnd
' della sua Finestra principale.
'******************************************************************
Public Function hWndShell(ByVal Job As String, _
      Optional WindowStyle As VbAppWinStyle = vbMinimizedNoFocus) As Long
    Dim
ProcessID As Long

    
' Verifica che il WindowStyle sia applicabile
    
If (WindowStyle < vbHide) Or (WindowStyle > vbMinimizedNoFocus) Then
        
WindowStyle = vbMinimizedNoFocus
    End If
    
' Lancia il processo con la modalità richiesta.
    
On Error Resume Next
    
ProcessID = Shell(Job, WindowStyle)
    On Error GoTo 0
    ' Recupera l'Handle della finestra relativa al nuovo processo.
    
If ProcessID Then
        
hWndShell = hWndProcess(ProcessID)
    End If
End Function

Public Function
hWndProcess(ByVal ProcessID As Long) As Long
    Dim
ewd As EnumWindowsData
    '******************************************************************
    ' Cicla attraverso l'Enumerazione delle Finestre di sistema cercando di recuperare
    ' l'hWnd della Main Window puntata dal Processo.
    '******************************************************************
    
ewd.ProcessID = ProcessID
    Call EnumWindows(AddressOf EnumWindowsProc, VarPtr(ewd))
    hWndProcess = ewd.hwnd
End Function

'***********************************
' Private Methods
'***********************************
Private Function EnumWindowsProc(ByVal hwnd As Long, _
                lParam As EnumWindowsData) As Long
    Dim
PID As Long     ' Verifica che sia una top-level window.
    
If GetParent(hwnd) = 0 Then
        
' Verifica il processo di appartenenza
        
Call GetWindowThreadProcessId(hwnd, PID)
        If PID = lParam.ProcessID Then
            
lParam.hwnd = hwnd
        End If
    End If
    
' Restituisce True per continuare se non ha trovato
    ' l'Hwnd relativo al PID.
    
EnumWindowsProc = (lParam.hwnd = 0)
End Function


Articolo ripreso da [microsoft.public.vb.winapi]