XL 2019 Molette Scroll sur ListBox

gg13

XLDnaute Occasionnel
Bonjour,

Je commence un nouveau projet pour lequel je devrai utiliser des ListBox et ComboBox.
Ces listes seront longues et je voudrais utiliser le scroll de la molette plutôt que les ascenseurs.

Après renseignement sur le site j’ai voulu utiliser ce post :
Mouse Wheel Hook (faire défiler le contenu d'une combobox/listbox avec la roulette)

Je galère depuis 2 jours et malgré plusieurs essais je n’arrive pas à intégrer ces différentes macros, plusieurs messages d’erreurs ….
Je ne comprends pas tout.
Si vous pouvez m’aider un peu je vous remercie d’avance.

Je joins le fichier exemple avec les listBox .

GG13
 

Pièces jointes

  • NBA1.3.xlsm
    37.6 KB · Affichages: 9

patricktoulon

XLDnaute Barbatruc
@Usine à gaz
peut etre ai je mal déclaré les api dans le #if vba7
je ne peut pas contrôler je suis en 32 bits

@Dudu2
j'ai testé tout fonctionne
sauf que le curseur en dehors du combo roule encore
si tu utilise et adapte ma fonction tu aura ce truc en plus et réduira de beaucoup le code de ton module

pour info
rangefrompoint donne l'object sous le curseur
et son typename(obj) te renvoie son type
  1. soit "Range"
  2. soit "OLEobject"
  3. si l'OLEobject.name<> obj.name= sortie du scroll(unhookmouse)
  4. soit "nothing"
et cela quelque soit le panes
donc là aussi on peut supprimer ta fonction objectpane
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
ben la fonction .[_gethwnd] visiblement en vba7 n'est plus tellement fiable (comme tu as plus ou moins dis)
reste que le getfocus
alors oui c'est ennuyant car il faut que la combo ai le focus
mais finalement pas tant que ça puisque le scroll doit pouvoir commencer quand elle a le focus puisque developpée donc le dropdownbutton est sensé avoir été cliqué
dans mon exemple
  • H1 est le handle de la combo
  • H2 le handle de la fenêtre Child (la partie developpée)de la combo
  • je vais mettre tout ca en pratique dans un exemple exclu combobox
 

Dudu2

XLDnaute Barbatruc
Ça y est, j'ai tous les RECT ListBox, ComboBox, ActiveX et UserForm. Et c'est pas facile !

Pour info je n'utilise QUE la fonction WindowFromPoint() mais il faut maniper pour les ComboBoxes et la manip n'est pas la même en ActiveX et en UserForm.

Je verrai demain comment les exploiter parce que là mes yeux se croisent et j'ai des trucs à faire sur une application.
 

Dudu2

XLDnaute Barbatruc
Ça dépend comment tu comptes capter le Handle de la ComboBox.

De mon point de vue, on n'y coupe pas de le faire sur l'évènement Click car c'est là que se créé la fenêtre de déploiement de la ComboBox. Après il faut gérer si le Clic est un ouverture ou fermeture de cette fenêtre, c'est un autre problème.

Le truc c'est qu'au moment du Clic, la fenêtre de déploiement n'est pas encore créée. Il faut laisser la main à Excel pour qu'il la créé et récupérer ensuite cette fenêtre. Ce que je fais, c'est un Application.OnTime Now sur le Clic qui laisse le temps à Excel de déployer la Combobox. La fonction du OnTime va alors récupérer la WindowFromPoint() d'une position Curseur du Clic (donc sur le DropDow Button) déplacée de la hauteur (en pixels) de la ComboBox pour que le Point en question soit placé sur la fenêtre de déploiement de la ComboBox. Intéressant non ?
Ça c'est pour le UserForm. Pour l'ActiveX je l'ai codé un peu différent mais le principe est le même et le même code pourrait s'appliquer.
 

patricktoulon

XLDnaute Barbatruc
re
non c'est pas un problème de temps chez moi
et comme je te l'ai dis le dropbutton_click a le même défaut que keypress ou keydown dans les textbox
le message envoyé n'est pas dispo (il n'est dipo que au mouse up)
alors j'utilise le mouseup et donc ca marche aussi si je clique sur le dropdownbutton sans utiliser l' events de ce bouton

ALORS :
  1. j'ai bien les deux handles (combo et sa fenêtre dépliée)
  2. qui je le rappelle change a chaque fois que l'on déroule)
  3. j'ai bien le rectangle comprenant le top de la combo le bottom de la child et left et le right
  4. et les coordonnées sont pil poil exactes
  5. et je l'ai aussi bien avec getfocus que windowfrompoint

ce qui est bizarre c'est que les coordonnée du rect au click sont complètement absurdes
plus tard après en bougeant la souris les coordonnées sont exactes
ça me rend fou depuis tout à l'heure je comprends pas pourquoi
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
Je ne suis jamais arrivé à détecter le Handle de la Combo d'un UserForm. Je ne sais pas comment faire, car à chaque fois, ça me renvoie le Handle du UserForm ou de sa partie interne je sais plus.
Je ne sais détecter que le Handle de la fenêtre déployée ce qui est en principe suffisant pour gérer le Scroll.
 

patricktoulon

