Option Explicit
Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _ (ByVal hwndParent As Long, _ ByVal hwndChildAfter As Long, _ ByVal lpszClass As String, _ ByVal lpszWindow As String) 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 SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hWnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long ' <--- Public Const WM_USER = &H400 Public Const TB_BUTTONCOUNT = (WM_USER + 24) ' Arbitrary maximum classname length ' (don't know this actual value, if there is one at all...) Public Const MAX_CLASS = 64 '_________________________________________________________ Sub main() Dim ahWnds() As Long Dim nWindows As Integer Dim i As Integer Call WindowsFromClassname(0, "ToolbarWindow32", ahWnds(), nWindows) For i = 1 To nWindows Debug.Print "&H" & Hex(ahWnds(i)) & " btns = " & _ SendMessage(ahWnds(i), TB_BUTTONCOUNT, 0, 0) Next End Sub '_________________________________________________________ ' Enumerates the child windows of the specified parent window ' and retrieves the window handles of the specified classname. ' hwndParent - parent window handle whose children are to be enumerated ' sTargetClass - classname of windows in which to retrieve handles from ' ahWnds() - variable dimension array filled with the window handles ' nWindows - the count of ahWnds() dimensions, specify 0 on first call. ' Specify 0 for hwndParent to enum the desktop's children (top level windows) ' Uses "inside-out" recursion (user-defined term :>), which enumerates the first ' child window found that has children windows (as opposed to "outside-in" ' recursion, which caches all child windows found that have child windows ' and then enumerates them at the end of the proc...) '_________________________________________________________ Private Sub WindowsFromClassname(hwndParent As Long, _ sTargetClass As String, _ ahWnds() As Long, _ nWindows As Integer) Dim hwndChild As Long Dim sCurClass As String * MAX_CLASS Dim nChars As Integer ' Get the first child window of the current parent window hwndChild = FindWindowEx(hwndParent, 0, vbNullString, vbNullString) Do While hwndChild ' If the current child window's classname is the same as ' our target classname, increment the window handle counter, ' reallocate the array, and add the handle to the array. nChars = GetClassName(hwndChild, sCurClass, MAX_CLASS) If nChars Then If (Left$(sCurClass, nChars) = sTargetClass) Then nWindows = nWindows + 1 ReDim Preserve ahWnds(nWindows) ahWnds(nWindows) = hwndChild End If End If ' Does the current child window has it's own children... If FindWindowEx(hwndChild, 0, vbNullString, vbNullString) Then ' It does, recursively call this proc again making the ' current child window the new parent. Call WindowsFromClassname(hwndChild, sTargetClass, ahWnds(), nWindows) End If ' Get the next sibling of the current child window hwndChild = FindWindowEx(hwndParent, hwndChild, vbNullString, vbNullString) Loop End Sub |