Private Declare Function GetForegroundWindow Lib "user32" () As Long 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 Const WM_CLOSE = &H10Public Sub CloseActiveWindow() Dim hWnd As Long hWnd = GetForegroundWindow() SendMessage hWnd, WM_CLOSE, 0, 0 End Sub
其實,這只是找一下沒有Parent且為Top-Level的可見視窗,主要用EnumWindows來巡行螢幕上的視窗,而這個Function不會找Windows,而且需一個EnumWindowsProc callbackfunction,這個EnumWindowsProc 傳回1時,表示繼續巡行,直到沒有符合條件的Window才結束,若傳回0表示立即停止巡行,而結束EnumWindows的呼叫。另有一件頭大的事,一個Process可能會包含有許多Windows,這些Widnows有些可見,有不可見,用IsWindowVisible可去除不可見的Window;但如果一個Process有兩個Top-Level且可見的Window(如:VB中一個Project有兩個Form,且同時出現時),我們要找的是Process而非Window,所以這種情況我們要將其中一個去除,只留下一個。而EmunWindowsProc傳給我們的是hWnd,所以我們使用GetWindowThreadProcessId來取得ProcessID,同一個ProcessID代表是相同的Process,我們記錄這些ProcessID,而且相同的ProcessID只能記錄一次,而且在記錄ProcessID時順帶將該Window的Title也記錄下來,若沒有Title則記錄ClassName。要完成這個動作,我選用Collection來做。 註: 1.這只是取得電腦上正常,且有Window的Process,有一些奇特的Process它可沒有那麼容易就可以取得,而且我也不知該如何取得,您所表列的Process,可以和Window按ctl-alt-delete所列出的Process表列做一比較。 2.主要是介紹EnumWindows的運用'以下在.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 LongPublic 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'以下在form,需一個Command1, 一個ListBox Private Sub Command1_Click() Dim co As Variant List1.Clear Call EnumWindows(AddressOf EnumWindowsProc, 0&) For Each co In coll If Mid(co, 1, 3) = "-!@" Then co = "Class Name:" + Mid(co, 4) End If List1.AddItem co Next End Sub
EnumWindows Windows Overview Window Functions GetClassName GetParent GetWindowText GetWindowThreadProcessId Q183009 - HOWTO- Enumerate Windows Using the WIN32 API
再给你一点提示,如果你用的是winnt or win2k,当你按在ctrl+alt+del后在任务管理嚣中有分应用程序和进程, 你注意看应用程序中位于第一的是你的最上层window,第二个就是你缩小最上层window后看到的window.
问题是。我把应用窗口找到。也是按任务管理嚣那样排列,不过是太多了。像我用winamp听歌得到 Winamp Playlist Editor Winamp Minibrowser Winamp Equalizer 5. 王菲 - 03 Eyes On Me featured in FINA - Winamp 而管理嚣得到的是 5. 王菲 - 03 Eyes On Me featured in FINA - Winamp 咋判断?
通过实例学习窗口函数-取得IE地址栏的地址 下载
這個問題常常見到,所以特別把他整理起來 程式如下
Private Declare Function GetForegroundWindow Lib "user32" () As Long
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 Const WM_CLOSE = &H10Public Sub CloseActiveWindow()
Dim hWnd As Long
hWnd = GetForegroundWindow()
SendMessage hWnd, WM_CLOSE, 0, 0
End Sub
不过你是要做一个软键盘程序,而你用软键盘控制其它window时,你的软键盘就是active window,所以你要用变通的方式.
嘗試尋找電腦中執行的程式(EnumWindows)
其實,這只是找一下沒有Parent且為Top-Level的可見視窗,主要用EnumWindows來巡行螢幕上的視窗,而這個Function不會找Windows,而且需一個EnumWindowsProc callbackfunction,這個EnumWindowsProc 傳回1時,表示繼續巡行,直到沒有符合條件的Window才結束,若傳回0表示立即停止巡行,而結束EnumWindows的呼叫。另有一件頭大的事,一個Process可能會包含有許多Windows,這些Widnows有些可見,有不可見,用IsWindowVisible可去除不可見的Window;但如果一個Process有兩個Top-Level且可見的Window(如:VB中一個Project有兩個Form,且同時出現時),我們要找的是Process而非Window,所以這種情況我們要將其中一個去除,只留下一個。而EmunWindowsProc傳給我們的是hWnd,所以我們使用GetWindowThreadProcessId來取得ProcessID,同一個ProcessID代表是相同的Process,我們記錄這些ProcessID,而且相同的ProcessID只能記錄一次,而且在記錄ProcessID時順帶將該Window的Title也記錄下來,若沒有Title則記錄ClassName。要完成這個動作,我選用Collection來做。 註:
1.這只是取得電腦上正常,且有Window的Process,有一些奇特的Process它可沒有那麼容易就可以取得,而且我也不知該如何取得,您所表列的Process,可以和Window按ctl-alt-delete所列出的Process表列做一比較。
2.主要是介紹EnumWindows的運用'以下在.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 LongPublic 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'以下在form,需一個Command1, 一個ListBox
Private Sub Command1_Click()
Dim co As Variant
List1.Clear
Call EnumWindows(AddressOf EnumWindowsProc, 0&)
For Each co In coll
If Mid(co, 1, 3) = "-!@" Then
co = "Class Name:" + Mid(co, 4)
End If
List1.AddItem co
Next
End Sub
--------------------------------------------------------------------------------
相關資訊
EnumWindows Windows Overview Window Functions GetClassName GetParent GetWindowText GetWindowThreadProcessId Q183009 - HOWTO- Enumerate Windows Using the WIN32 API
你注意看应用程序中位于第一的是你的最上层window,第二个就是你缩小最上层window后看到的window.
Winamp Playlist Editor
Winamp Minibrowser
Winamp Equalizer
5. 王菲 - 03 Eyes On Me featured in FINA - Winamp
而管理嚣得到的是
5. 王菲 - 03 Eyes On Me featured in FINA - Winamp
咋判断?