热键(鼠标、操纵杆和键盘快捷键)

目录

入门和简单示例

热键有时也称为快捷键, 因为它们能简便地触发动作 (例如运行程序或 键盘宏). 在下面的例子中, Win+N 被设置为启动记事本. 磅的符号 [#] 表示 Windows 键, 它被称为 修饰符:

#n::
Run Notepad
return

在前面的最后一行中,return 用来结束此热键。不过, 如果热键只需要执行单行语句, 那么此行可以直接放在双冒号的右边. 换句话说,return 可以省略:

#n::Run Notepad

要在热键中使用多个修饰键, 那么需要把它们连续地列出来 (顺序无关紧要). 下面的例子中使用 ^!s 来表示 Control+Alt+S:

^!s::
Send Sincerely,{enter}John Smith  ; 此行发送键击到活动 (最前面的) 窗口.
return

在定义热键时您可以使用下列修饰符:

符号 说明
# Win (Windows 徽标键). 在 v1.0.48.01+, 对于 Windows Vista 及以上版本, 包含 Windows 键的热键 (例如 #a) 会等待 Windows 键被释放后才发送任何包含 "L" 键击的文本. 这样避免了这种热键中的 Send 锁定 PC。这种行为适用于除 SendPlay (这里不需要) 和 盲从模式 外的所有发送模式.
! Alt
^ 控件
+ Shift
& 和符号可以用来组合任意两个按键或鼠标按钮, 让它们成为自定义热键. 请参阅 后面 了解详情.
< 使用成对按键中左边的那个. 例如 <!a 相当于 !a, 只是使用左边的 Alt 键才可以触发.
> 使用成对按键中右边的那个.
<^>!

AltGr (alternate graving). 如果您键盘布局中含 AltGr 键而非右 Alt 键,那么这一系列符号一般可用于表示 AltGr。例如:

<^>!m::MsgBox You pressed AltGr+m.
<^<!m::MsgBox You pressed LeftControl+LeftAlt+m.

或者, 让 AltGr 自己成为热键, 请使用下面的热键 (不像上面出现的任何热键):

LControl & RAlt::MsgBox You pressed AltGr itself.
*

通配符: 即使附加的修饰键被按住也能激发热键. 这常与 重映射 按键或按钮组合使用. 例如:

*#c::Run Calc.exe  ; Win+C、Shift+Win+C、Ctrl+Win+C 等都会触发此热键。
*ScrollLock::Run Notepad  ; 即使在按住其他修饰键时按下 ScrollLock 也会触发此热键。
~

激发热键时,不会屏蔽(被操作系统隐藏)热键中按键原有的功能。在下面的两个例子中, 用户的鼠标按钮点击会被发送到活动窗口:

~RButton::MsgBox You clicked the right mouse button.
~RButton & C::MsgBox You pressed C while holding down the right mouse button.

注意:1) 与其他前缀符号不同,可以在某些热键的变体中使用颚化符前缀而其他的不使用;2) 代替 alt-tab 的特殊热键总是忽略颚化符前缀。

[v1.1.14+]:如果把颚化符前缀用在自定义修饰键中且此修饰键自身也作为热键,则在按下此修饰键时会触发热键而不会被延迟到按键释放的时候。例如,上文中~RButton热键在按下此按键时就会触发。对于v1.1.14之前的版本(或未使用颚化符前缀), 则会在按键释放时触发其自身的热键,不过仅在未触发RButton & C组合键的时候。

$

通常只在脚本使用 Send 命令发送包含了热键自身的按键时才需要使用此符号, 此时可以避免触发它自己. $ 前缀强制使用 键盘钩子 来实现此热键, 作为一个副作用这样避免了 Send 命令触发它自己. $ 前缀相当于在此热键定义之前的某个位置指定了 #UseHook

[v1.1.06+]: #InputLevelSendLevel 对 Send 命令是否触发热键和热字串提供了额外的控制功能.

UP

单词 UP 可以跟在热键名后面使得在释放按键时触发热键, 而不是按下时. 下面的例子把 LWin 重映射 为 LControl:

*LWin::Send {LControl Down}
*LWin Up::Send {LControl Up}

