This will allow you to record a multi-click context for any button or hotkey that can be hooked by AHK. The example I found was helpful but required a lot of editing of the base code to get what I was going for, as well as having some undesired side effects. Through a bunch of trial and error I've managed to break it down into a function that can be plugged in with #INCLUDE as it's own separate library function (or just copy/pasted).
There are 2 ways to use this:
1) The easy way which also allows any other context (like single-click) to be executed as well as the multi-click context. In some situations, allowing the single-click, or other contexts to execute is not an issue and thus requires less code.
Example:
Code: Select all
YourHotkey::
ClickDetect := MultiClickDetect(200,A_ThisHotkey,A_PriorHotkey,A_TimeSincePriorHotkey)
; captures multi-click event, a triple-click in this case
If (ClickDetect = 3) {
MsgBox Double Click
; do other stuff
}
; the single and dobule-click event will still fire
return
Example:
Code: Select all
YourHotkey::
SetTimer, MyTimer_01, Off ; kill timer that allows other contexts to fire (if active)
Goto, Skip_01 ; skip undesired click contexts
; here is where you capture any click context that is less than the desired context you want to specify below
; so if you want a triple-click context, you must catch single-click (ClickDetect = 1) and double click (ClickDetect = 2)
MyTimer_01: ; timer action
If (ClickDetect = 1 Or ClickDetect = 2) { ; add another OR for other contexts you want to capture/block
MsgBox % "Clicks :" . ClickDetect ; do stuff here
; optionally, you can specify what to do for single or double click separately with if/then/else
return ; quit after undesired click events done
}
Skip_01:
ClickDetect := MultiClickDetect(200,A_ThisHotkey,A_PriorHotkey,A_TimeSincePriorHotkey) ; store clicks if clicked within 200ms of each other
SetTimer, MyTimer_01, -300 ; set timer to check for undesired click contexts - a subsequent click within 200ms will reset the click timer
; here is where you specify the desired multi-click context
; this example is for a triple-click. If you do a quadruple click, the triple-click will still fire, and you'll get a remaining single-click event
If (ClickDetect = 3) { ; if multi-click (or triple-click in this case)
SetTimer, MyTimer_01, Off ; kill timer after desired multi-click is detected
MsgBox Triple Click ; do your stuff here
}
return
Code: Select all
Global MultiClickCount
MultiClickDetect(ClickDuration,ThisKey,PriorKey,TimeSince,ProgList="") {
If (ProgList = "") {
WinGet, ProgList, ProcessName, A ; ProgList = active process by default
}
If (ThisKey = PriorKey) {
Loop, Parse, ProgList, `; ; parse through ProgList "prog.exe;prog.exe;..."
{
IfWinActive, ahk_exe %A_LoopField% ; if one of the items match as the active application
{
If (TimeSince < ClickDuration) {
MultiClickCount++ ; detect click within ClickDuration milliseconds
} Else {
MultiClickCount := 1 ; reset counter if click is more than ClickDuration ms apart
}
Break ; quit the loop
}
}
return MultiClickCount ; return clicks detected
} Else {
return 1 ; return 1 for all other contexts
}
}
The only parameter you need to worry about is ClickDuration (in milliseconds). Optionally you can specify a string of process names for which this can apply to ie. "prog.exe;prog.exe;..." --- Only the active process will get the click actions. By default ProgList is set to the active application. Using a custom list in ProgList allows you to specify a global hotkey for specific programs that will execute as desired, firing the same key-combinations as a result.
If you want to specify more than one multi-click context for other hotkeys in a single script, you need to rename the labels/timers in the examples. That's why I added "_01" to them to make that a little easier to understand. Of course you may want to use different timer/label names that are more descriptive for readability.
I shared this because I've seen multiple requests that would require some sort of functionality like this and I just wanted to try and help. Of the few solutions I did find (that I can't find anymore) none of them were exactly "programmatic". I wanted to try and winnow down the amount of code needed to write such functionality specifically with a function doing most of the trick work, so that it was easier to extend hotkeys into other multi-click contexts.
Hope this helps someone!