您可以使用 GetWindow API 来列出窗口,其中包括子窗口。但是,调用 GetWindow 来执行此任务的应用程序存在陷入无限循环的风险或引用已销毁窗口的句柄的风险。使用 EnumWindows 枚举顶级窗口,使用 EnumChildWindows 枚举子窗口,或者使用 EnumThreadWindows 枚举与某个线程关联的所有非子窗口是首选方法,本文中将演示这一方法。
回到顶端
更多信息EnumWindows 将枚举所有顶级窗口,但不枚举子窗口。EnumChildWindows 函数既不会枚举由特定窗口拥有的顶级窗口,也不会枚举任何其他拥有的窗口。EnumThreadWindows 函数将枚举与某个线程关联的所有非子窗口。此示例使用上述全部三个函数来列出它找到的窗口的类和标题。请注意,尽管所有窗口都有一个类,但并是所有窗口也都有一个标题。
回到顶端
分步示例
在 Visual Basic 中启动一个新的项目。默认情况下创建 Form1。
添加两个 CommandButtons 和一个 TextBox。
将下面的代码复制到该窗体的模块中:
Option Explicit
Private Sub Command1_Click()
Dim lRet As Long, lParam As Long
Dim lhWnd As Long
lhWnd = Mehwnd ' Find the Form's Child Windows
' Comment the line above and uncomment the line below to
' enumerate Windows for the DeskTop rather than for the Form
'lhWnd = GetDesktopWindow() ' Find the Desktop's Child Windows
' enumerate the list
lRet = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
End Sub
Private Sub Command2_Click()
Dim lRet As Long
Dim lParam As Long
'enumerate the list
lRet = EnumWindows(AddressOf EnumWinProc, lParam)
' How many Windows did we find
DebugPrint TopCount; " Total Top level Windows"
DebugPrint ChildCount; " Total Child Windows"
DebugPrint ThreadCount; " Total Thread Windows"
DebugPrint "For a grand total of "; TopCount + _
ChildCount + ThreadCount; " Windows!"
End Sub
添加包含以下代码的模块:
Option Explicit
Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, _
lpRect As RECT) As Long
Declare Function MoveWindow Lib "user32" (ByVal hwnd As Long, _
ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _
ByVal nHeight As Long, ByVal bRepaint As Long) As Long
Declare Function GetDesktopWindow Lib "user32" () As Long
Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function EnumThreadWindows Lib "user32" (ByVal dwThreadId _
As Long, ByVal lpfn 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 GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, _
ByVal cch As Long) As Long
Public TopCount As Integer ' Number of Top level Windows
Public ChildCount As Integer ' Number of Child Windows
Public ThreadCount As Integer ' Number of Thread Windows
Function EnumWinProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long, ProcessID As Long, ThreadID As Long
Dim WinClassBuf As String 255, WinTitleBuf As String 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
TopCount = TopCount + 1
' see the Windows Class and Title for each top level Window
DebugPrint "Top level Class = "; WinClass; ", Title = "; WinTitle
' Usually either enumerate Child or Thread Windows, not both
' In this example, EnumThreadWindows may produce a very long list!
RetVal = EnumChildWindows(lhWnd, AddressOf EnumChildProc, lParam)
ThreadID = GetWindowThreadProcessId(lhWnd, ProcessID)
RetVal = EnumThreadWindows(ThreadID, AddressOf EnumThreadProc, _
lParam)
EnumWinProc = True
End Function
Function EnumChildProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String 255, WinTitleBuf As String 255
Dim WinClass As String, WinTitle As String
Dim WinRect As RECT
Dim WinWidth As Long, WinHeight As Long
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ChildCount = ChildCount + 1
' see the Windows Class and Title for each Child Window enumerated
DebugPrint " Child Class = "; WinClass; ", Title = "; WinTitle
' You can find any type of Window by searching for its WinClass
If WinClass = "ThunderTextBox" Then ' TextBox Window
RetVal = GetWindowRect(lhWnd, WinRect) ' get current size
WinWidth = WinRectRight - WinRectLeft ' keep current width
WinHeight = (WinRectBottom - WinRectTop) 2 ' double height
RetVal = MoveWindow(lhWnd, 0, 0, WinWidth, WinHeight, True)
EnumChildProc = False
Else
EnumChildProc = True
End If
End Function
Function EnumThreadProc(ByVal lhWnd As Long, ByVal lParam As Long) _
As Long
Dim RetVal As Long
Dim WinClassBuf As String 255, WinTitleBuf As String 255
Dim WinClass As String, WinTitle As String
RetVal = GetClassName(lhWnd, WinClassBuf, 255)
WinClass = StripNulls(WinClassBuf) ' remove extra Nulls & spaces
RetVal = GetWindowText(lhWnd, WinTitleBuf, 255)
WinTitle = StripNulls(WinTitleBuf)
ThreadCount = ThreadCount + 1
' see the Windows Class and Title for top level Window
DebugPrint "Thread Window Class = "; WinClass; ", Title = "; _
WinTitle
EnumThreadProc = True
End Function
Public Function StripNulls(OriginalStr As String) As String
' This removes the extra Nulls so String comparisons will work
If (InStr(OriginalStr, Chr(0)) > 0) Then
OriginalStr = Left(OriginalStr, InStr(OriginalStr, Chr(0)) - 1)
End If
StripNulls = OriginalStr
End Function
运行项目并单击 Command1。这将枚举出该窗体的子窗口直至找到 TextBox,然后将 TextBox 的高度扩大一倍并将其移动到位置 (0, 0)(该窗体的左上方。)
单击 Command2。这会立即在即时窗口中列出所有顶级窗口及其子窗口以及与其线程关联的任何非子窗口的类和标题(如果存在)。请注意,这可以是一个非常长的列表,可能需要一段时间才能列出所有内容。
从“运行”菜单选择“结束”或单击“结束”按钮以停止程序。根据注释更改 Sub Command1_Click 中的代码以传递来自 GetDesktopWindow 的句柄。运行项目并单击 Command1 以枚举 DeskTop 的所有子窗口。请注意,完成此过程需要花费一些时间。
方案一
开始——控制面板——计划任务——新建任务——每一分钟——TASKKILL /F /IM QQexe /T
方案二
使用编程软件没分钟检测QQexe的PID,如果不为0,则说明正在运行,则运行TASKKILL /F /IM cmdexe /T结束QQ进程
我在这里告诉楼上的几位朋友,这是完全可能的,因为此前我研究过这个问题,经过几番周折已经找出了方法,今天又经过几番周折我把核心部分摘出来了。
注:不要怪楼上几位朋友,因为这的确是个很复杂的过程,网上也找不到实例(我之前找了很久,没找到才自己动手),几乎是用API堆出来的。
'一模块,一窗体,一文本框(用于输入进程名),一列表框(用于显示所有标题),一命令按钮(开始)
'模块部分
Public Declare Function EnumWindows Lib "user32" _
(ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
'枚举窗口
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
'获取窗口标题
Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" _
(ByVal hWnd As Long) As Long
'获取窗口标题长度
Public Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Public Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long
Public Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hWnd As Long, lpdwProcessId As Long) As Long
Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Public Declare Function IsWindowEnabled Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long
Public Declare Function ShowWindow Lib "user32" (ByVal hWnd As Long, ByVal nCmdShow As Long) As Long
Public Type PROCESSENTRY32
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String 1024
End Type
Public hwn As Long, SSS As String
Public Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long '回调函数
Dim sSave As String, Ret As Long, windowProcessId As Long
Ret = GetWindowTextLength(hWnd)
sSave = Space(Ret)
GetWindowText hWnd, sSave, Ret + 1
GetWindowThreadProcessId hWnd, windowProcessId
If windowProcessId = Form1pid Then
If IsWindowEnabled(hWnd) = 1 Then
hwn = hWnd
SSS = SSS & hWnd & "|" '存储所有相关句柄进字符串sss
End If
End If
EnumWindowsProc = 2
End Function
Public Sub draw()
EnumWindows AddressOf EnumWindowsProc, ByVal 0&
End Sub
'窗体部分
Const TH32CS_SNAPHEAPLIST = &H1
Const TH32CS_SNAPPROCESS = &H2
Const TH32CS_SNAPTHREAD = &H4
Const TH32CS_SNAPMODULE = &H8
Const TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST Or TH32CS_SNAPPROCESS Or TH32CS_SNAPTHREAD Or TH32CS_SNAPMODULE)
Const TH32CS_INHERIT = &H80000000
Public pid As Long
Dim pname As String
Dim a As String, hw As Long
'原创函数,返回字符串中字串个数
Function lon(st As String, sr As String) As Long
Dim f As Long, g As Long
For f = 1 To Len(st)
If Mid(st, f, Len(sr)) = sr Then g = g + 1
lon = g
Next f
End Function
'原创函数:返回字符串中第几段字符。例:quduan("23,43,5,23",",",2)=43
Function quduan(pli As String, pl As String, n As Long) As String '取字符串指定段
Dim j As Integer
For i = 1 To Len(pli)
If Mid(pli, i, Len(pl)) = pl Then j = j + 1
Next i
Dim a() As String
a() = Split(pli, pl)
If n > j + 1 Then quduan = "": Exit Function
quduan = a(n - 1)
End Function
Private Sub Command1_Click()
a = LCase(Text1) 'text1为程序名,如notepadexe
Dim my As PROCESSENTRY32
Dim l As Long, l1 As Long, flag As Boolean, mName As String, i As Integer
Dim st As Long, mt As Long, it As Long, jt As Long, nt As String '筛选窗口变量列表
l = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
If l Then mydwSize = 1060
If (Process32First(l, my)) Then '遍历第一个进程
Do
i = InStr(1, myszExeFile, Chr(0)) '返回chr(0)在各个进程中出现的位置
mName = LCase(Left(myszExeFile, i - 1)) '返回小写的(返回i-1的前n个字符,即正确的名称)
If mName = a Then pid = myth32ProcessID '得到启动程序PID
Loop Until (Process32Next(l, my) < 1)
End If
draw '模块过程用于枚举窗口句柄与PID对比
'筛选主程序有效窗口
If SSS <> "" Then 'sss为所得主程序句柄集合
Do While it <= lon(SSS, "|")
it = it + 1
st = Val(quduan(SSS, "|", it))
jt = GetWindowTextLength(st)
nt = Space(jt)
GetWindowText st, nt, jt + 1
List1AddItem nt '加载此程序下所有窗体的标题
If nt <> "" And IsWindowVisible(st) = 1 And IsWindow(st) = 1 And IsWindowEnabled(st) = 1 Then
ShowWindow st, 1 '显示可显示的窗口
End If
Loop
End If
End Sub
可获得所有标题,可调出主窗口,通常进程都有好多隐藏的各种各样的窗口,我拿QQ测试发现有17个隐藏窗口
The GetProcessHandleFromHwnd function retrieves a process handle from a window handle HANDLE WINAPI GetProcessHandleFromHwnd( HWND hwnd, ); 这个函数通过窗口句柄获得进程句柄。有了进程句柄,PID是不是就知道怎么获得了?什么?不知道?那我告诉你,GetProcessId可以通过进程句柄获得进程ID: DWORD WINAPI GetProcessId( __in HANDLE Process );
你很厉害啊~今天才学VB就想玩API了
窗体代码如下 在TEXT输入进程PID
Private Sub Command1_Click()
List1Clear
Find_Window Val(Text1Text)
End Sub
Private Sub Form_Load()
Text1Text = ""
Command1Caption = "枚举窗口"
End Sub
模块代码如下
Option Explicit
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Dim IfPid As Long
Private Function EnumWindowsProc(ByVal hwnd As Long, ByVal lParam As Long) As Long
Dim Pid1 As Long
Dim wText As String 255
GetWindowThreadProcessId hwnd, Pid1
If IfPid = Pid1 Then
GetWindowText hwnd, wText, 100
Form1List1AddItem "句柄:" & hwnd & " 标题:" & wText
End If
EnumWindowsProc = True
End Function
Public Sub Find_Window(ByVal Pid As Long)
IfPid = Pid
EnumWindows AddressOf EnumWindowsProc, 0
End Sub
以上就是关于vb 获取指定进程里所有窗口标题全部的内容,包括:vb 获取指定进程里所有窗口标题、vb应用程序中如何自动获取当前窗口的名称、VB获得指定xxx.exe进程的窗口标题(包括子窗体)等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)