[Résolu] Hook de la roulette de souris...

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

[Résolu] Hook de la roulette de souris...

Message par Fig »

Quelqu'un sait il faire un hook de la roulette (Wheelmouse) de la souris ?

Je souhaite intercepter cette information sans que le programme qui a le focus ne la reçoive...
J'ai vu un exemple sur le forum anglais pour une touche clavier [space] mais je ne sais pas comment l'adapter.
Dernière modification par Fig le jeu. 12/déc./2013 13:27, modifié 1 fois.
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Hook de la roulette de souris...

Message par falsam »

Le focus sur la fenêtre n'est pas nécessaire.

Code : Tout sélectionner

Procedure.w MouseWheelDelta()
  wz.w = ((EventwParam()>>16)&$FFFF)
  ProcedureReturn -(wz/100)
EndProcedure

Procedure MouseKeyHook(nCode, wParam, lParam) 
  Select wParam
    Case #WM_MOUSEWHEEL
      Debug MouseWheelDelta()
      
  EndSelect

  ProcedureReturn CallNextHookEx_(0, nCode, wParam, lParam) 
 
EndProcedure 

OpenWindow(0, 0, 0, 240, 140, "Mouse Wheel", #WS_CAPTION|#WS_SYSMENU|1) 
StickyWindow(0,1) 

hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseKeyHook(), GetModuleHandle_(0), 0) 
hhkLLKey = SetWindowsHookEx_(#WH_KEYBOARD_LL, @MouseKeyHook(), GetModuleHandle_(0), 0) 

Repeat 
 Event = WaitWindowEvent() 
Until Event = #PB_Event_CloseWindow

UnhookWindowsHookEx_(hhkLLMouse)
UnhookWindowsHookEx_(hhkLLKey)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Kwai chang caine
Messages : 6989
Inscription : sam. 23/sept./2006 18:32
Localisation : Isere

Re: Hook de la roulette de souris...

Message par Kwai chang caine »

Le focus sur la fenêtre n'est pas nécessaire.
Sur W7, ça capte bien l'evenement mais ça retourne zero si y'a pas le focus...enfin c'est juste pour l'info :wink:
Et comme dirait dupont et dupont..."Je dirais même plus" en ayant le focus ça retourne une fois zero si on ne survole pas la fenetre
En tout cas merci FALSAM 8)
ImageLe bonheur est une route...
Pas une destination

PureBasic Forum Officiel - Site PureBasic
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Hook de la roulette de souris...

Message par Fig »

