前天对EnumChildWindows函数的回调函数作了修改,提高了枚举速度,现备忘如下:
'为指定的父窗口枚举子窗口
Public Declare Function EnumChildWindows Lib "user32" Alias "EnumChildWindows" (ByVal hWndParent As System.IntPtr, ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
'枚举窗口的回调函数
Public Delegate Function EnumWindowsProc(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
'在类里建3个私有变量声明
Private strclassname As String
Private wintitle As String
Private intprthwnd As String
''' <summary>
''' 精确查找,枚举所有符合类名,标题名的窗口句柄,;父句柄为0表示桌面,类名\标题为空时用""表示.
''' </summary>
''' <param name="ParentHandle">要查找窗口的父窗口句柄,如果是桌面用0</param>
''' <param name="ClassName">被找窗口的类名</param>
''' <param name="StrTitle">被找窗口的标题</param>
''' <returns>带|隔开的字符串</returns>
''' <remarks></remarks>
Public Function SearchWin(ByVal ParentHandle As IntPtr, ByVal ClassName As String, ByVal StrTitle As String) As String
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
intprthwnd = Nothing
strclassname = ClassName
wintitle = StrTitle
Try
EnumChildWindows(ParentHandle, AddressOf SearchWinCallBack, GCHandle.ToIntPtr(ListHandle))
Catch ex As Exception
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return intprthwnd
'Return ChildrenList.ToArray
End Function
''' <summary>SearchWin枚举函数中回调函数的委托函数 </summary>
Private Function SearchWinCallBack(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Dim ChildrenList As List(Of IntPtr) = GCHandle.FromIntPtr(Parameter).Target
If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
Dim length As Integer = GetWindowTextLength(Handle)
Dim strTitle1 As New StringBuilder("", length)
Dim classname1 As New StringBuilder(255)
If strclassname <> "" And wintitle <> "" Then
If length <> 0 And Handle.ToInt32 <> 0 Then
GetWindowText(Handle, strTitle1, strTitle1.Capacity + 1)
GetClassName(Handle, classname1, 256)
If classname1.ToString = strclassname And strTitle1.ToString = wintitle Then
'intprthwnd += Handle.ToString & "|"
intprthwnd = Handle.ToString
Return False
End If
End If
ElseIf strclassname <> "" And wintitle = "" Then
If Handle.ToInt32 <> 0 Then
'GetWindowText(ChildrenList(i), strTitle1, strTitle1.Capacity + 1)
GetClassName(Handle, classname1, 256)
If classname1.ToString = strclassname Then
intprthwnd += Handle.ToString & "|"
End If
End If
ElseIf strclassname = "" And wintitle <> "" Then
If length <> 0 And Handle.ToInt32 <> 0 Then
GetWindowText(Handle, strTitle1, strTitle1.Capacity + 1)
'GetClassName(ChildrenList(i), classname1, 256)
If strTitle1.ToString = wintitle Then
intprthwnd += Handle.ToString & "|"
End If
End If
Else
intprthwnd += Handle.ToString & "|"
End If
'ChildrenList.Add(Handle)
Return True
End Function
''' <summary>
''' 模糊查找,枚举所有符合类名,标题名的窗口句柄,;父句柄为0表示桌面,类名\标题为空时用""表示.
''' </summary>
''' <param name="ParentHandle">要查找窗口的父窗口句柄,如果是桌面用0</param>
''' <param name="ClassName">被找窗口的类名</param>
''' <param name="StrTitle">被找窗口的标题</param>
''' <returns>带|隔开的字符串</returns>
''' <remarks></remarks>
Public Function SearchWinInstr(ByVal ParentHandle As IntPtr, ByVal ClassName As String, ByVal StrTitle As String) As String
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
intprthwnd = Nothing
strclassname = ClassName
wintitle = StrTitle
Try
EnumChildWindows(ParentHandle, AddressOf SearchWinInstrCallBack, GCHandle.ToIntPtr(ListHandle))
Catch ex As Exception
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
Return intprthwnd
'Return ChildrenList.ToArray
End Function
''' <summary>SearchWinInstr枚举函数中回调函数的委托函数 </summary>
Private Function SearchWinInstrCallBack(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Dim ChildrenList As List(Of IntPtr) = GCHandle.FromIntPtr(Parameter).Target
If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
Dim length As Integer = GetWindowTextLength(Handle)
Dim strTitle1 As New StringBuilder("", length)
Dim classname1 As New StringBuilder(255)
If strclassname <> "" And wintitle <> "" Then
If length <> 0 And Handle.ToInt32 <> 0 Then
GetWindowText(Handle, strTitle1, strTitle1.Capacity + 1)
GetClassName(Handle, classname1, 256)
If InStr(classname1.ToString, strclassname) And InStr(strTitle1.ToString, wintitle) Then
intprthwnd += Handle.ToString & "|"
'intprthwnd = Handle.ToString
End If
End If
ElseIf strclassname <> "" And wintitle = "" Then
If Handle.ToInt32 <> 0 Then
'GetWindowText(ChildrenList(i), strTitle1, strTitle1.Capacity + 1)
GetClassName(Handle, classname1, 256)
If InStr(classname1.ToString, strclassname) Then
intprthwnd += Handle.ToString & "|"
End If
End If
ElseIf strclassname = "" And wintitle <> "" Then
If length <> 0 And Handle.ToInt32 <> 0 Then
GetWindowText(Handle, strTitle1, strTitle1.Capacity + 1)
'GetClassName(ChildrenList(i), classname1, 256)
If InStr(strTitle1.ToString, wintitle) Then
intprthwnd += Handle.ToString & "|"
End If
End If
Else
intprthwnd += Handle.ToString & "|"
End If
'ChildrenList.Add(Handle)
Return True
End Function
Imports System.Runtime.InteropServices
Imports System.Text
'为指定的父窗口枚举子窗口
Public Declare Function EnumChildWindows Lib "user32" Alias "EnumChildWindows" (ByVal hWndParent As System.IntPtr, ByVal lpEnumFunc As EnumWindowProcess, ByVal lParam As Integer) As Boolean
'枚举窗口列表中的所有父窗口(顶级和被所有窗口)
Public Delegate Function EnumWindowProcess(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Integer, ByVal lpString As System.Text.StringBuilder, ByVal cch As Integer) As Integer
Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As System.IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As IntPtr) As Integer
Public Function EnumInstrWin(ByVal ParentHandle As IntPtr, ByVal ClassName As String, ByVal StrTitle As String) As String
Dim ChildrenList As New List(Of IntPtr)
Dim ListHandle As GCHandle = GCHandle.Alloc(ChildrenList)
Dim strhwnd As String = Nothing
' Instr函数与InstrRev函数的区别()
'“InstrRev(String1,String2),InstrRev函数与Instr函数的功能类似,
'不同之处在于InstrRev函数是从字符串尾部开始进行搜索,
'而Instr函数是从字符串首部开始进行搜索。
Try
EnumChildWindows(ParentHandle, AddressOf CallBackAddressOfFunction, GCHandle.ToIntPtr(ListHandle))
For i As Integer = 0 To ChildrenList.Count - 1
Dim length As Integer = GetWindowTextLength(ChildrenList(i))
Dim strTitle1 As New StringBuilder("", length)
Dim classname1 As New StringBuilder(255)
If ClassName <> "" And StrTitle <> "" Then
If length <> 0 And ChildrenList(i).ToInt32 <> 0 Then
GetWindowText(ChildrenList(i), strTitle1, strTitle1.Capacity + 1)
GetClassName(ChildrenList(i), classname1, 256)
If InStr(classname1.ToString, ClassName) And InStr(strTitle1.ToString, StrTitle) Then
strhwnd += CInt(ChildrenList(i)) & "|"
End If
End If
ElseIf ClassName <> "" And StrTitle = "" Then
If ChildrenList(i).ToInt32 <> 0 Then
'GetWindowText(ChildrenList(i), strTitle1, strTitle1.Capacity + 1)
GetClassName(ChildrenList(i), classname1, 256)
If InStr(classname1.ToString, ClassName) Then
strhwnd += CInt(ChildrenList(i)) & "|"
End If
End If
ElseIf ClassName = "" And StrTitle <> "" Then
If length <> 0 And ChildrenList(i).ToInt32 <> 0 Then
GetWindowText(ChildrenList(i), strTitle1, strTitle1.Capacity + 1)
'GetClassName(ChildrenList(i), classname1, 256)
If InStr(strTitle1.ToString, StrTitle) Then
strhwnd += CInt(ChildrenList(i)) & "|"
End If
End If
Else
strhwnd += CInt(ChildrenList(i)) & "|"
End If
Next
Finally
If ListHandle.IsAllocated Then ListHandle.Free()
End Try
'Return ChildrenList.ToArray '原始语句
EnumInstrWin = strhwnd
End Function
Private Shared Function CallBackAddressOfFunction(ByVal Handle As IntPtr, ByVal Parameter As IntPtr) As Boolean
Dim ChildrenList As List(Of IntPtr) = GCHandle.FromIntPtr(Parameter).Target
If ChildrenList Is Nothing Then Throw New Exception("GCHandle Target could not be cast as List(Of IntPtr)")
ChildrenList.Add(Handle)
Return True
End Function