Autres toutes versions tester le scrool avec la roulette sans passer par un hooking en addressof

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

patricktoulon

XLDnaute Barbatruc
Bonjour a tous
la principal raison des crash excel quand on utilise le hooking de la souris pour avoir le mouse wheel(la roulette)
c'est que le looping avec le (CallnextHook)est asynchrone avec le captage du message de la souris
donc quand une erreur se produit(on va trop vite ou autre)
le looping lui continue parfois au moins une fois même en erreur
résultat comme on déplace le block type du message en mémoire ça crash

je vous propose de tester ceci
ici on va rester dans un do/loop vba classique et le message de la souris sera récupéré par un peekmessage
si il y a une erreur (du au message de la souris non conforme) normalement on a une erreur vba classique
et donc le do/loop est interrompu
donc pas de relance avec un message de la souris erroné donc pas de crash
Vous constaterez que j'augmente l'allocation de la mémoire aussi (64 bits double (longlong ou longPtr))(+2&)

d'autant plus que la dans cette démo je met tout dans le userform
ce qui n'est pas possible avec un code de hooking bien entendu
et ça peut avoir un avantage lorsque l'on veut distribuer un interface(userform) sans devoir l'accompagner de x modules

toujours pareil pour déterminer le rectangle je me sert de ma fonction perso du calendar que j'ai modifié pour ce besoins
donc testez et si ça fonctionne je ferais une ressource au propre

merci d'avance pour votre participation

j'en connais un qui vas ouvrir grand les yeux 🤣

Patrick
 

Pièces jointes

Solution
Bonjour @jurassic pork , @Dudu2 , @Nathe
j'ai mis le controlrelease en optionnel dans la démo (fonctionne aussi dans userform)
j'en ai profité pour mettre un multipage
et dans la page 1 du multipage j'ai mi un label violet
et c'est lui qui pilote le scroll de la page
comme ca on peut mettre un fond sur chaque page vu que ce control n'a pas de propertie backcolor
bien évidemment j'ai ajouté le textbox
dans cette démo donc on a le controlrelease optionnel
et le scroll piloté par un autre control
voila comme ça on est au même niveau que la V 3.0 avec iaccessible (All control working)

patrick
J'essaie... Est-ce en faisant ce genre de manip ?

xxx.gif
 
Alors il est vrai que sur la TextBox il y a un nouveau traitement qui modifie la Curline d'une valeur qui n'est pas +1 ou -1 mais le +/- le nombre de lignes apparentes dans la TextBox au tout début et quand on change de sens de Scroll.
Ce nombre plus important (pour provoquer un décalage du curseur de la ScrollBar) peut être source de délai pour la TextBox qui mettrait plus de temps à se positionner quand on fait du "back & forth" rapide.

Sur la TextBox ActiveX, il n'y a pas de ScrollBar, donc le Curline ne varie que de +1 ou -1.
 
Dernière édition:
Attention, dans la feuille, la TextBox n'a pas de ScrollBar et dans mon code (pas dans celui de @patricktoulon qui a simplifié mon algorithme et l'a généralisé) le Scroll se fait par ligne. Si bien que tant que la ligne courante de la TextBox n'est pas aux marges (haute ou basse), le texte ne défile pas. C'est seulement le SelStart qui va se décaler d'une ligne à l'intérieur de la TextBox.

En UserForm où la ScrollBar apparaît automatiquement, le Scroll fait en sorte de décaler la ScrollBar SAUF si on clique dans la TextBox auquel cas on passe en mode ligne jusqu'à revenir en 1ère ou dernière ligne de la TextBox qui réinitialise le décalage ScrollBar.
 
Tu me diras, pourquoi avoir fait un système qui mélange le décalage ScrollBar et le décalage ligne ?
Pour des raisons ergonomiques.

Lors du décalage ScrollBar, le SelStart est toujours soit en haut (1ère ligne visible de la TextBox en Scroll Up) soit en bas (dernière ligne visible de la TextBox en Scroll Down). Donc si l'utilisateur veut positionner le SelStart sur une ligne à l'intérieur ed la TextBox avec la molette, il faut ce que j'ai appelé le mode ligne.
Alors certes, avec les flèches hautes et basses il peut y aller sans le mode ligne, mais j'ai préféré lui donner cette possibilité via le Scroll:
- s'il n'y a pas de ScrollBar
- s'il y a une ScrollBar et qu'il a cliqué sur une ligne qui n'est pas la ligne courante indiquée par le SelStart (hélas exclue parce que je n'ai aucun moyen de savoir qu'il a cliqué sauf par le changement de ligne courante).

Edit: autre question: pourquoi avoir fait un décalage ScrollBar ?
Parce qu'un commentaire me l'a demandé sur la Ressource et qu'il semble naturel de voir la ScrollBar se décaler quand on Scrolle avec la molette.
Mais d'un point de vue codage, le Scroll "naturel" est le décalage ligne (+1 ou -1 sur la Curline) qui déplace le SelStart d'une ligne et pas forcément la ScrollBar. Le décalage ScrollBar n'est pas simple à coder.
 
