赞
踩
是为了让少数的常用的快捷键发挥出更多的作用. 设计快捷键的思维应是增强现有的按键组合,而不是为了新功能去开发冷门的组合键.
而连续按键的检测,是为了引入上下文特征而用的. 并不是简单地,同一个组合按键固定连续按下两次就固定触发一个功能.
个人认为的快捷键设计原则:
- 键少功能多. 少量的人机接口方式,实现更多的功能.
- 连击最多2次单击,且由双手食指触发. 因为食指灵敏, 且我们习惯了鼠标的双击动作.
- 如果为双键结合,那么修饰键最好按整体功能进行分离,例如 shift 用来修饰编辑文本的. alt用来处理窗口操作的.
- 尽可能保留已经习惯的触发键,例如s为保存,f为查找. c为复制
- 不同软件的同概念性的快捷键应该保持一致. 例如 ctrl f 为一般的搜索功能,那么可以把百度激活搜索框的快捷键设置为ctrl f. 这样就不需要每次都用鼠标去单击搜索框,也不需要安装vim等插件. 因为是搜索引擎.没有必要保留原本的ctrl+F的功能.
- 可将同概念性的功能按软件的先后层次进行顺序切换,例如,在百度里面, 如果没有在输入框中,则按一次ctrl+f先激活输入框,再按一次搜索打开的标签或者直接跳转到系统的全局搜索 ,例如everything这类工具,再按一次则切换回浏览器的输入框,完全没有必要设置那么多个快捷键。
- 设计的时候先考虑新添加的功能是否与旧功能具有概念相似性。切记一上来就是一个新的快捷键。这是很多人一开始常犯的毛病。
举个具体的例子,在pycharm中,单独使用了一个ctrl +d 作为重复一行或者选中内容的快捷键. 其实完全没必要这么做. 只要在原始的复制ctrl+c加一个是否选取内容的判断就可以,当没有选择内容的时候,默认就是重复复制一行. 在选中多行,或者一行中局部内容的时候,直接重复填充反而会很乱. 还要额外去记一个快捷键.
这部分实际上当初参考了某个博客,但是找不到了,所以这边没有引用.
$1:: sendinput,+1 ;这边是自己修改的,为了弥补按一下也许等待计时器的问题 if winc_presses_1 > 0 ; SetTimer 已经启动, 所以我们记录键击. { winc_presses_1 += 1 return } winc_presses_1 = 1 SetTimer, KeyWin_1_大写, %tout% ; 在 100 毫秒内等待更多的键击. return KeyWin_1_大写: SetTimer, KeyWin_1_大写,off if winc_presses_1 = 2 { sendinput,{backSpace} sendinput,{backSpace} sendinput,+1 } winc_presses_1 = 0 return
局限性:
;http://www.autohotkey.com/board/topic/35566-rapidhotkey/ 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) { 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 } }
这边只实现了检测连续按下两次,因为不推荐检测3次以上的连发,不自然。
原理是通过判断上次热键和这次热键是否相同,且在规定的时间内.
这边用了ahk内置的三个变量
A_ThisHotkey, 当前触发的热键
A_PriorHotkey, 上次触发点热键
A_TimeSincePriorHotkey , 上次触发按键的时刻到目前的时长,单位是ms
; 函数名是中文,因为我的编辑器支持,如果你的不支持的话,改成自己的就行.
; 我们手指的灵敏度不同,避免一股脑的给所有的连发设置同样的时间参数.
; 平时常用的手指可以设置快点.
不间断触发了两次(tout)
{
return (A_ThisHotkey = A_PriorHotkey) and (A_TimeSincePriorHotkey < tout)
}
优点:
触发受实际手速的影响,无须等待最大时长.
代码通用,在任何的热键中直接调用,用作判断条件即可
不影响单次触发的速度.
使用案例
; 注释 +e:: ; 用e作为注释键,是因为在word等文本编辑器中,我们常用他做居中的快捷键,因此比较熟练. ;而且都有一种代码右移的视觉感. if 在这个程序中(ahkIDE) ; 这边是我自己判断在ahkIDE的情况下才生效 { if (不间断触发了两次(300)) { SendInput, ^q ;取消之前的注释代码 ToolTip,在300毫秒内连续按下了两次. ; 为了演示,这边就不控制这个提示自动隐藏了 SendInput,{End} ; 到代码段的末尾 SendInput,{space} `; ; 添加注释说明的符号 } else { SendInput, ^q ;只按一次的话 } } if 在这个程序中(pythonIDE) { SendInput,!f } return
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。