'以下在.Bas
Option Explicit
Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Long) As Long
Public coll As New Collection
'hWnd是Window傳給我們的Window handle,而lParam是我們呼叫EnumWindows()時的第
'二個參數值,在這個例子中,我們傳0進來,所以lParam一直是0
Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Boolean
Dim S As String, pid As Long
If GetParent(hwnd) = 0 Then
'讀取 hWnd 的視窗標題
S = String(80, 0)
Call GetWindowText(hwnd, S, 80)
S = Left(S, InStr(S, Chr(0)) - 1)
Call GetWindowThreadProcessId(hwnd, pid)
'當沒有標題的hWnd之pid被加入Coll的Collection時,若pid重覆會有錯,我們不管它
On Error Resume Next
If Len(S) = 0 Then
'沒有標題,則記錄Class Name
S = String(255, 0)
Call GetClassName(hwnd, S, 255)
S = Left(S, InStr(S, Chr(0)) - 1)
coll.Add "-!@" + S, Str(pid) 'key 為Pid
Else
'如果相同的pid記錄兩次,便會產生err, 而去執行errh的程式
On Error GoTo errh
If IsWindowVisible(hwnd) Then
coll.Add S, Str(pid)
End If
End If
End If
EnumWindowsProc = True ' 表示繼續列舉 hWnd
Exit Function
errh:
'如果先前coll 記錄key=pid的 那個Item記錄的是ClassName,則Item以Window
'的Title來取代
If Mid(coll.Item(Str(pid)), 1, 3) = "-!@" Then '表示先前以ClassName記錄
coll.Remove (Str(pid))
coll.Add S, Str(pid)
End If
EnumWindowsProc = True ' 表示繼續列舉 hWnd
End Function
|