235 lines
8.8 KiB
VB.net
235 lines
8.8 KiB
VB.net
Imports System.Text
|
|
|
|
Public Class ClassWindowAPI
|
|
Const WM_GETTEXT As Int32 = &HD
|
|
Const WM_GETTEXTLENGTH As Int32 = &HE
|
|
|
|
Public Class ApiWindow
|
|
Public MainWindowTitle As String = ""
|
|
Public ClassName As String = ""
|
|
Public hWnd As Int32
|
|
End Class
|
|
|
|
Public Class WindowInfo
|
|
Public WindowTitle As String = ""
|
|
Public ProcessName As String = ""
|
|
Public ClassName As String = ""
|
|
Public ProcessId As Integer = 0
|
|
Public ControlName As String = ""
|
|
Public hWnd As IntPtr
|
|
End Class
|
|
|
|
Private Delegate Function EnumCallBackDelegate(ByVal hwnd As Integer, ByVal lParam As Integer) As Integer
|
|
|
|
Private Declare Function GetCurrentThreadId Lib "kernel32.dll" Alias "GetCurrentThreadId" () As IntPtr
|
|
Private Declare Function AttachThreadInput Lib "user32.dll" Alias "AttachThreadInput" (ByVal idAttach As IntPtr, ByVal idAttachTo As IntPtr, fAttach As Boolean) As Boolean
|
|
Private Declare Function GetFocus Lib "user32.dll" Alias "GetFocus" () As IntPtr
|
|
Private Declare Function GetForegroundWindow Lib "user32.dll" Alias "GetForegroundWindow" () As IntPtr
|
|
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As IntPtr, ByRef lpdwProcessID As Integer) As Integer
|
|
Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hWnd As IntPtr, ByVal WinTitle As String, ByVal MaxLength As Integer) As Integer
|
|
Private Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hwnd As Int32) As Integer
|
|
|
|
' Top-level windows.
|
|
Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnumCallBackDelegate, ByVal lParam As Integer) As Integer
|
|
|
|
' Child windows.
|
|
Private Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Integer, ByVal lpEnumFunc As EnumCallBackDelegate, ByVal lParam As Integer) As Integer
|
|
|
|
' Get the window class.
|
|
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Integer, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer) As Integer
|
|
|
|
' Test if the window is visible--only get visible ones.
|
|
Private Declare Function IsWindowVisible Lib "user32" (ByVal hwnd As Integer) As Integer
|
|
|
|
' Test if the window's parent--only get the one's without parents.
|
|
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Integer) As Integer
|
|
|
|
' Get window text length signature.
|
|
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As Int32) As Int32
|
|
|
|
' Get window text signature.
|
|
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Int32, ByVal wParam As Int32, ByVal lParam As StringBuilder) As Int32
|
|
|
|
Private _listChildren As New List(Of WindowInfo)
|
|
Private _listTopLevel As New List(Of WindowInfo)
|
|
|
|
Private _topLevelClass As String = ""
|
|
Private _childClass As String = ""
|
|
|
|
''' <summary>
|
|
''' Get all top-level window information
|
|
''' </summary>
|
|
''' <returns>List of window information objects</returns>
|
|
Public Overloads Function GetTopLevelWindows() As List(Of WindowInfo)
|
|
|
|
EnumWindows(AddressOf EnumWindowProc, &H0)
|
|
|
|
Return _listTopLevel
|
|
|
|
End Function
|
|
|
|
Public Overloads Function GetTopLevelWindows(ByVal className As String) As List(Of WindowInfo)
|
|
_topLevelClass = className
|
|
|
|
Return GetTopLevelWindows()
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Get all child windows for the specific windows handle (hwnd).
|
|
''' </summary>
|
|
''' <returns>List of child windows for parent window</returns>
|
|
Public Overloads Function GetChildWindows(ByVal hwnd As Int32) As List(Of WindowInfo)
|
|
' Clear the window list.
|
|
_listChildren = New List(Of WindowInfo)
|
|
|
|
' Start the enumeration process.
|
|
EnumChildWindows(hwnd, AddressOf EnumChildWindowProc, &H0)
|
|
|
|
' Return the children list when the process is completed.
|
|
Return _listChildren
|
|
End Function
|
|
|
|
Public Overloads Function GetChildWindows(ByVal hwnd As Int32, ByVal childClass As String) As List(Of WindowInfo)
|
|
' Set the search
|
|
_childClass = childClass
|
|
|
|
Return GetChildWindows(hwnd)
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Callback function that does the work of enumerating top-level windows.
|
|
''' </summary>
|
|
''' <param name="hwnd">Discovered Window handle</param>
|
|
''' <returns>1=keep going, 0=stop</returns>
|
|
Private Function EnumWindowProc(ByVal hwnd As Int32, ByVal lParam As Int32) As Int32
|
|
|
|
' Eliminate windows that are not top-level.
|
|
If GetParent(hwnd) = 0 AndAlso CBool(IsWindowVisible(hwnd)) Then
|
|
|
|
' Get the window title / class name.
|
|
Dim oWindow As WindowInfo = GetWindowInfo(hwnd)
|
|
|
|
' Match the class name if searching for a specific window class.
|
|
If _topLevelClass.Length = 0 OrElse oWindow.ClassName.ToLower() = _topLevelClass.ToLower() Then
|
|
_listTopLevel.Add(oWindow)
|
|
End If
|
|
|
|
End If
|
|
|
|
' To continue enumeration, return True (1), and to stop enumeration
|
|
' return False (0).
|
|
' When 1 is returned, enumeration continues until there are no
|
|
' more windows left.
|
|
Return 1
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Callback function that does the work of enumerating child windows.
|
|
''' </summary>
|
|
''' <param name="hwnd">Discovered Window handle</param>
|
|
''' <returns>1=keep going, 0=stop</returns>
|
|
Private Function EnumChildWindowProc(ByVal hwnd As Int32, ByVal lParam As Int32) As Int32
|
|
|
|
Dim oWindow As WindowInfo = GetWindowInfo(hwnd)
|
|
|
|
' Attempt to match the child class, if one was specified, otherwise
|
|
' enumerate all the child windows.
|
|
If _childClass.Length = 0 OrElse oWindow.ClassName.ToLower() = _childClass.ToLower() Then
|
|
_listChildren.Add(oWindow)
|
|
End If
|
|
|
|
Return 1
|
|
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Returns Information about the Window with `hWnd`
|
|
''' </summary>
|
|
Public Shared Function GetWindowInfo(ByVal hWnd As Integer) As WindowInfo
|
|
Dim oPID As Integer = 0
|
|
Dim oTitleLength As Int32 = GetWindowTextLength(hWnd)
|
|
Dim oWindowTitle As String = StrDup(oTitleLength + 1, "*")
|
|
Dim oClassBuilder As New StringBuilder(64)
|
|
|
|
GetWindowText(hWnd, oWindowTitle, oTitleLength + 1)
|
|
GetWindowThreadProcessId(hWnd, oPID)
|
|
|
|
If oPID = 0 Then
|
|
Return Nothing
|
|
End If
|
|
|
|
Dim oProcess As Process = Process.GetProcessById(oPID)
|
|
|
|
If oProcess Is Nothing Then
|
|
Return Nothing
|
|
End If
|
|
|
|
GetClassName(hWnd, oClassBuilder, 64)
|
|
|
|
Return New WindowInfo With {
|
|
.hWnd = hWnd,
|
|
.ClassName = oClassBuilder.ToString,
|
|
.ProcessId = oProcess.Id,
|
|
.ProcessName = oProcess.ProcessName,
|
|
.WindowTitle = oWindowTitle
|
|
}
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Returns Information about the currently focused window
|
|
''' </summary>
|
|
Public Shared Function GetWindowInfo() As WindowInfo
|
|
Dim hWnd As IntPtr = GetForegroundWindow()
|
|
If hWnd = IntPtr.Zero Then
|
|
Return Nothing
|
|
End If
|
|
|
|
Return GetWindowInfo(hWnd)
|
|
End Function
|
|
|
|
''' <summary>
|
|
'''
|
|
''' </summary>
|
|
''' <param name="WindowHandle">Current window handle; can be obtained from Me.Handle</param>
|
|
''' <returns></returns>
|
|
Public Shared Function GetFocusedControl(WindowHandle As IntPtr) As WindowInfo
|
|
Try
|
|
Dim oWindow = GetWindowInfo()
|
|
|
|
If oWindow Is Nothing Then
|
|
Return Nothing
|
|
End If
|
|
|
|
Dim oThreadId As IntPtr = GetWindowThreadProcessId(oWindow.hWnd, IntPtr.Zero)
|
|
Dim oMyThreadId As IntPtr = GetWindowThreadProcessId(WindowHandle, IntPtr.Zero)
|
|
|
|
If AttachThreadInput(oThreadId, oMyThreadId, True) Then
|
|
Try
|
|
Dim oControlhWnd = GetFocus()
|
|
Dim oControl As WindowInfo = GetWindowInfo(oControlhWnd)
|
|
|
|
If oControl Is Nothing Then
|
|
Return Nothing
|
|
End If
|
|
|
|
Dim oUtils As New ClassWindowAPIUtils()
|
|
Dim oName = oUtils.GetWinFormsId(oControlhWnd)
|
|
oControl.ControlName = oName
|
|
|
|
Return oControl
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Finally
|
|
AttachThreadInput(oThreadId, oMyThreadId, False)
|
|
End Try
|
|
End If
|
|
|
|
Return Nothing
|
|
Catch ex As Exception
|
|
Logger.Error(ex)
|
|
Return Nothing
|
|
End Try
|
|
|
|
End Function
|
|
End Class
|