Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount 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
Private x As Integer
'Used a user defined type here rather than Enum so that it works on 97
Private Type winEnum
winHandle As Integer
winClass As Integer
winTitle As Integer
winHandleClass As Integer
winHandleTitle As Integer
winHandleClassTitle As Integer
End Type
Dim winOutputType As winEnum
Public Sub GetWindows()
x = 0
winOutputType.winHandle = 0
winOutputType.winClass = 1
winOutputType.winTitle = 2
winOutputType.winHandleClass = 3
winOutputType.winHandleTitle = 4
winOutputType.winHandleClassTitle = 5
GetWinInfo 0&, 0, winOutputType.winHandleClassTitle
End Sub
Private Sub GetWinInfo(hParent As Long, intOffset As Integer, OutputType As Integer)
'Sub to recursively obtain window handles, classes and text
'given a parent window to search
'Written by Mark Rowlinson
'www.markrowlinson.co.uk - The Programming Emporium
Dim hWnd As Long, lngRet As Long, y As Integer
Dim strText As String
hWnd = FindWindowEx(hParent, 0&, vbNullString, vbNullString)
While hWnd <> 0
Select Case OutputType
Case winOutputType.winClass
strText = String$(100, Chr$(0))
lngRet = GetClassName(hWnd, strText, 100)
Range("a1").Offset(x, intOffset) = Left$(strText, lngRet)
Case winOutputType.winHandle
Range("a1").Offset(x, intOffset) = hWnd
Case winOutputType.winTitle
strText = String$(100, Chr$(0))
lngRet = GetWindowText(hWnd, strText, 100)
If lngRet > 0 Then
Range("a1").Offset(x, intOffset) = Left$(strText, lngRet)
Else
Range("a1").Offset(x, intOffset) = "N/A"
End If
Case winOutputType.winHandleClass
Range("a1").Offset(x, intOffset) = hWnd
strText = String$(100, Chr$(0))
lngRet = GetClassName(hWnd, strText, 100)
Range("a1").Offset(x, intOffset + 1) = Left$(strText, lngRet)
Case winOutputType.winHandleTitle
Range("a1").Offset(x, intOffset) = hWnd
strText = String$(100, Chr$(0))
lngRet = GetWindowText(hWnd, strText, 100)
If lngRet > 0 Then
Range("a1").Offset(x, intOffset + 1) = Left$(strText, lngRet)
Else
Range("a1").Offset(x, intOffset + 1) = "N/A"
End If
Case winOutputType.winHandleClassTitle
Range("a1").Offset(x, intOffset) = hWnd
strText = String$(100, Chr$(0))
lngRet = GetClassName(hWnd, strText, 100)
Range("a1").Offset(x, intOffset + 1) = Left$(strText, lngRet)
strText = String$(100, Chr$(0))
lngRet = GetWindowText(hWnd, strText, 100)
If lngRet > 0 Then
Range("a1").Offset(x, intOffset + 2) = Left$(strText, lngRet)
Else
Range("a1").Offset(x, intOffset + 2) = "N/A"
End If
End Select
'check for children
y = x
Select Case OutputType
Case Is > 4
GetWinInfo hWnd, intOffset + 3, OutputType
Case Is > 2
GetWinInfo hWnd, intOffset + 2, OutputType
Case Else
GetWinInfo hWnd, intOffset + 1, OutputType
End Select
'increment by 1 row if no children found
If y = x Then
x = x + 1
End If
'now get next window
hWnd = FindWindowEx(hParent, hWnd, vbNullString, vbNullString)
Wend
End Sub