【热键】次数与时长

作者:amnesiac 首发:官方论坛中文版

在热键方面,AutoHotkey 扩展了很多概念和适用范围,例如平常所说的热键一般指前一篇所说的组合键,但在 ahk 中鼠标键、滚轮或游戏操纵杆按钮都可以作为热键。换句话说,这里介绍的方法都应该根据实际需要灵活应用。(与热键相关的一个概念是加速键,常出现的图形用户界面的元素中加下划线显示并使用 Alt 触发。)

按次数(单击与多击)

以常见的双击为例,双击实际上为短时间内两次连续的单击,包含了两个必要条件:

  • 两次单击的时间间隔必须在短时间内
  • 两次单击必须是连续的

在这个示例中(来自帮助并做适当修改),使用了两个判断条件:

intInterval := 500 ; 若两次连击在这个时间间隔中,则视为双击。
~RControl::
if (A_PriorHotkey <> "~RControl" or A_TimeSincePriorHotkey > intInterval)
{
    KeyWait, RControl
    return
}
MsgBox, 您双击了右边的 Ctrl 键。
return

在第一次按下右 Ctrl 键时,会被判断为不是双击,所以什么也没做。第二次则会显示提示框。在实际建立双击热键时,经常需要考虑两点:

  • 减少对该键单击的影响
  • 减少对该键其他组合键的影响

因此,对于 Control 这种本身作为修饰键(几乎不作为单键使用)配合 ~ 修饰符比较好,如果像字母键这样的普通键应首先考虑使用 Send 模拟(在这个脚本中则需在首次单击时发送,检测为双击后撤销前一次发送并执行双击操作)。

既然双击可行,那么三击或更多呢?在实际中不常用,不过思考还是挺有趣的。下面是多次连击的实用例子,设计的很精巧:

CapsLock::
if (A_ThisHotkey <> A_PriorHotkey)
    return
intCount := (intCount = "" ? 1 : intCount + 1)
SetTimer, MultiPresses, -500
Return

; 这里根据连续按下次数判断执行的操作。
MultiPresses:
if (intCount = 1)
    MsgBox, 这是单击。
else if (intCount = 2)
    MsgBox, 这是双击。
else if (intCount = 3)
    MsgBox, 这是三次连击。

intCount := "" ; 重置记数器。
Return

注意到了吗?其中计时器的周期是负的。此外,这里直接屏蔽了系统原来的功能,参照前面双击的例子可以很容易恢复。再看帮助中一个例子(做了修改):

#c::
if (intCount > 0) ; SetTimer 已经启动,这里记录键击。
{
    intCount += 1
    return
}

intCount = 1
SetTimer, KeyWinC, 400 ; 在 400 毫秒内等待更多的键击。
return

KeyWinC:
SetTimer, KeyWinC, off
if (intCount = 1) ; 此键按下了一次。
{
    Run, m:\
}
else if (intCount = 2) ; 此键按下了两次。
{
    Run, m:\multimedia
}
else if (intCount > 2)
{
    MsgBox, 连击了三次或更多。
}
intCount = 0
return

和前一个完全一样吗?如果不去执行,可能不容易明白这两者的运行机制区别在哪里,这里给点提示:它们的计时方式不相同。比较而言,前一个较为符合我们对多击的理解,可能实用一些。

前两个例子尽管看起来长一些,实际上很好理解,但下面这个虽短却需好好思考及实践才会有点头绪:

#MaxThreadsPerHotkey 5
#Space::  ; Win+Space 热键.
#MaxThreadsPerHotkey 1
intCount := (intCount ? (intCount + 1) : 1)
Sleep, 1000
if (intCount = 1)
    MsgBox, 这是单击。
else if (intCount = 2)
    MsgBox, 这是双击。
else if (intCount = 3)
    MsgBox, 这是三次连击。

intCount := "" ; 重置记数器。
Return

看不懂也没关系,用起来效果和第一个类似(使用指令时必须注意是全局还是局部的)。

这里举这么些例子(还有其他花样),不是为了看起来多厉害,而是在实际中经常必须有所选择。很多人不理解,为什么需要 SendRaw / SendInput / SendPlay / SendEvent 那么多类似的命令呢?在应用时实际情况比较复杂,而这些情况很难在程序中自动做出最优选择,所以需要平时多使用多实践才会找到感觉:什么情况下使用哪个会更有效(这是最让初学者困惑的问题之一)。

按时长

根据按住按键的时长执行不同的操作,可能实际中比上一种用法更少见。

Esc:: ; 在按下时触发。
If StartTime
    return
StartTime := A_TickCount
return

Esc up:: ; 在弹起时触发。
TimeLength := A_TickCount - StartTime
if (TimeLength < 200)
{
    MsgBox, 您按住退出键不到 200 毫秒。
}
else if (TimeLength < 1500 and TimeLength >= 200) ; 后一条件实际是多余的,加上只是为了更清晰。
{
    MsgBox, 您按住退出键 1 秒左右。
}
StartTime := ""
return

代码中已经自行解释了,这里补充一点是触发的时间点,在写普通热键时经常需要考虑到这点(主要是修饰键和普通键的具体表现的区别)。另外,Esc:: 热键写成这样为什么不行呢?

Esc::StartTime := A_TickCount

请看下面两图,可以看出长按一个按键时我们可能认为只会发送一次按下事件,但实际上它会发送连续的按下事件,且这些事件都触发了 Esc:: 热键:

2014-07-01 105102.png

2014-07-01 105116.png

因此,编写一个脚本时如果运行结果和预期不一致,调试是找出问题很好的方法。在实际中,有时可能用 Hotkey 命令效果较好:

Esc:: ; 在按下时触发。
If StartTime
    return
StartTime := A_TickCount
Hotkey, Esc up, EscUpSub, On
return

EscUpSub:
Hotkey, Esc up, EscUpSub, Off
TimeLength := A_TickCount - StartTime
if (TimeLength < 200)
{
    MsgBox, 您按住退出键不到 200 毫秒。
}
else if (TimeLength >= 200 and TimeLength < 1500)
{
    MsgBox, 您按住退出键 1 秒左右。
}
StartTime := ""
return
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,743评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,296评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,285评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,485评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,581评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,821评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,960评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,719评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,186评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,516评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,650评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,936评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,757评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,991评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,370评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,527评论 2 349

推荐阅读更多精彩内容

  • 写在前面: 普普通通一键盘,千千万万莫轻看。此中实有大学问,能掌握者不一般。要问如何懂键盘,请君无需太心烦。我自倾...
    醉后长亭阅读 1,846评论 9 42
  • 我的小王老师已经可以穿着轮滑鞋慢慢走了! 倔强的小家伙战胜了自己,真的很棒!特别棒! 小王老师对妈妈说:“宝宝进步...
    高小花0218阅读 170评论 0 0
  • 台上新人窃窃私语,女生好似听到了她想要的答案,跟着游荡在周嘈细碎的清爽秋风,微微低头笑靥如花。 林家宇听懂了她的简...
    惟冬逝雪阅读 537评论 0 2
  • 风起黄沙漫, 云兴碧水流。 提刀征四海, 跨马踏千秋。
    皓腕拾光阅读 178评论 0 5