DRJ
asked on
Help with enumerating child windows
I am trying to loop through all the controls on an external application window. I have the handle for that window but am not able to get the EnumChildWindows to work for me.
So basically I want to start with a handle and loop through all the child controls and return the text.
This is for VB.Net
Thanks
So basically I want to start with a handle and loop through all the child controls and return the text.
This is for VB.Net
Thanks
ASKER
I saw some of these, couldn't get any of them to work right.
I had some examples working in Excel but when I tried in visual studio I am getting an error, but think I am getting closer.
The error is: 'AddressOf; expression cannot be converted to 'Long' because 'Long' is a delegate type.
Public Class Form1
Declare Function GetParent Lib "user32" (ByVal hwnd 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 GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _
ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function SendMessageS Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Declare Function FindWindowX Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As Long, ByVal lpsz2 As Long) As Long
Public Declare Function APIGetTopWindow Lib "user32" Alias "GetTopWindow" (ByVal hwnd As Integer) As Integer
Public Declare Function APIGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Integer
Public Const WM_GETTEXT = &HD
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Hwnd
Hwnd = APIGetTopWindow(APIGetDesk topWindow)
Call EnumChildWindows(Hwnd, AddressOf EnumChildWindow, 0&)
End Sub
Function EnumChildWindow(ByVal hChild As Long, ByVal lParam As Long) As Long
Dim wClass As String, wText As String
Dim j As Integer
wClass = Space(64)
j = GetClassName(hChild, wClass, 63)
wClass = Microsoft.VisualBasic.Left (wClass, j)
wText = Space(256)
j = SendMessageS(hChild, WM_GETTEXT, 255, wText)
wText = Microsoft.VisualBasic.Left (wText, j)
EnumChildWindow = 1 ' Continue enumeration
End Function
End Class
I had some examples working in Excel but when I tried in visual studio I am getting an error, but think I am getting closer.
The error is: 'AddressOf; expression cannot be converted to 'Long' because 'Long' is a delegate type.
Public Class Form1
Declare Function GetParent Lib "user32" (ByVal hwnd 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 GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hwnd As Long, _
ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Declare Function SendMessageS Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Declare Function FindWindowX Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As Long, ByVal lpsz2 As Long) As Long
Public Declare Function APIGetTopWindow Lib "user32" Alias "GetTopWindow" (ByVal hwnd As Integer) As Integer
Public Declare Function APIGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Integer
Public Const WM_GETTEXT = &HD
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Hwnd
Hwnd = APIGetTopWindow(APIGetDesk
Call EnumChildWindows(Hwnd, AddressOf EnumChildWindow, 0&)
End Sub
Function EnumChildWindow(ByVal hChild As Long, ByVal lParam As Long) As Long
Dim wClass As String, wText As String
Dim j As Integer
wClass = Space(64)
j = GetClassName(hChild, wClass, 63)
wClass = Microsoft.VisualBasic.Left
wText = Space(256)
j = SendMessageS(hChild, WM_GETTEXT, 255, wText)
wText = Microsoft.VisualBasic.Left
EnumChildWindow = 1 ' Continue enumeration
End Function
End Class
Your code looks more like VB5/VB6 code.
This thing will not work in VB.NET, you will need delegates here.
This is not the solution, but you can try this to eliminate your current error.
Add:
Delegate Function EnumChildWindProc(ByVal hWnd As Long, _
ByVal lParam As Long) As Boolean
Change:
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
As Long, ByVal lpEnumFunc As EnumWindProc, ByVal lParam As Long) As Long
Another change:
Dim proc As New EnumWindProc(AddressOf EnumChildWindow)
Hwnd = APIGetTopWindow(APIGetDesk topWindow)
Call EnumChildWindows(Hwnd, proc, 0&)
All handles should be Int32, as the calls are of Win32 API.
This thing will not work in VB.NET, you will need delegates here.
This is not the solution, but you can try this to eliminate your current error.
Add:
Delegate Function EnumChildWindProc(ByVal hWnd As Long, _
ByVal lParam As Long) As Boolean
Change:
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent _
As Long, ByVal lpEnumFunc As EnumWindProc, ByVal lParam As Long) As Long
Another change:
Dim proc As New EnumWindProc(AddressOf EnumChildWindow)
Hwnd = APIGetTopWindow(APIGetDesk
Call EnumChildWindows(Hwnd, proc, 0&)
All handles should be Int32, as the calls are of Win32 API.
ASKER
I think it is closer, this compiles now, but when I run it nothing happens. As I step through, EnumChildWindow never runs.
Declare Function GetParent Lib "user32" (ByVal hwnd 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 SendMessageS Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Declare Function FindWindowX Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As Long, ByVal lpsz2 As Long) As Long
Public Declare Function APIGetTopWindow Lib "user32" Alias "GetTopWindow" (ByVal hwnd As Integer) As Integer
Public Declare Function APIGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Integer
Public Const WM_GETTEXT = &HD
Delegate Function EnumChildWindProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As EnumChildWindProc, ByVal lParam As Long) As Long
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Hwnd As Int32
Dim proc As New EnumChildWindProc(AddressO f EnumChildWindow)
Hwnd = APIGetTopWindow(APIGetDesk topWindow)
Call EnumChildWindows(Hwnd, proc, 0&)
End Sub
Function EnumChildWindow(ByVal hChild As Long, ByVal lParam As Long) As Boolean
Dim wClass As String, wText As String
Dim j As Integer
wClass = Space(64)
j = GetClassName(hChild, wClass, 63)
wClass = Microsoft.VisualBasic.Left (wClass, j)
wText = Space(256)
j = SendMessageS(hChild, WM_GETTEXT, 255, wText)
wText = Microsoft.VisualBasic.Left (wText, j)
EnumChildWindow = 1 ' Continue enumeration
End Function
Declare Function GetParent Lib "user32" (ByVal hwnd 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 SendMessageS Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long
Declare Function FindWindowX Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As Long, ByVal lpsz2 As Long) As Long
Public Declare Function APIGetTopWindow Lib "user32" Alias "GetTopWindow" (ByVal hwnd As Integer) As Integer
Public Declare Function APIGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Integer
Public Const WM_GETTEXT = &HD
Delegate Function EnumChildWindProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Long, ByVal lpEnumFunc As EnumChildWindProc, ByVal lParam As Long) As Long
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim Hwnd As Int32
Dim proc As New EnumChildWindProc(AddressO
Hwnd = APIGetTopWindow(APIGetDesk
Call EnumChildWindows(Hwnd, proc, 0&)
End Sub
Function EnumChildWindow(ByVal hChild As Long, ByVal lParam As Long) As Boolean
Dim wClass As String, wText As String
Dim j As Integer
wClass = Space(64)
j = GetClassName(hChild, wClass, 63)
wClass = Microsoft.VisualBasic.Left
wText = Space(256)
j = SendMessageS(hChild, WM_GETTEXT, 255, wText)
wText = Microsoft.VisualBasic.Left
EnumChildWindow = 1 ' Continue enumeration
End Function
ASKER
Just as a simple example of what I am trying to do.
Let's say I wanted to get the text from the textbox in calc.exe. And I already have found the handle for calc.exe.
From that how can I loop through all the children windows and find the textbox and return the text. And example returning all the text from any child windows would be sufficient for my purposes.
Thanks
Let's say I wanted to get the text from the textbox in calc.exe. And I already have found the handle for calc.exe.
From that how can I loop through all the children windows and find the textbox and return the text. And example returning all the text from any child windows would be sufficient for my purposes.
Thanks
I hope you found the calculator handle somehow, and then the children can be further enumerated as given in the code.
This code is not perfect, but it should work.
This code is not perfect, but it should work.
Public Class Form1
Declare Function GetParent Lib "user32" (ByVal hwnd 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 SendMessageS Lib "user32" Alias "SendMessageA" (ByVal hwnd As Int32, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As System.Text.StringBuilder) As Long
Public Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Int32
Public Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hwnd As Int32, ByVal sText As System.Text.StringBuilder, ByVal iVal As Int32) As Long
Declare Function FindWindowX Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Public Declare Function APIGetTopWindow Lib "user32" Alias "GetTopWindow" (ByVal hwnd As Integer) As Integer
Public Declare Function APIGetDesktopWindow Lib "user32" Alias "GetDesktopWindow" () As Integer
Public Const WM_GETTEXT = &HD
Delegate Function EnumChildWindProc(ByVal hWnd As Int32, ByVal lParam As Long) As Boolean
Declare Function EnumChildWindows Lib "user32" (ByVal hWndParent As Int32, ByVal lpEnumFunc As EnumChildWindProc, ByVal lParam As Long) As Long
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
Dim Hwnd As Int32
Dim proc As New EnumChildWindProc(AddressOf EnumChildWindow)
'Hwnd = APIGetTopWindow(APIGetDesktopWindow)
Hwnd = FindWindow("SciCalc", "Calculator")
Call EnumChildWindows(Hwnd, proc, 0&)
Catch ex As Exception
ex = ex
End Try
End Sub
Function EnumChildWindow(ByVal hChild As Int32, ByVal lParam As Long) As Boolean
Dim wText As New System.Text.StringBuilder(255)
Dim j As Long
j = GetWindowText(hChild, wText, 255)
j = j
If j > 0 Then MessageBox.Show(wText.ToString)
EnumChildWindow = 1 ' Continue enumeration
End Function
End Class
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
no objections
http://vbcity.com/forums/t/105842.aspx
http://www.vbforums.com/showthread.php?t=388122
http://www.developerfusion.com/article/34/enum-windows-sendmessage-api/2/