Page 1 sur 1
[Résolu] Hook de la roulette de souris...
Publié : sam. 30/nov./2013 18:43
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.
Re: Hook de la roulette de souris...
Publié : sam. 30/nov./2013 19:15
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)
Re: Hook de la roulette de souris...
Publié : lun. 02/déc./2013 10:48
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
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

Re: Hook de la roulette de souris...
Publié : mar. 03/déc./2013 9:59
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 ?

Re: Hook de la roulette de souris...
Publié : mar. 03/déc./2013 12:37
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)
Re: Hook de la roulette de souris...
Publié : mar. 03/déc./2013 13:19
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
Re: Hook de la roulette de souris...
Publié : mar. 03/déc./2013 16:14
par Fig
Je prend le code de Nico ... Merci à vous tous!

Re: Hook de la roulette de souris...
Publié : mar. 03/déc./2013 16:21
par Fig
Par contre, Nico, ton code ne bloque pas la roulette pour les autres applications...
(Oui, je sais je suis pénible...)
Re: Hook de la roulette de souris...
Publié : mar. 03/déc./2013 23:04
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)
Re: Hook de la roulette de souris...
Publié : mar. 03/déc./2013 23:50
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

Re: Hook de la roulette de souris...
Publié : mer. 04/déc./2013 0:05
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.
Re: Hook de la roulette de souris...
Publié : mer. 04/déc./2013 0:22
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
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

Re: Hook de la roulette de souris...
Publié : mer. 04/déc./2013 10:29
par Fig
Merci pour ces explications très intéressantes concernant la manière d'utiliser proprement les apis.