Tu as raison, Falsam, ton code retourne 0 quand il n'a pas le focus... Néanmoins il retourne une valeur, ce qui montre qu'il est conscient que la roulette est actionnée.... Que faire ? :(
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Hook de la roulette de souris...

Message par nico »

Code : Tout sélectionner

Global hhkLLMouse.i

Structure MSLLHOOKSTRUCT
  pt.POINT
  DmouseData.l
  flags.l
  time.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    PB_Alignment.b[4]
  CompilerEndIf
  dwExtraInfo.i
EndStructure


Procedure MouseKeyHook(nCode.l, wParam.i, lParam.i)
  Protected *pointer.MSLLHOOKSTRUCT = lparam
  
  If ncode = #HC_ACTION
    Select wParam
      Case #WM_MOUSEWHEEL
        Debug *pointer\DmouseData >>16
        
    EndSelect
  EndIf 
  ProcedureReturn CallNextHookEx_(hhkLLMouse, nCode, wParam, lParam) 
  
EndProcedure 

OpenWindow(0, 0, 0, 240, 140, "Mouse Wheel", #WS_CAPTION|#WS_SYSMENU|1) 
StickyWindow(0,1) 

hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseKeyHook(), GetModuleHandle_(0), 0) 

Repeat 
  Event = WaitWindowEvent() 
Until Event = #PB_Event_CloseWindow

UnhookWindowsHookEx_(hhkLLMouse)
Dernière modification par nico le mar. 03/déc./2013 23:28, modifié 1 fois.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Hook de la roulette de souris...

Message par falsam »

pas mal ton code Nico :)
Fig a écrit :Tu as raison, Falsam, ton code retourne 0 quand il n'a pas le focus... Néanmoins il retourne une valeur, ce qui montre qu'il est conscient que la roulette est actionnée.... Que faire ? :(
Effectivement la roulette de la souris est bien détectée mais le delta ne se calcule plus !!!

Un autre code (MouseHook.pb) de http://www.purearea.net que j'ai modifié qui te permet de savoir si la molette est activée.

Code : Tout sélectionner

Global EventId, hhook

Procedure MouseProc(nCode, wParam, lParam)
  Protected *ms.MOUSEHOOKSTRUCT = lParam
   
  If wParam = #WM_MOUSEWHEEL
    Debug *ms\hwnd 
  EndIf
  
EndProcedure

If OpenWindow(0, 0, 0, 300, 200, "Mouse hook example", #PB_Window_SystemMenu)
  
  hhook = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseProc(), GetModuleHandle_(0), 0)
  Repeat
    EventID = WaitWindowEvent()
    
  Until EventID = #PB_Event_CloseWindow
EndIf
UnhookWindowsHookEx_(hhook)
End
Le debug renvoyant une valeur négative ou positive il est facile tout comme dans le code de nico, de calculer la valeur de déplacement.

Code : Tout sélectionner

Global EventId, hhook, Wheel

Procedure MouseProc(nCode, wParam, lParam)
  Protected *ms.MOUSEHOOKSTRUCT = lParam
  
  If wParam = #WM_MOUSEWHEEL
    If *ms\hwnd > 0
      Wheel + 1
    Else
      Wheel -1
    EndIf
    
    Debug Wheel
  Else
    
  EndIf  
EndProcedure

If OpenWindow(0, 0, 0, 300, 200, "Mouse hook example", #PB_Window_SystemMenu)
  
  hhook = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseProc(), GetModuleHandle_(0), 0)
  Repeat
    EventID = WaitWindowEvent()
    
  Until EventID = #PB_Event_CloseWindow
EndIf
UnhookWindowsHookEx_(hhook)
End
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Hook de la roulette de souris...

Message par Fig »

Je prend le code de Nico ... Merci à vous tous! Image
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Hook de la roulette de souris...

Message par Fig »

Par contre, Nico, ton code ne bloque pas la roulette pour les autres applications... :?

(Oui, je sais je suis pénible...)
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Hook de la roulette de souris...

Message par nico »

Il faut renvoyer 1 dans le hook lorsque tu ne souhaites pas que le message soit envoyé à la fenêtre de destination; ici si la fenêtre qui a le focus n'est pas notre application, le message n'est pas envoyé.

@Falsam: attention MOUSEHOOKSTRUCT est une structure à utiliser avec un hook WH_MOUSE et non WH_MOUSE_LL, de plus il est nécessaire de tester nCode tel que recommandé dans la doc MSDN.

Code : Tout sélectionner

Global hhkLLMouse.i

Structure MSLLHOOKSTRUCT
  pt.POINT
  DmouseData.l
  flags.l
  time.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    PB_Alignment.b[4]
  CompilerEndIf
  dwExtraInfo.i
EndStructure


Procedure MouseKeyHook(nCode.l, wParam.i, lParam.i)
  Protected *pointer.MSLLHOOKSTRUCT = lparam
  
  If ncode = #HC_ACTION
    Select wParam
      Case #WM_MOUSEWHEEL
        Debug *pointer\DmouseData >>16
        If GetForegroundWindow_() <> WindowID(0)
          ProcedureReturn 1
        EndIf
        
    EndSelect
  EndIf 
  ProcedureReturn CallNextHookEx_(hhkLLMouse, nCode, wParam, lParam) 
  
EndProcedure 

OpenWindow(0, 0, 0, 240, 140, "Mouse Wheel", #WS_CAPTION|#WS_SYSMENU|1) 
StickyWindow(0,1) 

hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseKeyHook(), GetModuleHandle_(0), 0) 

Repeat 
  Event = WaitWindowEvent() 
Until Event = #PB_Event_CloseWindow

UnhookWindowsHookEx_(hhkLLMouse)
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Hook de la roulette de souris...

Message par falsam »

J'avoue que je me suis aventuré avec MOUSEHOOKSTRUCT. j'ai vu cette structure dans le lien que je cite plus haut et j'ai testé pour voir sans trop approfondir le sujet. Merci pour cette précision Nico. :)

Le décalage de bits (>>) est il utile ? Que l'on teste 7864320 ou -7864320 sans le décalage ou bien 120 ou - 120 avec le décalage ne change rien pour le calcul du déplacement de la molette.

Ceci dit, je vais adopter ta procédure moi aussi :)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Hook de la roulette de souris...

