32. Pid2Hwnd(), czyli jak z identyfikatora instancji Pid uzyskać uchwyt okna Hwnd?
Zdarza się, że otwieramy zewnętrzny program (za pomocą Shell) i chcielibyśmy uzyskać dostęp do
jego okna. Jednak funkcja Shell(...) zwraca jedynie Pid, czyli identyfikator wywołanego programu. Poniższy kod pokazuje jak z tego identyfikatora odczytać uchwyt okna?
'Kod w module głównym
Public Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function GetWindow Lib "user32" _
(ByVal hwnd As Long, ByVal wCmd As Long) As Long
Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" _
(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Public Const GW_HWNDNEXT = 2
Function Pid2Hwnd(ByVal target_pid As Long) As Long
Dim test_hwnd As Long, test_pid As Long, test_thread_id As Long
test_hwnd = FindWindow(ByVal 0&, ByVal 0&)
Do While test_hwnd <> 0
If GetParent(test_hwnd) = 0 Then
test_thread_id = GetWindowThreadProcessId(test_hwnd, test_pid)
If test_pid = target_pid Then
Pid2Hwnd = test_hwnd
Exit Do
End If
End If
test_hwnd = GetWindow(test_hwnd, GW_HWNDNEXT)
Loop
End Function
Do czego
nam taki odczyt może się przydać? To już zależy tylko od naszej pomysłowości...
Np można w ten sposób zamknąć okienko DOS, które wywołaliśmy do naszych celów,
można też w ten sposób uzyskać dostęp do zaawansowanych elementów okna w
zewnętrznej aplikacji. Poniższy przykład jest bardzo prosty i ma na celu jedynie
przedstawić zasadę:
'Kod na formularzu
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Private Declare Function PostMessage Lib "user32" Alias "PostMessageA" _
(ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Const WM_CHAR = &H102
Private Const WM_CLOSE = &H10
'Naciśnięcie przycisku wywołuje kalkulator, następnie procedura odczytuje jego uchwyt okna.
'Do tak odczytanego okna przekazujemy kilka komunikatów, a na koniec zamykamy wywołany program.
Private Sub Wylicz_Click()
Dim pid As Long, mWnd As Long, ret
pid = Shell("Calc.exe")
mWnd = Pid2Hwnd(pid)
PostMessage mWnd, WM_CHAR, Asc("2"), 0
PostMessage mWnd, WM_CHAR, Asc("*"), 0
PostMessage mWnd, WM_CHAR, Asc("3"), 0
PostMessage mWnd, WM_CHAR, Asc("="), 0
MsgBox "Skopiuj wynik. Kalkulator zostanie zamknięty automatycznie."
SendMessage mWnd, WM_CLOSE, 0, 0
End Sub
Zobacz tez wątki
1 i
2 w archiwum grupy dyskusyjnej.