[vba] obtenir l'handle de la liste déroulante d'un combobox d'une feuille excel

0/5 (5 avis)

Vue 4 918 fois - Téléchargée 315 fois

Description

Obtenir l'handle de la liste déroulante d'un combobox posé sur une feuille excel. Un combobox est composé d'une zone de texte et d'une liste (déroulante). Placé sur une feuille excel, il n'est pas facile d'identifier le handle de la liste déroulante. J'ai utilisé Spy++ pour déterminer les class names de la liste déroulante. Après, un simple coup d'API permet d'obtenir le handle de la liste déroulante d'un combobox placé sur une feuille. C'est un module facilement réutilisable pour vos documents excel.

Source / Exemple :


'-------------------------
' Dans une feuille excel :
'
Private Sub ComboBox1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single)
    If hWndDropListCombo = 0 Then
        hWndDropListCombo = GetHandleDropListFromCombo
        ' ajoutez ici votre code pour utiliser cet handle
        ' ...
    End If
End Sub
Private Sub ComboBox1_LostFocus()
    hWndDropListCombo = 0
End Sub

'-----------------
' Dans un module :
'
Public hWndDropListCombo As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
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
Public Function GetHandleDropListFromCombo() As Long
    Dim hWndExcel As Long
    Dim hWndPopup As Long
    Dim hWndList As Long
    Const VBA_POPUP_CLASSNAME = "F3 MdcPopup 60000000"
    Const VBA_LIST_CLASSNAME = "F3 Server 60000000"
    ' retourne l'handle d'excel
    hWndExcel = FindWindow("XLMAIN", vbNullString)
    'trouve celui du popup
    hWndPopup = FindWindowEx(hWndExcel, 0&, VBA_POPUP_CLASSNAME, vbNullString)
    If hWndPopup = 0 Then
        hWndPopup = FindWindow(VBA_POPUP_CLASSNAME, vbNullString)
    End If
    'trouve celui de la liste dans le popup
    hWndList = FindWindowEx(hWndPopup, 0&, VBA_LIST_CLASSNAME, vbNullString)
    GetHandleDropListFromCombo = hWndList
End Function

Conclusion :


La fonction GetHandleDropListFromCombo doit-être appelée lorsque la liste déroulante est déjà affiché. Si elle est appelée avant son affichage, alors son handle ne sera pas trouvée. C'est pour ça qu'elle est placée dans l'évènement mouseup du combo.

Codes Sources

A voir également

Ajouter un commentaire Commentaires
mimiZanzan Messages postés 301 Date d'inscription lundi 27 février 2006 Statut Membre Dernière intervention 17 décembre 2017
14 juin 2012 à 17:15
Bonjour Philippe 734,

Quand je clique dans la combobox, j'obtiens toujours le message:

"L'handle de la liste déroulante du combobox a été capturé = 0"

Je ne sais pas pourquoi...

Cdt
Philippe734 Messages postés 308 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 15 juin 2015 1
14 juin 2012 à 09:21
La valeur du handle change en effet à chaque fois. C'est à dire qu'à chaque fois que la liste est déroulé, son handle est bien différent.
à mimizanzan : je serait curieux de savoir la raison pour laquelle le code ne fonctionne pas chez toi. Reviens nous le dire lorsque tu aura trouvé.
cs_MPi Messages postés 3877 Date d'inscription mardi 19 mars 2002 Statut Membre Dernière intervention 17 août 2018 22
4 juin 2012 à 17:00
Personnellement, sous 2007, ça me retourne bien une valeur, mais celle-ci change à chaque fois que je reclique sur le combobox.

Il me semble que le handle devrait toujours être le même durant une même session, non ?
mimiZanzan Messages postés 301 Date d'inscription lundi 27 février 2006 Statut Membre Dernière intervention 17 décembre 2017
4 juin 2012 à 15:10
Bonjour Philippe 734,

Ton code serait intéressant, mais il donne toujours comme handle la valeur 0...(avec Excel 2003, 2007, et 2010).
Donc inutilisable.

Cdt
cs_Alain Proviste Messages postés 908 Date d'inscription jeudi 26 juillet 2001 Statut Modérateur Dernière intervention 1 février 2015 2
29 mai 2012 à 19:36
pour pinailler, une petite constante ferait bien du bien. Voire un petit paramètre à ta fonction, histoire d'être rexploitable pour d'autre types de composants. que quelqu'un puisse plus facilement utiliser ton code ;)

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.