Lister les fenêtres filles d'une fenêtre donnée



La fonction API EnumChildWindows permet de balayer toutes les fenêtres filles d'une fenêtre donnée :

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 cherche_fenetre Lib "user32" Alias "FindWindowA" _
      (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function get_titre Lib "user32" Alias "GetWindowTextA" _
       (ByVal hwnd As Long, ByVal lpString As String, _
       ByVal cch 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

Function classe(pointeur) As String 'classe de la fenetre
classe = String(100, Chr$(0))
GetClassName pointeur, classe, 100
classe = Left$(classe, InStr(classe, Chr$(0)) - 1)
End Function

Function titre(pointeur) As String 'titre du document
titre = String(100, Chr$(0))
get_titre pointeur, titre, 100
titre = Left$(titre, InStr(titre, Chr$(0)) - 1)
End Function

Function titre2(pointeur) As String 'texte titre fenetre
titre2 = String(100, Chr$(0))
nbcar = SendMessage_(pointeur, &HD, 100, ByVal titre2)
titre2 = Left$(titre2, InStr(titre2, Chr$(0)) - 1)
End Function


Function inscrit_child(ByVal fen As Long, ByVal lParam As Long) As Long
If classe(fen) <> "" Then
lin = Cells.Find("*", , , , , xlPrevious).Row + 1
Cells(lin, 1) = titre(fen)
Cells(lin, 2) = titre2(fen)
Cells(lin, 3) = classe(fen)
Cells(lin, 4) = fen
End If
inscrit_child = 1
End Function

Sub liste_childs()
Cells.ClearContents
Cells(1) = " "
titre_fen = "Formation Excel - Microsoft Internet Explorer"
pg = cherche_fenetre(vbNullString, titre_fen)
EnumChildWindows pg, AddressOf inscrit_child, ByVal 0&
End Sub


EnumChildWindows va passer à la fonction dont l'adresse est passée en second paramètre (inscrit_child), les handles des différentes fenêtres filles de la fenêtre dont le handle est passé en premier paramètre :
EnumChildWindows fenêtre_mère, adresse_de_la_fonction, paramètre
Tant qu'il reste des fenêtres filles et que la fonction visée (inscrit_child) lui renvoie 1, EnumChildWindows va poursuivre l'énumération.
inscrit_child se contente d'inscrire les caractéristiques des fenêtres filles dans la page Excel.

ATTENTION, la macro ci-dessus utilise AddressOf qui n'est reconnu par Excel qu'à partir d'Excel 2000.
Pour les versions antérieures, on doit fabriquer sa propre fonction "AddressOf" (tirée de http://www.ericphelps.com/) :

Private Declare Function GetCurrentVbaProject _
       Lib "vba332.dll" Alias "EbGetExecutingProj" _
       (hProject As Long) As Long
Private Declare Function GetFuncID Lib "vba332.dll" Alias "TipGetFunctionId" _
       (ByVal hProject As Long, ByVal strFunctionName As String, _
       ByRef strFunctionId As String) As Long
Private Declare Function GetAddr _
       Lib "vba332.dll" Alias "TipGetLpfnOfFunctionId" _
       (ByVal hProject As Long, ByVal strFunctionId As String, _
       ByRef lpfn As Long) As Long

Public Function AddressOf(strFuncName As String) As Long
Dim hProject As Long
Dim lngResult As Long
Dim strID As String
Dim lpfn As Long
Dim strFuncNameUnicode As String
Const NO_ERROR = 0
strFuncNameUnicode = StrConv(strFuncName, vbUnicode)
Call GetCurrentVbaProject(hProject)
If hProject <> 0 Then
lngResult = GetFuncID(hProject, strFuncNameUnicode, strID)
If lngResult = NO_ERROR Then
lngResult = GetAddr(hProject, strID, lpfn)
If lngResult = NO_ERROR Then
AddressOf = lpfn
End If
End If
End If
End Function




...Les API