Dernière édition:
Bonjour @Dudu2
(pas dans celui de @patricktoulon qui a simplifié mon algorithme et l'a généralisé)
je n'ai rien fait du tout a ton code moi j'ai juste changé any/longptr et varptr a la place de byval
mon code n'a rien a voir avec le tiens
j'ai juste transférer étape par étape dans le mien pour trouver ou ton code plantait chez moi
si tu commence a prétendre que je copie sur toi on va pas être d'accords toi et moi ,ça serait plutôt le contraire
que l'on soit bien d'accord ,c'est dans les code de dudu2 que l'on retrouve du patricktoulon pas l'inverse
comment pourrais je te copier depuis 3/4 ans je n'ai jamais réussi a comprendre comment tu travaille
autant jaafar avec son code monstrueux bien plus complexe que toi je le comprends relativement facilement
autant toi je n'y arrive jamais

moi ma base est celle que l'on trouve partout depuis 15 ans et ce n'est pas TON ALGORYTHME!!!!

ne redis jamais ça

ce qui m’intéresse avant tout c'est le moteur du scroll et rien de plus qui se résume a un looping en addressOf avec la structure de la souris
et voir comment l'accélérer pour éviter les variation de rythme pendant le scroll
tout le reste a coté (rectangle,pixel,etc...) m'importe peu chacun sa méthode

alors si je me met en longptr le scroll marche mais que dans un sens il descend que je scroll haut ou bas
par contre ça crashs plus
VB:
#If VBA7 Then
    #If Win64 Then
        Private Declare PtrSafe Function WindowFromPoint Lib "user32" (ByVal Point As LongLong) As LongPtr
        Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, ByVal nCode As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
    #Else
        Private Declare PtrSafe Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As LongPtr
        Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, ByVal nCode As Long, ByVal wParam As LongPtr, lParam As LongPtr) As LongPtr
    #End If

    Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
    Private Declare PtrSafe Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
    Private Declare PtrSafe Function GetActiveWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function GetWindowRect Lib "user32" (ByVal hWnd As LongPtr, lpRect As RECT) As Long
    Private Declare PtrSafe Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As LongPtr, ByVal hmod As LongPtr, ByVal dwThreadId As Long) As LongPtr
    Private Declare PtrSafe Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As LongPtr) As Long
    Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr
    Private Declare PtrSafe Function GetWindow Lib "user32" (ByVal hWnd As LongPtr, ByVal wCmd As Long) As LongPtr
    Private Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long
    Private Declare PtrSafe Function IsWindowVisible Lib "user32" (ByVal hWnd As LongPtr) As Long
    Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
    Private Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Long
#Else
    Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
    Private Declare Function GetCursorPos Lib "user32" (lpPoint As POINTAPI) As Long
    Private Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal Y As Long) As Long
    Private Declare Function GetActiveWindow Lib "user32" () As Long
    Private Declare Function GetWindowRect Lib "user32.dll" (ByVal hWnd As Long, lpRect As RECT) As Long
    Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As Long, lpRect As RECT) As Long
    Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
    Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal nCode As Long, ByVal wParam As Long, lParam As Long) As Long
    Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
    Private Declare Function GetDesktopWindow Lib "user32" () As Long
    Private Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal wCmd As Long) As Long
    Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
    Private Declare Function IsWindowVisible Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
    Private Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Long
#End If

#If VBA7 Then
    Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hWnd As LongPtr) As LongPtr
    Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hWnd As LongPtr, ByVal hDC As LongPtr) As Long
    Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal hDC As LongPtr, ByVal nIndex As Long) As Long
#Else
    Private Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
    Private Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, ByVal hDC As Long) As Long
    Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDC As Long, ByVal nIndex As Long) As Long
#End If

Private Const LOGPIXELSX = 88 'Pixels/inch in X
Private Const LOGPIXELSY = 90 'Pixels/inch in Y

#If VBA7 Then
    Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#Else
    Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
#End If

Const SM_CXVSCROLL = 2
Const SM_CYHSCROLL = 3

Private Type RECT
    Left As Long
    Top As Long
    Right As Long
    Bottom As Long
End Type

Private Type POINTAPI
    X As Long
    Y As Long
End Type

Private Type MSLLHOOKSTRUCT
    #If Win64 Then
        Pt As LongLong
    #Else
        Pt As POINTAPI
    #End If
    mouseData As Long
    flags As Long
    time As Long
    dwExtraInfo As Long
End Type

Private Const HC_ACTION = 0
Private Const WH_MOUSE_LL = 14
Private Const WM_MOUSEWHEEL = &H20A
Private Const WM_MOUSEMOVE = &H200
Private Const GWL_HINSTANCE = (-6)
Private Const GW_HWNDNEXT = 2
Private Const GW_CHILD = 5
Private Const WM_SYSCOMMAND = &H112
Private Const SC_CLOSE = &HF060
'
'===================
'HookMouse variables
'===================
Private ControlHooked As Object
Private UserFormControlHooked As Object

#If VBA7 Then
    Private plHooking As LongPtr
#Else
    Private plHooking As Long
