atvaxn Posted December 10, 2021 Share Posted December 10, 2021 (edited) Hey guys, I'm writing a little program, that runs in background. It's supposed to run a function when I: - hold down right mouse button for 1sec - hold down right mouse + left mouse (mouse chording) For example: hold down right mouse button for 1sec > delete current line in notepad. Now, the problem is: I can detect when the rightclick is pressed.BUT: the rightclick is already executed (in this case: note shows its contextmenu...) How can I "catch up" the original input, dismiss it/ replace it, to execute another command (in this case press "delete") #include <Misc.au3> While 1 If _IsPressed(2) Then MsgBox(64, "", "Rightclick") EndIf WEnd Edited December 13, 2021 by atvaxn Link to comment Share on other sites More sharing options...
Luke94 Posted December 10, 2021 Share Posted December 10, 2021 Have a look at this by @MrCreatoR. Link to comment Share on other sites More sharing options...
atvaxn Posted December 11, 2021 Author Share Posted December 11, 2021 (edited) hey, thanks a lot for the link. Its exactly what I'm looking for, except I still can't figure out how to combine both together. I downloaded the MouseOnEvent_2.4.zip from your link. Would be nice if you could give me a little kick expandcollapse popup#include <Misc.au3> #include <Process.au3> #include <MouseOnEvent.au3> ; catch Events ; ######################################################################################################################## _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "__MAIN", 0, 0) _MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "__MAIN", 0, 0) _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "__MAIN", 0, 0) While 1 WEnd ; __MAIN ; ######################################################################################################################## Func __MAIN() Switch _ProcessGetName(WinGetProcess(WinGetHandle("[active]"))) Case "notepad.exe" _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "__MAIN", 0, 0) _MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "__MAIN", WinGetHandle("[active]"), 1) _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "__MAIN", WinGetHandle("[active]"), 1) ; NOT WORKING ;Local $sInit = TimerInit() ;While _IsPressed(2) ;ToolTip("AA: " & TimerDiff($sInit)) ;WEnd Case Else _MouseSetOnEvent($MOUSE_PRIMARYDOWN_EVENT, "__MAIN", 0, 0) _MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "__MAIN", 0, 0) _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "__MAIN", 0, 0) ToolTip(WinGetTitle("[active]")) EndSwitch Return $MOE_BLOCKDEFPROC EndFunc And this is my original code, which basically works perfect, except the problem, that the original click is still passed to the target application: #include <Misc.au3> #include <Process.au3> While 1 If _IsPressed(2) Then Local $sInit = TimerInit() Switch _ProcessGetName(WinGetProcess(WinGetTitle("[active]"))) Case "notepad.exe" While _IsPressed(2) If _IsPressed(1) Then MsgBox(64, "CHORDINGmode", "Mouse 2 + Mouse1 clicked together") continueloop 2 EndIf WEnd If TimerDiff($sInit) < 175 Then MsgBox(64, "HOLDmode", "0-175 ms") ElseIf TimerDiff($sInit) >= 175 Then MsgBox(64, "HOLDmode", "> 175ms") EndIf EndSwitch EndIf sleep(10) WEnd Edited December 11, 2021 by atvaxn Link to comment Share on other sites More sharing options...
atvaxn Posted December 11, 2021 Author Share Posted December 11, 2021 no one? would be really nice, if someone could give me some tipps Link to comment Share on other sites More sharing options...
junkew Posted December 12, 2021 Share Posted December 12, 2021 https://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_SetWindowsHookEx.htm FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
atvaxn Posted December 13, 2021 Author Share Posted December 13, 2021 (edited) thank you so much junkew. I tried all night that WinAPI and it seem to be exactly what I'm looking for. T H A N K S !!!! I want to create mouse chordings, just like described in https://en.wikipedia.org/wiki/Mouse_chording I'm really surprised, that there seems to be no forum threads here about this very interesting topic... Now, after hours of googeling + trial & error 😄, I finally have some early results. It works so far, at least like what I expect from it. - custom command when holding right click > 200ms and >700ms - custom command when holding right click + left click (mouse chording) - custom command when holding right click + double click = sometimes it works, sometimes not.... 🤔 - the context-menu/normal rightclick is very slow... I'm still not sure about the performance (CPU-usage etc.), because the cursor got laggy sometimes when tried out different solutions. Especially, when putting a sleep() command. However, I'm still too unexperienced to detect weak spots. Would be cool if you can have a look over it and tell me some weak spots or some hints for speed improvements? thank you guys expandcollapse popup#include <WinAPI.au3> #include <WindowsConstants.au3> #include <Misc.au3> #include <Process.au3> HotKeySet('{ESC}', '_Close') ; ######################################################################################################################## Global $LEFTmbstate="up", $RIGHTmbstate="up", $sInit Global $GiTimerINIT = 0, $GiTimerCalc = 0, $GTempSleep = 0 Global $hHook Local $hFunc, $pFunc, $hMod $hFunc = DllCallbackRegister('_MouseProc', 'lresult', 'int;int;int') $pFunc = DllCallbackGetPtr($hFunc) $hMod = _WinAPI_GetModuleHandle(0) $hHook = _WinAPI_SetWindowsHookEx($WH_MOUSE_LL, $pFunc, $hMod) Global $DblClk_Speed = RegRead("HKCU\Control Panel\Mouse", "DoubleClickSpeed") If @error Then $DblClk_Speed = 500 Global $TimerDBLCLK = 0 While 1 Sleep(50) WEnd ; Permanently called when mouse changes its position ; ######################################################################################################################## Func _MouseProc($iCode, $iwParam, $ilParam) If $iCode < 0 Then Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) Switch $iwParam ; ######################################################################################## Case $WM_LBUTTONDOWN $LEFTmbstate = "down" If $GTempSleep = 1 Then Return If $RIGHTmbstate = "down" Then If __DBLCHECK() Then __ACTION(TimerDiff($sInit), "chordingRIGHT+LEFTdbclk") EndIF __ACTION(TimerDiff($sInit), "chordingRIGHT+LEFT") EndIf ; ######################################################################################## Case $WM_RBUTTONDOWN $RIGHTmbstate = "down" If $GTempSleep = 1 Then Return $GiTimerINIT = TimerInit() AdlibRegister('_Timer', 10) Return 1 ; ######################################################################################## Case $WM_RBUTTONUP $RIGHTmbstate = "up" If $GTempSleep = 1 Then Return __ACTION($GiTimerCalc, "holdingLRIGHT") EndSwitch Return _WinAPI_CallNextHookEx($hHook, $iCode, $iwParam, $ilParam) EndFunc ;==>_MouseProc Func __ACTION($iSeconds, $iMode) AdlibUnRegister('_Timer') Switch _ProcessGetName(WinGetProcess(WinGetTitle("[active]"))) ; NOTEPAD ; ######################################################################################################## Case "notepad.exe" If $iMode = "chordingRIGHT+LEFT" Then $GTempSleep = 1 __INFOshow("chording right > left: duplicate current line", $iSeconds) $GTempSleep = 0 ElseIf $iMode = "holdingLRIGHT" Then If $iSeconds < 200 Then $GTempSleep = 1 ; __INFOshow("NORMAL rightclick < 200 ms", $iSeconds) MouseClick($MOUSE_CLICK_RIGHT) $GTempSleep = 0 ElseIf $iSeconds >= 200 Then $GTempSleep = 1 __INFOshow("HOLDING rightclick > 200 ms: delete current line", $iSeconds) $GTempSleep = 0 EndIf ElseIf $iMode = "chordingRIGHT+LEFTdbclk" Then $GTempSleep = 1 __INFOshow("chordingRIGHT+LEFTdbclk: convert line to comment", $iSeconds) $GTempSleep = 0 ElseIf $iMode = "700extended" Then $GTempSleep = 1 __INFOshow("command fired up after 700 ms", $iSeconds) $GTempSleep = 0 EndIf EndSwitch EndFunc Func __INFOshow($sMSG, $iTime) ; MsgBox(64, $sMSG, $iTime) Tooltip($sMSG & @CRLF & $iTime) EndFunc Func _Close() _WinAPI_UnhookWindowsHookEx($hHook) DllCallbackFree($hHook) Exit EndFunc ;==>_Close Func __DBLCHECK() If $TimerDBLCLK = 0 Then $TimerDBLCLK = TimerInit() Return False Else If TimerDiff($TimerDBLCLK) <= $DblClk_Speed+200 Then Return True EndIf $TimerDBLCLK = TimerInit() Return False EndIf EndFunc Func _Timer() $GiTimerCalc = TimerDiff($GiTimerINIT) ; Hold longer than 700ms If $GiTimerCalc > 700 Then __ACTION($GiTimerCalc, "700extended") EndIf EndFunc Edited December 13, 2021 by atvaxn Link to comment Share on other sites More sharing options...
junkew Posted December 13, 2021 Share Posted December 13, 2021 As most solutions it depends on which user you are targetting. >98% of the user's only use what they can see. For mouse chording you have to read the manual and probably behavior would differ per application. Right mouse and (customized) contextmenu seems to work more intuitive if properly implemented. Would try your chording with this 😉 https://hard-drive.net/gaming-mouse-has-more-buttons-than-keyboard/ FAQ 31 How to click some elements, FAQ 40 Test automation with AutoIt, Multithreading CLR .NET Powershell CMDLets Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now