Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

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: 11

Dudu2

XLDnaute Barbatruc
Bonsoir @Gégé-45550,
Merci pour faire ces essais, c'est toujours bien d'avoir du retour d'autres personnes.
En fait, le comportement que tu décris est parfaitement normal.
  1. La ComboBox ne se replie pas - C'est le comportement standard d'une ComboBox ActiveX. Si tu sors de sa zone déployée avec la souris, elle ne se replie pas. Pour la replier il faut cliquer.

  2. Et scroll de la feuille - C'est aussi le comportement normal. Le Scroll avec la souris dans une ComboBox ActiveX standard déployée n'a aucun effet, mais dès que tu sors la souris de cette zone, c'est la feuille qui Scroll.
En fait, le système mis en place respecte le fonctionnement normal des Controls, sauf que quand tu es dans le Control, le Scroll devient effectif alors qu'en standard il est absent.

Voici un exemple de ComboBox standard, on sort le curseur de sa zone déployée, elle ne se ferme pas, on Scroll en dehors de la zone déployée, c'est la feuille qui Scroll.

 

patricktoulon

XLDnaute Barbatruc
Bonjour @Dudu2
Ah ben j'ai pas cherché la raison je la connais je te l'ai dis il me semble
et avec ta méthode c'est irrémédiablement impossible de palier a ce problème
sauf à faire comme tu fait ajouter des contraintes erreurs ou tout simplement bloquer le scroll feuille pendant le temps que le curseur est dans le rectangle avec le scrollaréa du visiblerange de la feuille
tout ça c'est des patchs qui fonctionnent aujourd'hui mais demain un moindre changement de config et c'est reparti pour des heures de débogage

et là ou nos opinions divergent

toi tu lis "il est nécessaire de faire un callhooknext
moi je lis il est recommandé de faire un callhooknext au cas ou le hook serait perdu dans le delay
c'est pas tout a fait la même chose

mais avant de faire un callhooknext il faudrait detruire le précedent et pas attentendre qu'il soit solutionné par des multiple gestion d'erreur dans la boucle du hook suivant(lancé par par le callhooknext)

car le callhooknext crée un nouveau pointeur(address) sur la fonction et donc le précédent ne se ferme pas
tout du moins jusqu’à le traitement de l'erreur dans ces tours de looping
et c'est ça qui génère toute tes erreurs qui paraissent ne rien a voir avec ça ( qui paraissent je dis bien !!!)

en fait chez vous ça marche par ce que vous traitez l'erreur
mais chez moi en 32 c'est la méthode elle même qui génère l'erreur
entre 2 timer ben la molette elle fait son job c'est a dire scroller la feuille

c'est pourtant pas compliqué a comprendre la fonction est sensée renvoyer 1 ou 0 par convertion interne du booleen
Private Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

tu le vois à la fin As Long !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

c'est avec ça qu'il faut décider de faire un callnexthook ou pas
mais dans tout les cas ou faut activer le répétiteur (ce que tu ne fais pas )
 

patricktoulon

XLDnaute Barbatruc
hah!.. tu a compris quoi ?

ben c'est simple si je sort du rectangle on unhookmouse et c'est tout
la souris reprends alors son role ou quelle soit
et le callnexthookex doit ce faire dans la gestion d'erreur et pas automatiquement
bien sur il faut activer la récursivité
avec LowLevelMouseProc = True 'ou 1 c'est pareil
et cela au bon endroit au bon moment
 

patricktoulon

XLDnaute Barbatruc
@Dudu2 regarde je te montre
démo1
je bloque la récursivité(rappel automatique) et le callnexthookex
comme tu peux le voir ca a pour effet de scroller la feuille en meme temps (ca doit te rappeler quelque chose)



démo2
maintenant je bloque la récursivité mais laisse le callnexthook




démo3
maintenant je bloque le callnextHookex et je laisse le callback(rappel automatique)



la si vous me croyez pas je peux plus rien faire

je répète
  1. activez le callback
  2. fait un nexthook uniquement dans la gestion d'erreur
  3. pas de timer pas de gestion d'erreur n° xxx ou je ne sais quoi
  4. on error resume next et apres le exit sub on call un new hook
