轻松定义双击热键(或三击、四击等)
; 来源:https://www.autohotkey.com/boards/viewtopic.php?f=6&t=95596 #Persistent #NoEnv #SingleInstance, force SetTitleMatchMode, RegEx SetBatchLines, -1 mk := new MultiHotkeys() ; Use hotkey command before definition to make context sensitive: ; Hotkey, IfWinActive, Notepad mk.Add("d" , "t200" , "d") ; send d if the below times out mk.Add("dd" , , "Test" , "Double hotkey") ; Calling functions mk.Add("ddd" , , "Test" , "Triple hotkey!") mk.Add("dddd" , , "Test" , "Quadruple hotkey!!") mk.Add("{F1}{F1}" , , "Test2") ; Calling a label; F1 > F1 mk.Add("^{F1}{F1}" , , "Test3") ; Sending a string; Ctrl+F1 > F1 mk.Add("+t" , , "T") ; Capital T if Shift+t times out mk.Add("+thisisatest" , "t1000", "Test" , "Hello," ,"World!") ; Sending 2 parameters ; Shift+t > hisisatest mk.Add("#{Capslock}{F2}{F3}", "t800" , "Test" , "Wow, this is a long hotkey!") ; Win+Caps > F2 > F3 return Test(param1:="",param2:="") { global mk str := mk.inputStr if param1 str .= "`r`n" param1 if param2 str .= "`r`n" param2 tooltip, % str SetTimer, Tooltipoff, -3000 return TooltipOff: tooltip return } Test2: msgbox, % A_ThisLabel "`r`n" mk.inputStr return ;--------------------------------------------------------------------------------------------------------------------------------------- ; ; Class_Multihotkeys.ahk v0.1 by evilmanimani ; ; ; Easily set up double, triple, or more hotkeys, and more for pseudo hotstrings, with a configurable timeout ; Can go functions with parameters, labels, or just send characters if it doesn't match a function/label ; If two input strings are similar i.e. (!aa, !aaa, !aaaa), it will trigger the shorter ones after the timeout ; , the longest will be triggered immediately. ; ; mh := new MultiHotkeys() to start ; ; The only public method is Add, see examples for details: ; ; - keys: string of letter keys, optionally starting with modifiers the modifier only needs to be held for the first key ; should support ~, but not really tested. ; - options: at the moment, only supports a timeout in milliseconds, this is the timeout period between each keypress ; of the full input string, entered as t400, t1000, etc; defaults to 400ms; the timeout applies to any configured ; input string that shares the same starting hotkey (the modifiers and first character) ; - function: either a function or label name, any other text not matching a function onr label will be sent as-is ; - params: if passing a Function, any amount of associated params are supported ; ; Class MultiHotkeys { __New(options:="") { ; not much for options here yet this.ih := InputHook(Options) this.KeyDict := {} } Add(keys, options:="", function :="", params*) { static optLookup := {"T":"timeout","t":"timeout"} for i, opt in StrSplit(options, A_Space) { if optLookup.HasKey(SubStr(opt,1,1)) { var := optLookup[SubStr(opt,1,1)] %var% := SubStr(opt,2) } } RegExMatch(keys, "O)^(?<mods>[~!^+#]{1,4})?(?<keys>.*)", keys) mods := StrReplace(keys.mods,"~",,noHide) keyStr := keys.keys If IsFunc(function) { if params func := Func(function).Bind(params*) else func := Func(function) } if IsObject(keyStr) { ; to-do: put in support for simple remaps via passing an array, i.e. mp.Add({"aa":"b","bb":"c","cc":"d"},,"Test") } else { hotkeyFunc := ObjBindMethod(this,"HotkeyHandler") pos := 1 loop { pos := RegExMatch(keyStr,"({.*?})|(\w)",key,pos) if (A_Index = 1) { pos += StrLen(key) firstKey := key hk := ( noHide ? "~" : "$") . mods . RegExReplace(key, "[{}]") HotKey, % hk, % hotkeyFunc } else { this.ih.KeyOpt(key, "+E+S") pos += StrLen(key) } } Until (!key) keyStr := StrReplace(keyStr, firstKey, , , 1) keyStr := RegExReplace(keyStr, "[{}]") for i, e in StrSplit(keys) { if (e = "{") this.ih.KeyOpt(e, "+E+S") } if !isObject(this.KeyDict[hk]) { this.KeyDict[hk] := {} this.KeyDict[hk].timeout := timeout ? Format("{:.1f}", timeout / 1000) : 0.4 } this.KeyDict[hk][keyStr] := {} this.KeyDict[hk][keyStr].function := func this.KeyDict[hk][keyStr].funcName := function if mods this.KeyDict[hk][keyStr].mods := mods } } HotkeyHandler() { Suspend, On thisHotkey := A_ThisHotkey Mods := RegExReplace(thisHotkey, "i)^[~\$]*([!^+#]{0,4}).*$", "$1") timeout := this.KeyDict[thisHotkey].timeout loop { matched := [] this.ih.Start() EndReason := this.ih.Wait(timeout) inputStr .= this.ih.EndKey for k, v in this.KeyDict[thisHotkey] { if IsObject(v) { if InStr(k, inputStr) matched.Push(k) maxLen := StrLen(k) > maxLen ? StrLen(k) : maxLen } } if ((matched.MaxIndex() = 1 && this.KeyDict[thisHotkey].HasKey(inputStr)) || !EndReason || StrLen(inputStr) >= maxLen) break } this.ih.Stop() matchConfirm := [] for i, e in matched { if this.KeyDict[thisHotkey][e].HasKey("mods") { for _, char in StrSplit(mods) { if InStr(this.KeyDict[thisHotkey][inputStr].mods,char) { matchConfirm.Push(e) continue 2 } } } else if !mods { matchConfirm.Push(e) } } if ((matched.MaxIndex() = 0 && this.KeyDict[thisHotkey].HasKey("")) || (this.KeyDict[thisHotkey].HasKey(matchConfirm.1) && (!Endreason || matchConfirm.MaxIndex() = 1))) { this.inputStr := SubStr(thisHotkey,2) . inputStr funcName := this.KeyDict[thisHotkey][inputStr].funcName if IsFunc(funcName) { this.KeyDict[thisHotkey][inputStr].function.Call() } else if IsLabel(funcName) { Gosub, % funcName } else { Send, % "{raw}" funcName } } else { this.inputStr := "" } Suspend, Off } }
声明:站内资源为整理优化好的代码上传分享与学习研究,如果是开源代码基本都会标明出处,方便大家扩展学习路径。请不要恶意搬运,破坏站长辛苦整理维护的劳动成果。本站为爱好者分享站点,所有内容不作为商业行为。如若本站上传内容侵犯了原著者的合法权益,请联系我们进行删除下架。
评论(0)