Page 1 sur 1
[R] Intercepter et modifier clic droit
Posté : mer. 29 juil. 2009 22:10
par Iste
Salutations,
Je cherche a modifier le menu contextuel clic droit d'une apli pour y ajouter des fonctions.
Pour cela, j'ai commencé par chercher a savoir comment capturer le clic, j'ai réussi grace à
► Afficher le texte_WinAPI_SetWindowsHookEx
Code : Tout sélectionner
#include <WinAPI.au3>
Global $hFunc, $pFunc
Global $hHook, $hMod
$hFunc = DllCallbackRegister('_MouseProc', 'lresult', 'int;int;int')
$pFunc = DllCallbackGetPtr($hFunc)
$hMod = _WinAPI_GetModuleHandle(0)
$hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pFunc, $hMod)
While 1
Sleep(2000)
WEnd
Func _MouseProc($iCode, $iwParam, $ilParam)
Local $tMSLL, $iDelta
If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
ToolTip($iwParam)
Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam)
EndFunc
Maintenant je cherche a
vérifier si le curseur se trouve bien sur la bonne fenêtre, mais ce cous ci, j'ai beau avoir retourné la doc, j'ai toujours rien trouvé :/ GUIGetCursorInfo() reste muet.
Par la suite, et surement plus compliqué, je cherche a
'stopper' le clic envoyé a l'appli, histoire de pas avoir deux menus l'un dessus l'autre...
Voila, si vous avez des idées, des solutions...
Merci
Re: [..] Intercepter et modifier clic droit
Posté : mer. 29 juil. 2009 23:37
par orax
Bonsoir, il y cette UDF
MouseSetOnEvent_UDF qui devrait faire ce que vous demandez.
Code : Tout sélectionner
#include <MouseSetOnEvent_UDF.au3>
_MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "Fonction_pour_remplacer_le_clic", "", "", $handle_fenetre)
While 1
Sleep(10)
WEnd
Func Fonction_pour_remplacer_le_clic()
ConsoleWrite("*")
Return 0
EndFunc
J'ai testé ça sur le notepad et ça semble marcher. Le seul problème est que ça pose un hook global, et je trouve que ça fait un peu ramer l'ordi... Pour faire un hook sur un seul processus, il est probable qu'il faille utiliser une DLL :
http://www.autoitscript.com/forum/index ... t&p=540999.
Re: [..] Intercepter et modifier clic droit
Posté : jeu. 30 juil. 2009 00:39
par Iste
Déja, merci beaucoup pour cet UDF, il m'apporte au moins la solution pour intercepter le clic.
Mais a part ca, j'ai plusieurs problemes ;
Si la fenêtre cible n'est pas active, la fonction ne se lance pas :/ (faut clic deux fois)
Ensuite, la fonction _IsHoveredWnd() et des plus.. archaïque. Du coup elle ne permet pas d'appliquer la fonction sur une sous GUI :\
Je vais donc analyser tout ca et essayer d'en tirer le meilleur
Re: [..] Intercepter et modifier clic droit
Posté : jeu. 30 juil. 2009 08:23
par SagePourpre
Ce n'est pas exactement ce que tu veux mais si ça t'inspire...
J'ai associé le clic droit de la fenêtre de SciTE
à un "second menu contextuel" qui s'ouvre à la gauche du premier.
► Afficher le texte
Code : Tout sélectionner
#include<misc.au3>
#include <WindowsConstants.au3>
Global $gui, $flag = 1
Global $sciteblu, $sciteblu2
Opt("GuiOnEventMode", 1)
Opt("WinTitleMatchMode", 2)
While Not _IsPressed(23)
Sleep(50)
If _IsPressed(02) Then checkwin()
WEnd
Func _guicreate($w, $h)
$pos = MouseGetPos()
$gui = GUICreate("Options", $w, $h, $pos[0] - $w - 10, $pos[1], $WS_POPUP)
EndFunc ;==>_guicreate
Func wait()
GUISetState()
While WinActive($gui, "") And $flag = 1
Sleep(50)
WEnd
$t = GUIDelete($gui)
$flag = 1
EndFunc ;==>wait
Func checkwin()
Select
Case win("SciTE")
_guicreate(100, 200)
$sciteblu = GUICtrlCreateButton("BLU !!!", 10, 10, 80, 20)
GUICtrlSetOnEvent(-1, "scite")
$sciteblu2 = GUICtrlCreateButton("Blu 2.0", 10, 35, 80, 20)
GUICtrlSetOnEvent(-1, "scite")
wait()
Case Win("Bloc-notes")
; créer un menu pour le bloc-notes
; _guicreate sert à choisir la largeur et hauteur du menu à créer
; ensuite, on crée les contrôles du menu manuellement
; wait() sert à placer la boucle d'attente qui gère le menu
EndSelect
EndFunc ;==>checkwin
Func win($titre, $texte = "")
Return WinActive($titre, $texte)
EndFunc ;==>win
Func scite()
$flag = 0
Switch @GUI_CtrlId
Case $sciteblu
MsgBox(0, "BLU ? ", "BLU !!")
Case $sciteblu2
MsgBox(0, "", "Blu 2.0 !")
EndSwitch
EndFunc ;==>scite
À ce moment, le menu contextuel principal reste inchangé... Seulement, un deuxième menu apparaît automatiquement à la gauche du premier
Re: [..] Intercepter et modifier clic droit
Posté : jeu. 30 juil. 2009 11:00
par Iste
Merci beaucoup pour l'exemple ^^
Mais bon, comme tu t'en doute, c'est pas trop ce que je recherche
J'ai trouvé la fonction win() quil me faut
Code : Tout sélectionner
Func win()
Local $tPoint = DllStructCreate("int X;int Y")
DllStructSetData($tPoint, "X", MouseGetPos(0))
DllStructSetData($tPoint, "Y", MouseGetPos(1))
Return _WinAPI_WindowFromPoint($tPoint)
EndFunc
Avec le code que j'ai posté dans mon 1er message, c'est exactement ce que je cherche, me reste juste a trouver ce qui, dans l'udf donné par orax, empeche le clic de réellement s'effectuer.
Apres j'essayerai de comprendre comment mettre un hook spécifique pour déco des recouses
Encore merci de votre aide, je continue de chercher dans mon coin
Edit : Apres des teste avancés, la fonction win() ci dessus est toujours bien moins réactive que AU3Info (nombreux bug quand plusieurs fenêtres superposées)
Edit2 : je confirme
Avec l'udf d'orax,
tout fonctionne, sauf la fonction de récup du handle de la fenêtre sous le curseur. Je l'ai modifier ainsi
► Afficher le texte
Code : Tout sélectionner
#include-once
Global Const $MOUSE_MOVE_EVENT = 512
Global Const $MOUSE_PRIMARYDOWN_EVENT = 513
Global Const $MOUSE_PRIMARYUP_EVENT = 514
Global Const $MOUSE_SECONDARYDOWN_EVENT = 516
Global Const $MOUSE_SECONDARYUP_EVENT = 517
Global Const $MOUSE_WHELLDOWN_EVENT = 519
Global Const $MOUSE_WHELLUP_EVENT = 520
Global Const $MOUSE_WHELLSCROLL_EVENT = 522
Global Const $MOUSE_EXTRABUTTONDOWN_EVENT = 523
Global Const $MOUSE_EXTRABUTTONUP_EVENT = 524
Global $hKey_Proc = -1
Global $hM_Module = -1
Global $hM_Hook = -1
Global $aMouse_Events[1][1]
Func OnAutoItExit()
If IsArray($hM_Hook) And $hM_Hook[0] > 0 Then
DllCall("user32.dll", "int", "UnhookWindowsHookEx", "hwnd", $hM_Hook[0])
$hM_Hook[0] = 0
EndIf
If IsPtr($hKey_Proc) Then
DllCallbackFree($hKey_Proc)
$hKey_Proc = 0
EndIf
EndFunc
Func _MouseSetOnEvent($iEvent, $sFuncName="", $sParam1="", $sParam2="", $hTargetWnd=0, $iBlockDefProc=1)
If $sFuncName = "" Then ;Unset Event
If $aMouse_Events[0][0] < 1 Then Return 0
Local $aTmp_Mouse_Events[1][1]
For $i = 1 To $aMouse_Events[0][0]
If $aMouse_Events[$i][0] <> $iEvent Then
$aTmp_Mouse_Events[0][0] += 1
ReDim $aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]+1][6]
$aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][0] = $aMouse_Events[$i][0]
$aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][1] = $aMouse_Events[$i][1]
$aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][2] = $aMouse_Events[$i][2]
$aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][3] = $aMouse_Events[$i][3]
$aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][4] = $aMouse_Events[$i][4]
$aTmp_Mouse_Events[$aTmp_Mouse_Events[0][0]][5] = $aMouse_Events[$i][5]
EndIf
Next
$aMouse_Events = $aTmp_Mouse_Events
If $aMouse_Events[0][0] < 1 Then OnAutoItExit()
Return 1
EndIf
If $aMouse_Events[0][0] < 1 Then
$hKey_Proc = DllCallbackRegister("_Mouse_Events_Handler", "int", "int;ptr;ptr")
$hM_Module = DllCall("kernel32.dll", "hwnd", "GetModuleHandle", "ptr", 0)
$hM_Hook = DllCall("user32.dll", "hwnd", "SetWindowsHookEx", "int", $WH_MOUSE_LL, _
"ptr", DllCallbackGetPtr($hKey_Proc), "hwnd", $hM_Module[0], "dword", 0)
EndIf
$aMouse_Events[0][0] += 1
ReDim $aMouse_Events[$aMouse_Events[0][0]+1][6]
$aMouse_Events[$aMouse_Events[0][0]][0] = $iEvent
$aMouse_Events[$aMouse_Events[0][0]][1] = $sFuncName
$aMouse_Events[$aMouse_Events[0][0]][2] = $sParam1
$aMouse_Events[$aMouse_Events[0][0]][3] = $sParam2
$aMouse_Events[$aMouse_Events[0][0]][4] = $hTargetWnd
$aMouse_Events[$aMouse_Events[0][0]][5] = $iBlockDefProc
EndFunc
Func _Mouse_Events_Handler($nCode, $wParam, $lParam)
Local $iEvent = BitAND($wParam, 0xFFFF)
If $aMouse_Events[0][0] < 1 Then
OnAutoItExit()
Return 0
EndIf
For $i = 1 To $aMouse_Events[0][0]
If $aMouse_Events[$i][0] = $iEvent Then
If $aMouse_Events[$i][4] <> 0 And Not _IsHoveredWnd($aMouse_Events[$i][4]) Then Return 0 ;Allow default processing
Local $sExec = "Call($aMouse_Events[$i][1]"
For $j = 2 To 3
If $aMouse_Events[$i][$j] <> "" Then $sExec &= ", " & $aMouse_Events[$i][$j]
Next
$sExec &= ")"
$iRet = Execute($sExec)
If $aMouse_Events[$i][5] = -1 Then Return $iRet
Return $aMouse_Events[$i][5] ;Block default processing (or not :))
EndIf
Next
EndFunc
Func _IsHoveredWnd($hWnd)
Local $tPoint = DllStructCreate("int X;int Y")
DllStructSetData($tPoint, "X", MouseGetPos(0))
DllStructSetData($tPoint, "Y", MouseGetPos(1))
If $hWnd = _WinAPI_WindowFromPoint($tPoint) Then Return True
Return False
EndFunc
Il ne me faut donc maintenant, que trouver comment récup l'handle de la fenêtre sous le curseur, aussi bien que le fait AU3Info
Re: [..] Intercepter et modifier clic droit
Posté : jeu. 30 juil. 2009 12:17
par Iste
Problème résolu
Le bug venais de MouseGetPos() car j'etai en Opt("MouseCoordMode",0).
Merci pour votre aide, je vais pour le moment me contenter de ca, meme si c'est super pas propre ^^'