Include the function in your script or save it in .\Lib folder (RapidHotkey.ahk).
Many thanks to Laszo for Morse(), I have modified it to capture invalid keys.
:!: Please note, my Morse() version does not detect long key presses :!:
Syntax:
Key::RapidHotkey("keystrokes" ;Enter keystrokes here. E.g.: "^o" , times ;optional. The number of times the key must be pressed to execute. E.g.: 3 , delay ;optional. How quick the key must be pressed to execute. E.g.: 0.2 , IsLabel) ;optional. specify 1 to indicate that parameter 1 is a label. ;E.g. ~o::RapidHotkey("^o") ;open file dialog if o pressed twice ;To specify several actions , use " as separator and leave times parameter empty. If press times parameter is omitted, first action would be triggered on 2 presses. ~e::RapidHotkey("#r""#e""#f") ; #r if pressed twice, #e 3 times and so on ;You can specify also one (can be also 1) or separated value for times ~s::RapidHotkey("^s""{F12}""^+s", 5) ;so pressing 5 times = ^s, 6 times = {F12} and so on ;You can also specify separated times value $x::RapidHotkey("x""#r""#e", "1""5""3") ;use same separator for delay and islabel parameter
ChangeLog:
02.06.2010
- Added exeption for Capslock,LButton,MButton + RButton
20.05.2010
- Invalid hotkey presses are detected using Input command now.
19.09.2009
- Detects invalid hotkey presses as well now
18.09.2009
- Removed some invalid keys from GetKeyState list
17.09.2009
- Detects invalid key presses and terminates execution
24.02.2009
- Use combination of Hotkeys, e.g. ~LButton & RButton::...
14.01.2009
- Use "" instead of Chr(4). E.g. ...RapidHotkey("^a""Hello""World")
14-12-2008
- You can use 1 for times to do action on one press as well.
- changed standard delay parameter to 0.1.
Examples:
~+::RapidHotkey("Plus") ~h::RapidHotkey("{Raw}Hello World!", 3) ;Press h 3 times rapidly to send Hello World! ~o::RapidHotkey("^o", 4, 0.2) ;be careful, if you use this hotkey, above will not work properly ~Esc::RapidHotkey("exit", 4, 0.2, 1) ;Press Esc 4 times rapidly to exit this script ~LControl::RapidHotkey("!{TAB}",2) ;Press LControl rapidly twice to AltTab ~RControl::RapidHotkey("+!{TAB}",2) ;Press RControl rapidly twice to ShiftAltTab ~LShift::RapidHotkey("^{TAB}", 2) ;Switch back in internal windows ~RShift::RapidHotkey("^+{TAB}", 2) ;Switch between internal windows ~e::RapidHotkey("#e""#r",3) ;Run Windows Explorer ~^!7::RapidHotkey("{{}{}}{Left}", 2) ~a::RapidHotkey("test", 2, 0.3, 1) ;You Can also specify a Label to be launched test: MsgBox, Test Return Exit: ExitApp ~LButton & RButton::RapidHotkey("Menu1""Menu2""Menu3",1,0.3,1) Menu1: Menu2: Menu3: MsgBox % A_ThisLabel ReturnFunctions
RapidHotkey(keystroke, times="2", delay=0.2, IsLabel=0) { Pattern := Morse(delay*1000) If (StrLen(Pattern) < 2 and Chr(Asc(times)) != "1") Return If (times = "" and InStr(keystroke, """")) { Loop, Parse, keystroke,"" If (StrLen(Pattern) = A_Index+1) continue := A_Index, times := StrLen(Pattern) } Else if (RegExMatch(times, "^\d+$") and InStr(keystroke, """")) { Loop, Parse, keystroke,"" If (StrLen(Pattern) = A_Index+times-1) times := StrLen(Pattern), continue := A_Index } Else if InStr(times, """") { Loop, Parse, times,"" If (StrLen(Pattern) = A_LoopField) continue := A_Index, times := A_LoopField } Else if (times = "") continue := 1, times := 2 Else if (times = StrLen(Pattern)) continue = 1 If !continue Return Loop, Parse, keystroke,"" If (continue = A_Index) keystr := A_LoopField Loop, Parse, IsLabel,"" If (continue = A_Index) IsLabel := A_LoopField hotkey := RegExReplace(A_ThisHotkey, "[\*\~\$\#\+\!\^]") IfInString, hotkey, %A_Space% StringTrimLeft, hotkey,hotkey,% InStr(hotkey,A_Space,1,0) backspace := "{BS " times "}" keywait = Ctrl|Alt|Shift|LWin|RWin Loop, Parse, keywait, | KeyWait, %A_LoopField% If ((!IsLabel or (IsLabel and IsLabel(keystr))) and InStr(A_ThisHotkey, "~") and !RegExMatch(A_ThisHotkey , "i)\^[^\!\d]|![^\d]|#|Control|Ctrl|LCtrl|RCtrl|Shift|RShift|LShift|RWin|LWin|Alt|LAlt|RAlt|Escape|BackSpace|F\d\d?|" . "Insert|Esc|Escape|BS|Delete|Home|End|PgDn|PgUp|Up|Down|Left|Right|ScrollLock|CapsLock|NumLock|AppsKey|" . "PrintScreen|CtrlDown|Pause|Break|Help|Sleep|Browser_Back|Browser_Forward|Browser_Refresh|Browser_Stop|" . "Browser_Search|Browser_Favorites|Browser_Home|Volume_Mute|Volume_Down|Volume_Up|MButton|RButton|LButton|" . "Media_Next|Media_Prev|Media_Stop|Media_Play_Pause|Launch_Mail|Launch_Media|Launch_App1|Launch_App2")) Send % backspace If (WinExist("AHK_class #32768") and hotkey = "RButton") WinClose, AHK_class #32768 If !IsLabel Send % keystr else if IsLabel(keystr) Gosub, %keystr% Return } Morse(timeout = 400) { ;by Laszo -> http://www.autohotkey.com/forum/viewtopic.php?t=16951 (Modified to return: KeyWait %key%, T%tout%) tout := timeout/1000 key := RegExReplace(A_ThisHotKey,"[\*\~\$\#\+\!\^]") IfInString, key, %A_Space% StringTrimLeft, key, key,% InStr(key,A_Space,1,0) If Key in Shift,Win,Ctrl,Alt key1:="{L" key "}{R" key "}" Loop { t := A_TickCount KeyWait %key%, T%tout% Pattern .= A_TickCount-t > timeout If(ErrorLevel) Return Pattern If key in Capslock,LButton,RButton,MButton,ScrollLock,CapsLock,NumLock KeyWait,%key%,T%tout% D else if Asc(A_ThisHotkey)=36 KeyWait,%key%,T%tout% D else Input,pressed,T%tout% L1 V,{%key%}%key1% If (ErrorLevel="Timeout" or ErrorLevel=1) Return Pattern else if (ErrorLevel="Max") Return } }