# 如何编写热键

热键是一个可以触发某个动作的键或组合键. 例如, `Win`+`E` 通常会启动文件资源管理器, 而 `F1` 通常会激活一个特定应用程序的帮助功能. AutoHotkey 有能力定义热键, 这些热键可以在任何地方使用, 或 只在特定的应用程序中使用, 执行任何你能用代码表达的动作.

定义热键最常见的方法是写下 热键的名称, 后面加上双冒号, 然后是动作:

    #n::Run "notepad"

这个例子定义了一个热键, 每当你按下 `Win`+`N` 时运行记事本. 要了解如何试用, 请参阅如何运行示例代码.

有关运行程序的更多信息, 请参阅如何运行程序.

如果需要多行, 请使用大括号标记热键动作的开始和结束. 这就是所谓的块.

    #n::
    {
        if WinExist("ahk_class Notepad")
            WinActivate  ; Activate the window found above
        else
            Run "notepad"  ; Open a new Notepad window
    }

开大括号也可以写在热键的同一行, 在 `::` 之后.

双冒号热键后面的块隐式的是函数的主体, 但这只有在定义自己的变量时才重要. 现在, 只需知道块是用来将多行组合成一个动作或 语句 (有关详情, 请参阅控制流).

## 基本的快捷键

对于大多数热键, the 热键名称 由紧跟着单个字母或符号, 或键名的可选修饰符组成. 试着对上面的例子做以下修改:

- 去掉 `#`, 每当你单独按下 `N` 时, 热键激活. 请记住, 如果出现错误, 您可以随时退出脚本.
- 使用 `^` 代表 Ctrl, `!` 代表 Alt 或 `+` 代表 Shift 替换 `#`, 或者尝试各种组合.
- 使用 `<^` 替换 `#` 使其只在按下 左 Ctrl 键时激活, 或者 `>^` 代表右 Ctrl 键, 或 同时 使用两个键.
- 将 `n` 替换为任何其他字母或符号(除了 `:`).
- 将 `n` 替换为按键列表中的任意名称.

注意:`::` 前面的最后一个字符永远不会被解释为修饰符.

使用这种形式的热键, 只有组合中的最后一个键可以按字面意思写成单个字符或将其名称完整地拼写出来. 例如:

- `#::` 将创建一个由哈希键(井号键 #)激活的热键, 或与该符号相关的任何组合(在美国布局中, 它是 `Shift`+`3`).
- `##::` 会创建一个类似上面的热键, 但只有当你同时按住 Windows 键时才会激活.
- `LWin::` 将创建一个热键, 通过按住左边的 Windows 键而不使用任何其他修饰键来激活.

最常见的修饰符是 Ctrl(`^`), Alt(`!`), Shift(`+`) 和 Win(`#`).

符号 `<` 和 `>` 可以作为上述四个修饰符中任何一个的前缀, 以指定该键的左侧或右侧变体. 修饰符组合 `<^>!` 对应于 AltGr 键(如果你的键盘布局中存在), 因为操作系统将其作为 LCtrl 和 Alt 的组合来实现.

其他的修饰符是:

- `*`(通配符) 允许热键激活, 即使你按住的修饰键不在热键符号中.
- `~`(非抑制) 防止热键阻塞该键的原生功能.
- `$`(使用钩子) 防止在发送按键时出现无意义的循环, 并且在某些情况下使热键更可靠.

要使热键只在释放键时触发, 而不是在按下键时触发, 请使用 UP 后缀.

相关: 热键修饰符, 按键列表

## 上下文敏感的热键

#HotIf 指令可以用来指定激活热键必须满足的条件, 如:

- 当您按下热键时, 某个特定应用程序的窗口处于活动状态.
- 如果按下热键时, CapsLock 是打开的.
- 可以用代码检测的任何其他条件.

例如:

    #HotIf WinActive("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."

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

您可以通过编写一个表达式来定义条件, 每当您按下热键时, 该表达式都会被求值. 如果表达式的计算结果为 true, 则执行热键的操作.

通过为热键的每次出现或每个 热键变体 指定不同的条件, 同一热键可以使用多次. 当您按下热键时, 程序将执行满足条件的第一个热键变体, 或没有条件的热键变体(例如上面示例中的最终的 `#c::`).

如果不满足热键的条件, 并且热键没有无条件的变体, 则按键将传递到活动窗口, 就好像一开始就没有定义热键一样. 例如, 如果在运行上述示例时, Notepad 未处于 活动状态, 则 `Ctrl`+`A` 将执行其正常功能(可能是全选).

尝试对示例进行以下更改:

- 将 `WinActive` 替换为 `WinExist`, 以便在记事本正在运行时激活热键, 即使记事本没有焦点也是如此.
- 将条件替换为 `GetKeyState("CapsLock", "T")` 以便热键仅在 CapsLock 打开时激活.
- 为其他窗口添加另一个 ^a 或 #c 热键, 例如您的 Web 浏览器或编辑器. 请注意, 我们使用 ahk_class 以便该示例适用于非英语系统, 但如果您需要, 您可以将其删除并使用窗口的标题.

正确识别您希望热键影响的窗口有时需要使用窗口标题以外的条件. 有关详情, 请参阅如何管理窗口.

相关: #HotIf, 表达式, WinActive

## 自定义组合

自定义组合 是一个热键, 它将两个通常不用于组合的键组合在一起. 例如, `Numpad0 & Numpad1::` 定义了一个热键, 当你按住 Numpad0 并按下 Numpad1 时激活.

当您在自定义组合中使用一个键作为前缀时, AutoHotkey 假定您不希望激活该键的正常功能, 因为这将干扰它作为修饰键的使用. 有两种方法可以恢复按键的正常功能:

1. 使用另一个热键, 如 `Numpad0::Send "{Numpad0}"` 来复制该键的原始功能. 默认情况下, 热键只有在你 释放 Numpad0 时才会激活, 而且只有在你没有同时按下 Numpad0 和 Numpad1 时才会激活.
2. 在组合的前缀中加上波浪号(~), 如 `~Numpad0 & Numpad1::`. 这可以防止 AutoHotkey 抑制 Numpad0 的正常功能, 除非你也定义了 `Numpad0::`, 在这种情况下, 波浪号允许后者的热键立即激活, 而不是当你释放 Numpad0 时.

注意: 自定义组合只支持两个键/鼠标按钮的组合, 不能与其他修饰符组合, 如 `!#^+` 代表的 Alt, Win, Ctrl 和 Shift.

虽然 AutoHotkey 不能直接支持两个以上键的自定义组合, 但使用 #HotIf 也可以实现类似的结果. 如果你运行下面的例子, 按下 `Ctrl`+`CapsLock`+`Space` 或 `Ctrl`+`Space`+`CapsLock` 应该显示一条消息:

    #HotIf GetKeyState("Ctrl")
    Space & CapsLock::
    CapsLock & Space::MsgBox "Success!"

在本例中, 有必要先按 Ctrl. 这样做的好处是, 如果你不按住 Ctrl, Space 和 CapsLock 会执行他们正常的功能.

相关: 自定义组合键

## 其他功能

AutoHotkey 的热键还有其他一些值得探索的功能. 虽然大多数应用程序都局限于组合 Ctrl, Alt, Shift, Win 与另一个键(通常不是键盘上的所有键都被支持), AutoHotkey 没有那么多限制. 如需进一步阅读, 请参阅热键.

dftg