point final
il y a une erreur(quelle qu'elle soit) on fait un nexthook c'est tout


 

Dudu2

XLDnaute Barbatruc
Je vois pas trop le rapport entre l'erreur et le NextHook, mais bon.
J'ai volontairement retirer le OnError Resume Next de la séquence pour voir si on tombait dedans et jamais ça ne s'est produit.
En fait tu retournes True et tu n'appelles pas le NextHook.

pas de timer pas de gestion d'erreur n° xxx ou je ne sais quoi
Ça c'est parce que tu ne sais pas de quoi tu parles, mais c'est pas grave.

J'ai une licence 2013 qui traine dans mes cartons avant que je passe en 2016.
Je vais installer et tester pour y voir plus clair. On n'est jamais mieux servi que par soi-même
 

patricktoulon

XLDnaute Barbatruc
crois moi je sais très bien de quoi je parle

j'explique comment je le comprends le truc
dans ma sub on voit

LowLevelMouseProc = True 'pas de panique true ou 1 c'est pareil la fonction attend un long on est en addressof l'autoconvertion se fait tout seul

que j'appelle le callback mais en fait cette instruction indique de rester sur le mème pointeur d'address(adressof)

seule une erreur quelconque peut renvoyer vers la partie gestion d'erreur et donc faire un rappel avec callnexthookex

je vous raconte pas d'histoire vous voyez bien dans les captures qu'il n'y a pas d'erreur chez moi
vous avez seulement un tout petit soucis de delay et c'est ce qui cause tout ce toin toin
régler le de la maniere la plus simple qui soit c'est a dire dans une gestion d'erreur globale
a la limte on error got gestion erreur
mais ne faites pas un nexthook si le precedent c'est conclu par une reussite


et j'irais meme plus loin mais je ne garantie rien je ne peux pas tester
un simple doevents pourrait très bien faire l'affaire
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
et ben mon ami de 2016 32 tu passe a 365 avec 2016 64 et maintenant tu reviens a 2013 32 vba7.0
je te dis pas la clé office dans la base de registre
fait un nettoyage avant de réinstaller la désinstallation ne fait pas tout
 

Dudu2

XLDnaute Barbatruc
De mont point de vue, il n'est pas normal que le message WM_MOUSEWHEEL parvienne à la feuille.
En faisant un Call NextHook, on suit très précisément la recommandation de MS pour précisément éviter que ces messages n'aillent ailleurs que dans le Thread concerné. D'ailleurs si ça fonctionne en 2016 (32Bits et 64Bits) c'est que quelque chose a été corrigé entre temps.

Qu'à cela ne tienne, il faut bien faire avec la réalité, j'adapterai le code en fonction des résultats obtenus, quitte à coder selon la version.
 

patricktoulon

XLDnaute Barbatruc
re
que le message WM_MOUSEWHEEL parvienne à la feuille.
ce n'est pas ce que j'ai dis
on doit pas parler le même language

en gros voilà ce que ca fait chez moi ton code

1°eventmouse lance hookmouse

2° hookmouse traite le rectangle et tout i cointi et lance le sethookwindow blablablaqui lance la procedure lowlevelmouse appelée est en addressof

et c'est dans la lowlevelmouseproc que ça déraille

je roll la molette(dans un sens ou dans l'autre)

entre deux cran de molette du instore des temps d'attente( car visiblement en 64 vous avez besoins ce donc je doute)
et ca génère une erreur et donc un unhook
du coup même desuss la souris ne scrolle plus la combo mais la feuille ce quelle est sensé faire toute seule dans un fichier excel
de suite après comme tu a fait un nexthook ben la combo reprends du service avec la lolevelmouseproc dans une autre address et c'est elle qui est a nouveau scrollée

en gros un coup sur X

c'est quand même pas compliqué a comprendre

on suit très précisément la recommandation de MS pour précisément éviter que ces messages n'aillent ailleurs que dans le Thread concerné
ben il faudrait les les suivre de A à Z
commence par générer la récursivité et non un rappel suite a erreur
c'est pas moi qu'il ai inventé tout les codes que tu va trouver avec une fonction en addressof et qui est sensé se répéter doivent être récursive
toi tu rappelle la même fonction dans une autre instance si je puis m’exprimer ainsi
c'est quand même incroyable que j'arrive pas a te faire comprendre ça
 
Dernière édition:

Dudu2

XLDnaute Barbatruc
on doit pas parler le même language
J'en conviens volontiers .
ce n'est pas ce que j'ai dis
Je n'ai pas commenté ce que tu as dis, j'ai fait mon propre commentaire qui t'est passé au-dessus de la tête.
que le message WM_MOUSEWHEEL parvienne à la feuille.
Oui, le message WM_MOUSEWHEEL parvient à la feuille et c'est ce qui la fait scroller.
C'est la seule chose qui m'intéresse dans cette affaire.

c'est quand même incroyable que j'arrive pas a te faire comprendre ça
T'en tiens une sacré couche !
 

patricktoulon

XLDnaute Barbatruc
tien regarde
je me suis contenté de mettre des debug.print dans tes gestion d'erreur
je n'ai rien changé d'autre
VB:
'https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms644986(v=vs.85)
Private Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
    Dim Bool As Boolean
    Dim ErrNumber As Long
    Dim Obj As Object
    Dim TopIndex As Long
    Dim DoNotCallNextHook As Boolean
    Static LastTimer As Single
  
    'Test validité du ControlHooked
    On Error Resume Next
    Set Obj = ControlHooked
    ErrNumber = Err.Number: Debug.Print "ControlHooked est le control: erreur " & ErrNumber
    On Error GoTo 0
  
    'Le ControlHooked a disparu (UserForm fermé Alt + F4 par exemple)
    If ErrNumber <> 0 Or ControlHooked Is Nothing Then
        Call UnHookMouse
    Else
        If nCode = HC_ACTION Then
            If Int((Timer - LastTimer) * 100) >= 0 Then
                If wParam = WM_MOUSEMOVE Then
                    Debug.Print "addresse structure hookmouse:" & lParam
                    'DoNotCallNextHook = True
                  
                    'Either on WM_MOUSEMOVE or on WM_MOUSEWHEEL
                    GoSub CheckMouseIsOverTheBox
                End If
              
                If wParam = WM_MOUSEWHEEL Then
                    'DoNotCallNextHook = True
                  
                    'Either on WM_MOUSEMOVE or on WM_MOUSEWHEEL
                    'GoSub CheckMouseIsOverTheBox

                    If Not plHooking = 0 Then
                  
                        With ControlHooked
                            'Is the Window still there ?
                            TopIndex = .TopIndex
                          
                            On Error Resume Next
                            .TopIndex = 0: Debug.Print "erreur topindex"
                            ErrNumber = Err.Number
                            On Error GoTo 0
                          
                            If ErrNumber <> 0 Then
                                Call UnHookMouse
                                Exit Function
                            End If
                          
                            .TopIndex = TopIndex
                          
                            'Moves the ScrollBar depending on the mouse wheel, Info is stored in lParam
                            If GetHookStruct(lParam).mouseData > 0 Then
                                If .TopIndex < ScrollStep Then .TopIndex = 0 Else .TopIndex = .TopIndex - ScrollStep
                            Else
                                .TopIndex = .TopIndex + ScrollStep
                            End If
                        End With
                    End If
                End If
            End If
        End If
    End If

    If Not DoNotCallNextHook Then
        Debug.Print "rappel de secour"
        LowLevelMouseProc = CallNextHookEx(0&, nCode, wParam, ByVal lParam)
    End If
  
    LastTimer = Timer
    Exit Function
  
CheckMouseIsOverTheBox:
    If Not ControlHooked Is Nothing Then
        On Error Resume Next
        Bool = MouseIsOverTheBox: Debug.Print "MouseIsOverTheBox " & Bool
        ErrNumber = Err.Number:: Debug.Print "MouseIsOverTheBox " & ErrNumber
        On Error GoTo 0

        'Run time Error 57097: le résultat de l'appel à la fonction MouseMoveFunction() n'est pas significatif, on oublie !
        If ErrNumber <> 57097 Then
            If ErrNumber = 0 Then
                'The mouse is not anymore over the ControlHooked Object
                If Not Bool Then
                    Call UnHookMouse
                End If
            End If
        End If
    End If
    Return
End Function
resultat dans le debug


 
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…