Message par nico »

Ben oui, il faut faire le décalage car les 16 bits de poids faible sont réservés (donc d'aucune utilité) et cette valeur pourrait changer au fil des versions et la valeur plus ou mois 120 est la valeur attendue qui correspond à la constante #WHEEL_DELTA mais en réalité la valeur peut être un multiple ou une division de 120, ainsi j'obtiens plus ou moins 240 en tournant rapidement la molette de la souris. La valeur 120 aurait été choisie apparemment pour faciliter les calculs, on peut la diviser facilement par 2,3,4, 5 ou 6.
Avatar de l’utilisateur
falsam
Messages : 7324
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Hook de la roulette de souris...

Message par falsam »

nico a écrit :j'obtiens plus ou moins 240 en tournant rapidement la molette de la souris.
ok je comprend mieux l'utilité de ce décalage. Il faut effectivement faire tourner rapidement la molette pour obtenir cette valeur de 240 ..... trop fatiguant :mrgreen:

Je vais en tenir compte pour calculer la valeur de déplacement de la molette.

Code : Tout sélectionner

Global hhkLLMouse.i, WheelDelta.i

Structure MSLLHOOKSTRUCT
  pt.POINT
  DmouseData.l
  flags.l
  time.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    PB_Alignment.b[4]
  CompilerEndIf
  dwExtraInfo.i
EndStructure


Procedure MouseKeyHook(nCode.l, wParam.i, lParam.i)
  Protected *pointer.MSLLHOOKSTRUCT = lparam
  
  If ncode = #HC_ACTION
    Select wParam
      Case #WM_MOUSEWHEEL
        If *pointer\DmouseData >> 16 >0
          WheelDelta + 1
        Else
          WheelDelta - 1
        EndIf
        
        Debug WheelDelta
        
        If GetForegroundWindow_() <> WindowID(0)
          ProcedureReturn 1
        EndIf
        
    EndSelect
  EndIf 
  ProcedureReturn CallNextHookEx_(hhkLLMouse, nCode, wParam, lParam) 
  
EndProcedure 

OpenWindow(0, 0, 0, 240, 140, "Mouse Wheel", #WS_CAPTION|#WS_SYSMENU|1) 
StickyWindow(0,1) 

hhkLLMouse = SetWindowsHookEx_(#WH_MOUSE_LL, @MouseKeyHook(), GetModuleHandle_(0), 0) 

Repeat 
  Event = WaitWindowEvent() 
Until Event = #PB_Event_CloseWindow

UnhookWindowsHookEx_(hhkLLMouse)
Pratique pour un calcul de zoom :)
Configuration : Windows 11 Famille 64-bit - PB 6.20 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Fig
Messages : 1176
Inscription : jeu. 14/oct./2004 19:48

Re: Hook de la roulette de souris...

Message par Fig »

Merci pour ces explications très intéressantes concernant la manière d'utiliser proprement les apis. :idea:
Il y a deux méthodes pour écrire des programmes sans erreurs. Mais il n’y a que la troisième qui marche.
Version de PB : 6.00LTS - 64 bits
Répondre