XL 2016 Quelle API pour savoir si une ListBox (UserForm ou ActiveX) a sa ScrollBar Verticale présente ?

Dudu2

XLDnaute Barbatruc
Bonjour les XLDNautes,

Si on peut, sans API, savoir si une ComboBox a son ascenseur affiché grâce à la différence (ComboBox.ListCount - ComboBox.ListRows) ce n'est pas possible avec les ListBoxes.
Certes on connaît son ListBox.TopIndex mais il n'existe pas de ListBox.BottomIndex.
Un approximation est possible avec la ListBox.Font.Size mais ça reste imprécis.

Reste l'API qui pourrait indiquer la présence d'une Vertical ScrollBar mais mes essais sont restés infructueux.
Merci pour toute suggestion.
 
Solution
pour ce qui est de cette discussion j'ai revue la chose pour les ListBox dans userform et feuille

Dudu2

XLDnaute Barbatruc
En fait c'est vrai qu'en 64Bits ça se déclare comme ça
VB:
Declare PtrSafe Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" (ByVal Point As LongLong) As LongPtr
Et en 32Bits comme ça:
VB:
Declare PtrSafe Function WindowFromPoint Lib "user32" Alias "WindowFromPoint" (ByVal xPoint As Long, ByVal yPoint As Long) As LongPtr
Je l'avais vu mais ce LongLong me perturbait.

Avec cette fonction de conversion:
VB:
Function PointToLongLong(point As POINTAPI) As LongLong
    Dim ll As LongLong
    Dim cbLongLong As LongPtr
    
    cbLongLong = LenB(ll)
    
    ' make sure the contents will fit
    If LenB(point) = cbLongLong Then
        CopyMemory ll, point, cbLongLong
    End If
    
    PointToLongLong = ll
End Function
 

patricktoulon

XLDnaute Barbatruc
je veux dire ça
VB:
#If VBA7 Then
    'DECLARATION VBA7
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (ByRef lpPoint As POINTAPI) As LongPtr                                                                'MAYBE Long

    #If Win64 Then
        'seulement pour le vba7 en 64
        Private Declare PtrSafe Function WindowFromPoint Lib "user32" (ByVal Point As LongLong) As LongPtr     '_
        Private Type POINTAPI: XY As LongLong: End Type
    #Else
    'seulement pour le vba7 en 32
        Private Declare PtrSafe Function WindowFromPoint Lib "user32" (ByVal xPoint As LongPtr, ByVal yPoint As LongPtr) As LongPtr
        Private Type POINTAPI: X As Long: Y As Long: End Type
#End If

#Else

    'DECLARATION VB6

#End If


Function HandleUnderCursor()
    Dim PoS As POINTAPI
    GetCursorPos PoS
    #If Win64 Then
        HandleUnderCursor = WindowFromPoint(PoS.XY) & " en mode 64"
    #Else
        HandleUnderCursor = WindowFromPoint(PoS.X, PoS.Y) & " en mode 32"
    #End If
End Function
msgbox HandleUnderCursor (dans l'event move d'un control)

alors chez moi j'arrive a avoir le child mais pas la combo

sinon ça marche pour listbox,frame,multipage

maintenant si vraiment windowfrompoint fonctionne chez toi avec ça j'ai la solution
que j'emploie d'ailleurs dans ma version 4 du fichier

je croise les doigts
 

patricktoulon

XLDnaute Barbatruc
alors ça marche
ben alors on y est je je vais essayer l'astuce de mon fichier 4
pas facile a adapter avec ce pointapi en 64
il va falloir peut etre utiliser 2!! type pointapi a moins que l'on arrive a discerner le X du Y
c'est la dessus que l'on doit travailler
enfin si tu veux ;)

de mon coté je vais voir si le pointapi64 fonction en vba7 32
si oui alors on va pouvoir chercher tout les deux sinon je vais être obligé de te faire confiances dans tes résultats
 

Dudu2

XLDnaute Barbatruc
Par contre je viens de faire une découverte intéressante.
On obtient le RECT des ComboBoxes quand elles sont déployées.
La question est maintenant de savoir quand elles sont déployées.

Il y a la "solution en or" décrite dans l'autre sujet qui consiste à suivre l'état dans le DropDownButton Event.
Car on sait qu'il ne peut y avoir qu'une seule ComboBox déployée et que tout déploiement / repli passe par cet évènement.
 

patricktoulon