#End If
'
'Scroll step
Private ScrollStep As Integer
Private Const ScrollStep_UserForm_Frame_Page = 16 'Points delta for scrolling UserForm, Frame and Page

'=============
'Box variables
'=============
Private BoxRECT As RECT
Private TabInitializedTexBox() As Object
Private NbInitializedTexBox As Integer

#If Win64 Then
    ' Copies a POINTAPI into a LongLong.  For an API requiring a ByVal POINTAPI parameter,
    ' this LongLong can be passed in instead.  Example API's include WindowFromPoint,
    ' ChildWindowFromPoint, ChildWindowFromPointEx, DragDetect, and MenuItemFromPoint.
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
#End If

'===================
'HookMouse functions
'===================
Private Sub HookMouse(ByVal Control As Object)
    If Not plHooking = 0 Then
        Call UnHookMouse
    End If

    'https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa
    plHooking = SetWindowsHookEx(WH_MOUSE_LL, AddressOf LowLevelMouseProc, 0, 0)
    If Not plHooking = 0 Then
        Set ControlHooked = Control
    End If
End Sub

Private Sub UnHookMouse()
    If Not plHooking = 0 Then
        UnhookWindowsHookEx plHooking
        plHooking = 0
        Set ControlHooked = Nothing
    End If
End Sub

#If VBA7 Then
Private Function GetHookStruct(ByVal lParam As LongPtr) As MSLLHOOKSTRUCT
#Else
Private Function GetHookStruct(ByVal lParam As Long) As MSLLHOOKSTRUCT
#End If
    Dim udtlParamStuct As MSLLHOOKSTRUCT
    #If Win64 Then
        CopyMemory ByVal udtlParamStuct, ByVal lParam, LenB(udtlParamStuct)
    #Else
        CopyMemory VarPtr(udtlParamStuct), ByVal lParam, LenB(udtlParamStuct)
    #End If
    GetHookStruct = udtlParamStuct
End Function
 
Dernière édition:
non je sais pas comment tu fait avec tes static (j'ai pas très bien compris) mais l'astuce je l'ai trouvé avec chatgpt
c'est simple on entre la premiere fois on focus donc on met a zero le curline tag=1 pour descendre on descend donc +nbline
on est en bas tag=0
arrête pluto toi de te la peter
ensuite dis moi comment veux tu que ca marche partout ton truc
VB:
Private Declare PtrSafe Function CallNextHookEx Lib "user32" (ByVal hHook As LongPtr, ByVal nCode As Long, ByVal wParam As LongPtr, lParam As any) As longptr


Code:
#If VBA7 Then
    Private Function GetHookStruct(ByVal lParam As LongPtr) As MSLLHOOKSTRUCT
#Else
    Private Function GetHookStruct(ByVal lParam As Long) As MSLLHOOKSTRUCT
#End If
    Dim udtlParamStuct As MSLLHOOKSTRUCT
    CopyMemory ByVal udtlParamStuct, ByVal lParam, LenB(udtlParamStuct)
    GetHookStruct = udtlParamStuct
End Function

Code:
#If VBA7 Then
    Private Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr
#Else
    Private Function LowLevelMouseProc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
#End If
.....
.....

il y a des choses qui sont evidentes quand même
 
car en 64 bit le lowlevelmouseproc n'est pas récursif même si tu met lowlevelmouseproc=true ou 1
alors qu'avec 32 oui
donc la CallNextHookEx est essentielle pour le repeat en 64 sauf que tu passe de any a un long(ptr)
et je vois nul part la conversion
varptr c'est bien beau sauf que ça devient un numérique (nombre positif)et non l'adresse mémoire qui est un nombre aussi mais peut être negatif(monter descente) resultat varptr chez moi le scroll va que vers le bas que je monte ou descende

dis moi que j'ai tords 😉
j'ai fait volontairement la même erreur chez moi avec mon code et j'ai le même résultat un plantage comme il se doit
 
Écoute, je veux bien déclarer le bidule en LongPtr alors que tous les sites de référence le déclarent en Any pour que ça fonctionne chez toi.
Je n'ai rien contre ta modif à partir du moment où elle n'a pas d'impact chez moi, modif que seul toi tu peux détecter puisque avec Any ça fonctionne partout ailleurs.

Quant à la récursivité de la fonction LowLevel, je n'en sais rien. Ça peut être récursif ou non récursif avec un système interne de "queing", je n'en sais rien. Ça fonctionne c'est tout ce qui m'intéresse.
 
Bonjour le Fil
Pour Dudu2
Chez moi pas de problème ! w11-365-32
Merci !
Bonne Journée
Jean marie
Moi j'ai toujours le phénomène avec Excel 2021 64 bits que j'ai décrit précédemment. Cela ressemble à une saturation de quelque chose. J'ai même des bips sonores parfois. Je veux bien croire que cela vient de mon PC si personne d'autre à ce problème pourtant c'est un PC portable HP récent Ryzen 5 avec 16 Go de Ram sous Windows 11.
 
Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

P
Réponses
1
Affichages
834
P
Retour