“Up”也可以用于普通热键中,例如:^!r Up::MsgBox You pressed and released Ctrl+Alt+R。它还可以用在组合键(例如 F1 & e Up::

限制:1) “Up”不能和游戏杆按钮一起使用;2) 在没有普通/按下热键副本的“Up”热键会完全接管那个按键以防被卡住。避免这种情况的一种方法是添加颚化符前缀(例如 ~LControl up::

相关提示, 类似于上面的一种技术是让热键成为前缀键. 好处是尽管热键会在按键松开时激发, 但仅在您之前按住此前缀键时没有按其他任何键的情况下才会如此. 例如:

LControl & F1::return  ; 通过把左 control 键放在 "&" 前面至少一次来让它成为前缀键.
LControl::MsgBox You released LControl without having used it to modify any other key.

(请参阅 按键列表 来了解键盘按键和鼠标/操纵杆按钮的完整列表)


多个热键可以垂直地叠放来让它们执行相同的动作. 例如:

^Numpad0::
^Numpad1::
MsgBox Pressing either Control+Numpad0 or Control+Numpad1 will display this message.
return

通过不为按键或按键组合的热键指定任何操作可以在整个系统中完全禁用它们. 下面的例子中禁用了右 Windows 键:

RWin::return

上下文相关的热键

#IfWinActive/Exist#If 指令可以用来让热键根据不同的条件执行不同的动作 (或什么都不做). 例如:

#IfWinActive, ahk_class Notepad
^a::MsgBox You pressed Ctrl-A while Notepad is active. Pressing Ctrl-A in any other window will pass the Ctrl-A keystroke to that window.
#c::MsgBox You pressed Win-C while Notepad is active.

#IfWinActive
#c::MsgBox You pressed Win-C while any window except Notepad is active.

#If MouseIsOver("ahk_class Shell_TrayWnd")
WheelUp::Send {Volume_Up}     ; 在任务栏上滚动滚轮:增加/减小音量。
WheelDown::Send {Volume_Down} ;

自定义组合键及其他特性

通过在两个按键 (不包括操纵杆按钮) 间使用 "&" 可以定义定制的组合键. 在下面的例子中, 您在按住 Numpad0 接着按下第二个按键时会触发此热键:

Numpad0 & Numpad1::MsgBox You pressed Numpad1 while holding down Numpad0.
Numpad0 & Numpad2::Run Notepad

在上面的例子中, Numpad0 成为 前缀键; 但是这也让 Numpad0 在被按下时失去了它原有的功能. 为了避免此问题, 脚本中可以配置 Numpad0 执行新的动作, 例如下列热键的其中一个:

Numpad0::WinMaximize A   ; 最大化活动/前端窗口.
Numpad0::Send {Numpad0}  ; 让 Numpad0 释放 时产生 Numpad0 键击. 请参阅下面的注释.

使用上面的其中一个自定义组合热键可以在释放Numpad0时执行指定的动作,但仅在您之前按住Numpad0时没有按其他任何按键的情况下。在v1.1.14+中,可以在其中某个热键使用颚化符前缀来避免这种行为。

Numlock, Capslock 和 Scrolllock: 这些键可以被强制设置为 "AlwaysOn" 或 "AlwaysOff". 例如:SetNumlockState AlwaysOn

覆盖资源管理器热键: 在脚本中可以为 Windows 内置的热键例如 Win-E (#e) 和 Win-R (#r) 指定一个动作来个别的替换. 请参阅 覆盖页面 了解详情.

替换 Alt-Tab: 热键可以提供 Alt-Tab 切换窗口的可选方法. 例如, 下面的两个热键可以让您用右手进行 alt-tab:

RControl & RShift::AltTab  ; 按住右 control 后接着反复下右 shift 来向前移动.
RControl & Enter::ShiftAltTab  ; 甚至不需要释放右 control, 直接按 Enter 来反向移动.

想了解更多细节, 请参阅 Alt-Tab.

鼠标滚轮热键

通过键名 WheelDown 和 WheelUp 可以支持转动滚轮来激发热键. 在 v1.0.48+ 中还支持 WheelLeft 和 WheelRight,但在早于 Windows Vista 的操作系统上没有效果。这里是一些鼠标滚轮热键的例子:

MButton & WheelDown::MsgBox You turned the mouse wheel down while holding down the middle button.
^!WheelUp::MsgBox You rotated the wheel up while holding down Control+Alt.

在 v1.0.43.03+, 内置变量 A_EventInfo 包含了滚轮转动的格数, 通常为 1. 然而在后面的情况中, A_EventInfo 可能大于或小于 1:

鼠标滚轮最有用的一些热键包括滚动窗口文本的可选方法. 例如, 使用下面的一对热键可以在您按住左 Control 键并转动滚轮时进行水平滚动而不是垂直滚动:

~LControl & WheelUp::  ; 向左滚动.
ControlGetFocus, fcontrol, A
Loop 2  ; <-- 增加这个值来加快滚动速度.
    SendMessage, 0x114, 0, 0, %fcontrol%, A  ; 0x114 是 WM_HSCROLL, 它后面的 0 是 SB_LINELEFT.
return

~LControl & WheelDown::  ; 向右滚动.
ControlGetFocus, fcontrol, A
Loop 2  ; <-- 增加这个值来加快滚动速度.
    SendMessage, 0x114, 1, 0, %fcontrol%, A  ; 0x114 是 WM_HSCROLL, 它后面的 1 是 SB_LINERIGHT.
return

最后, 由于鼠标滚轮热键只产生按下事件 (从没有弹起事件), 所以它们无法用作 弹起的按键热键.

热键技巧和备注

根据 Numlock的状态, 每个小键盘上的按键可以运行两个不同的热键子程序. 可选的, 可以让小键盘上的按键不论 Numlock 的状态如何都运行相同的子程序. 例如:

NumpadEnd::
Numpad1::
MsgBox, This hotkey is launched regardless of whether Numlock is on.
return

如果颚化符 (~) 和 前缀键 一起使用, 即使只是一次, 那么其中的前缀键总是会被发送到活动窗口. 例如, 在下面的两个热键中, 活动窗口都会接收到右键点击, 尽管只是其中一个热键使用了颚化符:

~RButton & LButton::MsgBox You pressed the left mouse button while holding down the right.
RButton & WheelUp::MsgBox You turned the mouse wheel up while holding down the right button.

Suspend 命令可以临时禁用所有的热键, 但不包括您要排除的那些. 要得到更大的选择性, 请使用 #IfWinActive/Exist.

通过使用 Hotkey 命令, 可以在脚本运行时动态创建热键. Hotkey 命令还能单独地修改, 禁用或启用脚本现有的热键.

操纵杆热键当前不支持修饰符前缀, 例如 ^ (Control) 和 # (Win). 不过, 您可以使用 GetKeyState 来模仿这种效果, 如下所示:

Joy2::
if not GetKeyState("Control")  ; 左边和右边的 Control 键都没有按下.
    return  ; 即什么都不做.
MsgBox You pressed the first joystick's second button while holding down the Control key.
return

如果热键应该在继续执行前等待其修饰键被释放, 这可能需要一些时间. 请参考下面的例子:

^!s::Send {Delete}

按下 Control-Alt-S 会让系统以为您按下了 Control-Alt-Delete (由于系统对 Ctrl-Alt-Delete 的侵略性检测). 要变通解决此问题, 请使用 KeyWait 来等待按键释放; 例如:

^!s::
KeyWait Control
KeyWait Alt
Send {Delete}
return

如果像 #z:: 这样的热键标签产生了类似“无效热键”的错误,那么您的系统键盘布局/语言可能不包含特殊字符(此时为“Z”)。尝试使用您键盘布局中您知道的其他字符.

热键标签可以作为 GosubGoto 的目标. 例如:Gosub ^!s

热键的一个常见用途是启动和停止重复的动作, 例如一系列的键击或鼠标点击. 关于这方面的例子, 请参阅 这个 FAQ 主题.

最后, 每个脚本都是 准多线程的, 这样可以在之前的热键子程序还在运行时启动新的热键. 例如, 即使在当前热键显示 MsgBox 时也能启动新热键.

Alt-Tab 热键

每个 Alt-Tab 热键必须是两个键的组合, 通常通过和符号 (&) 实现. 在下面的例子中, 按住右 Alt 键并按下 J 或 K 可以导航 alt-tab 菜单:

RAlt & j::AltTab
RAlt & k::ShiftAltTab

AltTabShiftAltTab 是两个特殊的命令, 它们仅在与热键在同一行时才能被识别. 这里是完整的列表:

AltTab: 如果 alt-tab 菜单可见, 那么在菜单中前移. 否则, 显示菜单 (仅当热键为由 "&" 连接的两个按键时; 否则, 它什么都不做).

ShiftAltTab: 与上面相同, 不过这里在菜单中后移.

AltTabAndMenu:如果 alt-tab 菜单可见,那么在菜单中前移。否则, 显示菜单.

AltTabMenuDismiss: 关闭 Alt-tab 菜单.

为了举例说明上述命令, 可以用鼠标滚轮完全代替 Alt-tab. 当下面的热键生效时, 点击鼠标中键显示菜单, 转动滚轮在菜单中导航:

MButton::AltTabMenu
WheelDown::AltTab
WheelUp::ShiftAltTab

要取消热键调用的 Alt-tab 菜单而不激活选择的窗口, 请使用类似下面这样的热键:它可能需要根据后面的这些进行调整: 1) 最初显示 alt-tab 菜单的方法; 和 2) 脚本是否安装了 键盘钩子.

LCtrl & CapsLock::AltTab
!MButton::  ; 鼠标中键. ! 前缀让它在按住 Alt 键时激发 (当 alt-tab 菜单可见时, alt 键是按住的).
IfWinExist ahk_class #32771  ; 表示 alt-tab 菜单出现在屏幕上.
    Send !{Escape}{Alt up}
return

当前, 所有特殊的 Alt-tab 动作必须像上面的例子那样直接指定到热键上 (即它们无法像命令那样使用). 它们 不受 #IfWin#If 的影响.

自定义的 alt-tab 动作还可以通过热键创建. 在下面的例子中, 按下 F1 来显示菜单并预先向前移动. 然后可以按下 F2 来激活选择的窗口 (或按下 Escape 取消):

*F1::Send {Alt down}{tab} ; 这里需要星号.
!F2::Send {Alt up}  ; 释放 Alt 键激活选择的窗口.
~*Escape::
IfWinExist ahk_class #32771
    Send {Escape}{Alt up}  ; 取消菜单而不激活选择的窗口.
return