XLDnaute Barbatruc
On obtient le RECT des ComboBoxes quand elles sont déployées.
La question est maintenant de savoir quand elles sont déployées.
oui dans ma version 4 c'est ça le move sur la combo me donne le rect si elle est deployée
dans ma version il me manquait juste le windowfrompoint pour la faire passer en 64

ce ce fait je sais si elle est déployée ou pas
il me reste une seule chose a trouver et ca je ne peux pas tester je n'ai pas 64
c'est de pouvoir dissocier dans pos.XY( de 64) le x et le y
 

patricktoulon

XLDnaute Barbatruc
d'accords je crois comprendre que tu utilise pointapi normal et tu converti en lonlong avec ça
VB:
Function PointToLongLong(point As POINTAPI) As LongLong
    Dim ll As LongLong
    Dim cbLongLong As LongPtr
   
    cbLongLong = LenB(ll)
   
    ' make sure the contents will fit
    If LenB(point) = cbLongLong Then
        CopyMemory ll, point, cbLongLong
    End If
   
    PointToLongLong = ll
End Function

ca veux dire aussi que tu utilise
VB:
  Private Type POINTAPI: X As Long: Y As Long: End Type
et pas celui là
VB:
   Private Type POINTAPI: XY As LongLong: End Type

est ce que j'ai bien compris ??
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
et oui moi je peux pas tester car la fonction elle meme me met
une errur " type indéfinie pour le longlong"
conclusion je suis obligé de la mettre dans un "if #win64.....#endif
je ne peux donc pas tester

et je viens de lire par hasard sur une page que les combox n'ont pas de handle
en fait la combo c'est
  1. une fenêtre 1
  2. un truc (ce que tu vois a l’écran le control)
  3. une fenêtre child(enfant de la fenêtre 1)
  4. et divers child comme les scroll et input etc....

conclusion le windowsfrompoint passant sur ""truc""
ben on a pas le handle de la fenêtre F3 MDCPopup 60xxxxxxx qui est la vraie mère de la child

on a en fait le handle du userform comme si on essayait avec les autres controls qui n'ont pas de handle
 

Dudu2

XLDnaute Barbatruc
J'ai trouvé un subterfuge pour les ComboBoxes UserForm.
Alors ça marche chez moi en 64Bits à une différence près:
- Le RECT d'une ComboBox ActiveX inclut la zone de valeur => il faudrait la retirer.
- Le RECT d'une ComboBox UserForm N'inclut PAS la zone de valeur

Fonctionnement: Si la fenêtre de ComboBox n'est pas déployée, on ne fait rien, sinon on positionne le curseur en haut à droite du RECT de la ComboBox et on affiche le message.

A essayer en 32Bits.
 

Pièces jointes

  • GetControlHandleMethods.xlsm
    70 KB · Affichages: 1

patricktoulon

XLDnaute Barbatruc
conclusion je vais essayer de comprendre mon problème avec la librairie
UiAutomationclient et Iaccessible sur mon 2013
si j'y arrive je pourrais déterminer chaque éléments
et avec cette librairie on a bien sur la propertie GetBoundRectangle qui est niplus ni moins que l'equivalent à getwindowrect pour les api
 

Dudu2

XLDnaute Barbatruc
En fait c'est encore plus simple.
Pour connaître la fenêtre d'une ComboBox ActiveX, il faut d'abord l'activer.
Inutile de faire ce que j'ai fait avant avec des comparaisons de RECT et RECT parent.

Je suppose que c'est la même chose avec la ComboBox UserForm, et là il faut probablement (à vérifier) un SetFocus "nouveau" comme dans la fonction du Post #13.
 

patricktoulon

XLDnaute Barbatruc
J'ai trouvé un subterfuge pour les ComboBoxes UserForm.
Alors ça marche chez moi en 64Bits à une différence près:
- Le RECT d'une ComboBox ActiveX inclut la zone de valeur => il faudrait la retirer.
- Le RECT d'une ComboBox UserForm N'inclut PAS la zone de valeur

Fonctionnement: Si la fenêtre de ComboBox n'est pas déployée, on ne fait rien, sinon on positionne le curseur en haut à droite du RECT de la ComboBox et on affiche le message.

A essayer en 32Bits.
ben c'est ni plus ni moins que l'astuce de mon fichier 4
en fait c'est la child qui devient maîtresse dans nos codes
 

Statistiques des forums

Discussions
314 487
Messages
2 110 121
Membres
110 677
dernier inscrit
volare