XLDnaute Barbatruc
re
ben avec le dropbutton pour démarrer tu n'y arrivera jamais le message interne est envoyé au up du bouton

Je ne sais détecter que le Handle de la fenêtre déployée ce qui est en principe suffisant pour gérer le Scroll.
ben ca depend comment tu gère l’arrêt du scroll en fait
car quand tu click tu est dans la combo et le rectangle combo n'est pas le meme
de même que si tu n'utilise que le rect du child de la combo le rect s’arrête en dessous la combo
et justement au moment du click le curseur n'est pas encore dans la fenêtre enfant

moi je prend le rectangle de la child et je soustrait au rectangle.top la hauteur de la combo en pixel
comme ça mon rectangle comprend la combo et sa fenêtre enfant

bon en tout cas mon exemple fonctionne
mais je vais aller plus loin encore
je veux lui envoyer un sendmessage l'ors de la sortie du rectangle pour qu'elle se replie
je cherche comment faire ca il me faut le bon argument

demo.gif
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
ben avec le dropbutton pour démarrer tu n'y arrivera jamais le message interne est envoyé au up du bouton
C'est marrant que tu dises ça puisque précisément j'ai expliqué que j'y arrivais grâce à un OnTime.

De toutes façons, je change d'approche pour ne traiter que les MouseMove.
Mais il y a d'autres difficultés, notamment la détection de la disparition des DropDown Windows des ComboBox qu'il faut que je fasse.
 

patricktoulon

XLDnaute Barbatruc
Bonjour @Dudu2
ben avec le dropbutton pour démarrer tu n'y arrivera jamais le message interne est envoyé au up du bouton
C'est marrant que tu dises ça puisque précisément j'ai expliqué que j'y arrivais grâce à un OnTime.
c'est pas marrant ca fait deux pages que je te le dis
et je trouve que c'est un peu bricoler les events

donc
pour moi c'est bon
pas besoins de application.ontime

les ComboBox par mouseup( et donc par conséquent le dropbutton_click fonctionne)
et le mouseup en dehors du Dropbutton annule le scroll
conclusion le drop démarre uniquement sur le dropbutton sans utiliser cet event

les listBox là c'est le mousemove pas besoins qu'elle aient le focus

les Frames ben là aussi le mousemove et pas besoins quelle soient actives ou quelles aient le focus

ça fonctionne sur userform et sur feuille avec le même code

sur les feuilles j'ai résolu provisoirement l'auto ré enroulement des combobox

principe de déclenchement
getcursorpos ---> windowfrompoint (pour combobox windowfrompoint +pos.y+height combo en pixel

principe de sortie de scroll
si pos.x ou pos.y de (getcursorpos) en dehors du rectangle bye!bye!! le scroll

api utilisées
  1. rtlCopyMemory---------------Lib "kernel32"
  2. SetWindowsHookEx----------Lib "user32"
  3. CallNextHookEx--------------Lib "user32"
  4. UnhookWindowsHookEx-----Lib "user32"
  5. GetWindowRect-------------- Lib "user32"
  6. GetCursorPos------------------Lib "user32"
  7. WindowFromPoint------------Lib "user32"

et rien d'autre

démonstration sur feuille
demo.gif


démonstration sur userform
demo.gif


terminé
maintenant si tu a une methode pour réenrouler la combo a la sortie du rectangle (dans le model userform ) je suis preneur
;)
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
bon ben j'ai réussi a obtenir ce que je voulais
a savoir : le ré enroulent de la combo lors de la sortie du rectangle
alors c'est une méthode originale (façon patrick 😂 ) 😂 😂 😂

tout simplement donner le focus a un autre élément
sauf que cet autre élément peut avoir un event et etre utilisé pour autre chose


alors pour le scroll sur activX dans feuille et dans userfom
lors de la sortie du rectangle j'ajoute un control et je le supprime toute de suite
le fait d'ajouter sur feuille , et un setfocus et fait sur ce new control dans le userform avant de le supprimer

terminé c'est transparent et aucun event d'un autre control du parent n'est déclenché

l'idée du siècle 🤣
🤣🤣🤣🤣🤣🤣🤣

voilà comment je ré enroule la combo sans cliqué dans une autre cellule ou un autre controls dans le userform ou l’userform lui même
VB:
 GetCursorPos pos
    If pos.Y < rct2.Top Or pos.Y > rct2.Bottom Or pos.X < rct2.Left Or pos.X > rct2.Right Then
        If TypeName(CtrlHooked.Parent) = "Worksheet" Then
             If TypeName(CtrlHooked) = "ComboBox" Then
                Set CtL = CtrlHooked.Parent.OLEObjects.Add(ClassType:="Forms.ListBox.1", Left:=0, Top:=0, Width:=1, Height:=1): CtL.Activate
                CtrlHooked.Parent.Shapes(CtL.Name).Delete
            End If
        Else
            With CtrlHooked.Parent: Set CtL = .Controls.Add("forms.CommandButton.1", "vide"): CtL.SetFocus: .Remove ("vide"): End With
        End If
        UnHookMouse
        Exit Function
    End If
 

Statistiques des forums

Discussions
312 508
Messages
2 089 139
Membres
104 047
dernier inscrit
bravetta