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
heu...c'est quoi ces grandes listbox ???? je ne l'ai pas livré comme ça
voila comment c'est au depart
1742413227361.png

l'erreur 1 je ne sais pas ce que c'est fait un deboage et donne moi la ligne
l'erreur 2 je pense savoir ce qui se passe

déjà remplace les 3 listbox avec ta boite a outils

ta dernière version me bloque tout avec un white screen au bout d'un moment si j'insiste sur la roulette
 
@jurassic pork,

J'ai insuffisamment corrigé l'erreur que tu as signalée.
En effet, ce n'est pas seulement au 1er clic + Scroll dans la ComboBox Main que ça plante.
C'est aussi quand on ferme le Drop Down en cliquant dans la ComboBox Main + Scroll alors que pour le code le Control reste inchangé et est la ComboBox.

J'ai donc créé une petite fonction que j'appelle au tout début lorsqu'on reçoit le Control_MouseMove et dans la loop de Scroll pour vérifier que la Drop Down Window de la ComboBox est bien présente, ce qui est facile à tester: TopIndex = -1 => pas de Drop Down Window.

Fichier -> voir plus loin
 
Dernière édition:
Lors de la correction du problème signalé par @jurassic pork, ayant protégé le cas d'un Control ComboBox Main, j'ai supprimé l'interception d'erreur sur la récupération de Set IUIAElement = CUIA.ElementFromIAccessible(IA, 0).

Mal m'en a pris car lors d'un survol rapide d'un Control, en particulier les ActiveX TextBox qui requièrent un petit traitement préalable (Activate + Curline), le curseur n'est plus sur le Control et la récupération de l'IUIAElement se plante !

Edit: En fait c'est parce que la récupération de la position du curseur est tardive par rapport aux traitements.
J'ai corrigé ça en prenant la position curseur dès la réception du 1er MouseMove et la propage dans la Scroll Loop qui intervient après de petits traitements sur les TextBox, traitement obligatoire pour les ActiveX TexBox (Activate) pour récupérer l'IUIAElement.
Il n'y a plus d'erreur de récupération de l'IUIAElement mais j'ai quand même laissé par précaution le On Error.

Fichier modifié après l'Edit.
 

Pièces jointes

Dernière édition:
Hello,
Le phénomène de double affichage est un véritable casse-tête chinois car cela dépend de la version d'Excel, de la résolution d'écran utilisée, de la mise à l'échelle utilisée et peut être même de l'O.S .
J'ai pris la dernière version de Patrick que j'ai édité sous un Excel 2016 32 bits sous windows 11 en résolution 1920x1080 et mise à l'échelle 100%
Je me suis aperçu qu'il n'y avait pas de propriété de largeur de colonné dans les ListBox et donc j'en ai mis une de "40 pt" ce qui m'a l'air d'avoir grandement amélioré le problème du double affichage . J'ai essayé ma version sous différentes versions d'excel et de mise à l'échelle et le seul
défaut que j'ai constaté c'est celui-ci :
DefautListBox.png


mais ce défaut est facile à enlever car il suffit d'enregistrer le fichier, le fermer et le rouvrir pour l'enlever.
En pièce jointe un classeur à essayer. Si vous avez un défaut autre que celui que j'ai décrit l'indiquer dans cette discussion en précisant la version d'Excel, l'O.S, la résolution d'écran et la mise à l'échelle.
Ami calmant, J.P
 

Pièces jointes

Bonjour @jurassic pork , @ChTi160,
Je crois en effet que le fait de l'enregistrer puis de le ré-ouvrir recale probablement les bidules d'affichage dont j'ignore tout.

@jurassic pork,
Dans le code du Scroll on obtient le rectangle comme tu l'as indiqué.
VB:
    Dim vChild As Variant
    Dim IA As IAccessible
    Dim CUIA As New CUIAutomation
    Dim IUIAElement  As IUIAutomationElement

    #If Win64 Then
        Dim lPt As LongLong
        Call CopyMemory(lPt, PtInitial, LenB(lPt))
        Call AccessibleObjectFromPoint(lPt, IA, vChild)
    #Else
        Call AccessibleObjectFromPoint(PtInitial.X, PtInitial.Y, IA, vChild)
    #End If
    
    'Get Control Rectangle
    Set IUIAElement = CUIA.ElementFromIAccessible(IA, 0)
    
    With IUIAElement.CurrentBoundingRectangle
On part donc d'une position curseur (AccessibleObjectFromPoint) pour obtenir le IUIAElement.CurrentBoundingRectangle.
Saurais-tu partir de l'Object indépendamment de la position curseur pour récupérer I'UIAElement ?
 
Saurais-tu partir de l'Object indépendamment de la position curseur pour récupérer I'UIAElement ?
Hello Dudu2,
ben oui en passant par un IAccessible. Exemple pour un contrôle ActiveX control :
VB:
        Dim UIAelem As IUIAutomationElement, accescontrol As IAccessible:
        Set accescontrol = control: Set UIAelem = c.ElementFromIAccessible(accescontrol, 0)

Ami calmant, J.P
 
@Dudu2 oui
tu fait juste une convertion
VB:
sub machin(control)

dim accesControl as iaccessible

Dim vChild As Variant

    Dim IA As IAccessible

    Dim CUIA As New CUIAutomation

    Dim IUIAElement  As IUIAutomationElement


set accescontrol=control'on le coverti 'on iaccessible

set  IUIAElement=CuiAElementFromIAccessible(accescontrol,0)'on converti le iaccessible en uiautoelement


end sub

edit on c'est croisé avec @jurassic pork
 
re
a savoir me semble t il qu'a partir de cet element uiauto on peut si je ne me trompe pas
récupérer le handle si control est une listbox ou frame ou multipage ou combobox
parti de là on peut comparer le handle de accesscontrol et poscontrol qui est récupérer par les point x,y
 
- 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
801
P
Retour