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

## 内容列表

- 介绍和简单的例子
- 热键前缀符号(修饰键)
- 上下文相关的热键
- 自定义组合键和其他特性
- 鼠标滚轮热键
- 热键技巧和备注

## 介绍和简单的例子

热键有时也被称作快捷键，因为它们能轻易地触发一个动作(例如启动一个程序或键盘宏)。在下面的例子中，热键 Win+N 被设定为启动记事本。pound sign [#] 表示 Windows 键，其被称作修饰键：

    #n::
    Run Notepad
    return

在上面的最后一行，"return" 用来结束热键。不过，如果一个热键仅仅需要执行一行，那么这行可以列在双冒号的右边。换句话说，return 可以省略：

    #n::Run Notepad

要对一个热键使用多个修饰键，把它们连续地列出来(顺序没有关系)。下面的例子用 ^!s 来表示 Control+Alt+S:

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

#### 你可以使用下列的修饰键符号来定义热键：

符号 | 描述
# | Win (Windows 标识键)
! | Alt
^ | Control
+ | Shift
& | 一个连接符可以用在任何两个键或者鼠标按键的中间，从而将它们组合成一个自定义热键。详见下面 。这样的热键在 Windows 95/98/Me 上被忽略(未被激活)。
< | 使用成对按键中左边的按键。例如 <!a 和 !a 一样，只是仅有左边的 Alt 键会触发它。这个符号在 Windows 95/98/ME 上被忽略。
> | 使用成对按键中右边的按键。这个符号在 Windows 95/98/ME 上被忽略。
<^>! | AltGr (alternate graving)(译注：传说此键出现在大部分欧洲键盘上)。如果你的键盘布局中有一个代替右 Alt 键的 AltGr 键，这一系列的符号一般能用来表示 AltGr (需要 Windows NT/2k/XP 或之后版本)。例如：
    <^>!m::MsgBox 你按下了 AltGr+m.
    <^<!m::MsgBox 你按下了 LeftControl+LeftAlt+m.
或者，要使 AltGr 它自己成为一个热键，使用下面的热键(不用像上面出现的任何一个热键):
    LControl & RAlt::MsgBox 你按了 AltGr 它本身。
* | 通配符：即使附加的修饰键被按住也激发热键。这常被用来协同重映射按键或按钮。例如：
    *#c::Run Calc.exe ; Win+C, Shift+Win+C, Ctrl+Win+C 等全部会触发这个热键。
    *ScrollLock::Run Notepad ;即使当修饰键按住时，按下 Scrolllock 键也将触发这个热键。
这个符号在 Windows 95/98/ME 上被忽略。
~ | 当激发热键时，按键的原来的功能不会被屏蔽(被操作系统隐藏)。在下面的两个例子中，用户的鼠标按钮点击将被发送到激活的窗口：
    ~RButton::MsgBox 你点击了鼠标右键。
    ~RButton & C::MsgBox 你在按住鼠标右键的同时按下了 C 键。
注意：1) 和其他前缀符号不同，波浪符前缀被允许在一个热键的某些变体上出现但在其他部分不存在；2) 那些代替 alt-tab的特殊热键永远忽略波浪符前缀；3) 波浪符前缀在 Windows 95/98/ME 上被忽略。
$ | 这符号通常仅仅在脚本使用 Send 命令发送包含了热键自身的按键时才有必要使用，否则这可能导致发送热键触发它自己。$ 前缀确切的特性变化取决于操作系统： 在 Windows NT4/2k/XP 或之后版本上：$ 前缀强制使用键盘钩子来执行这个热键，作为一个副作用它防止了 Send 命令触发热键。$ 前缀等效于在此热键定义的上面某处指定了 #UseHook。 在 Windows 95/98/Me 上：热键在它的线程执行期间被禁用，之后重新启用。作为一个副作用，如果 #MaxThreadsPerHotkey 设成高于 1，它也将表现得像被这个热键设为 1 一样。
UP | 单词 UP 可以跟在一个热键名称后面来促使热键在松开按键时激发而不是在按下按键时。下面的例子将 LWin 重映射成 LControl: *LWin::Send {LControl Down} *LWin Up::Send {LControl Up} "Up" 也可以和一般的热键一起使用比如在这个例子中： ^!r Up::MsgBox 你按下并松开了 Ctrl+Alt+R 。它也可以和 组合热键 一起用(例如 F1 & e Up::) 限制: 1) "Up" 不能和游戏杆按钮一起用；2) "Up" 需要 Windows NT4/2000/XP 或之后版本；3) 不和一个普通/按下的配对热键一起用的 "Up" 热键将完全接管那个热键从而防止它卡在按下的状态。唯一能防止这种情况发生的就是添加一个波浪符前缀 (例如 ~LControl up::) 作个相关的提示，和上面相似的一个技术是让一个热键成为一个前缀键。尽管热键会在松开时激发是个有利情况，但热键仅在你如果按住它的同时不去按其他任何键的时候才会激发。例如：
    LControl & F1::return ;通过让左 control 键在 "&" 前面至少使用一次来把它变成一个前缀。
    LControl::MsgBox 你在没有用 LControl 去修饰其他任何键的情况下松开了它。

(请看按键列表获取一个完整的键盘按键和鼠标/操纵杆按钮列表)

多个热键可以被垂直地堆放起来让它们执行同样的动作。例如：

    ^Numpad0::
    ^Numpad1::
    MsgBox 按了 Control+Numpad0 或 Control+Numpad1 都会显示这个消息。
    return

通过让热键不作任何动作可以在整个操作系统中禁用一个键或者组合键。下面的例子禁用了右边的 Windows 键：

    RWin::return

## 上下文相关的热键

#IfWinActive/Exist 指令可以被用来让一个热键视激活或存在的窗口的类型而执行一个不同的动作(或根本无动静)。例如：

    #IfWinActive, ahk_class Notepad
    ^a::MsgBox 你在记事本激活时按了 Ctrl-A 。在其他任何窗口按 Ctrl-A 将只传递 Ctrl-A 键击到那个窗口。
    #c::MsgBox 你在记事本激活时按了 Win-C 。
    #IfWinActive
    #c::MsgBox 你在除了记事本外的任意窗口激活时按了 Win-C 。

## 自定义组合键和其他特性 [Windows NT/2000/XP 或之后版本]

你可以通过在两个键之间使用 " & " 来自定义一个组合键(除了操纵杆按钮)。在下面的例子中，你能够按住 Numpad0 之后再按第二个键来触发热键：

    Numpad0 & Numpad1::MsgBox 你在按住 Numpad0 的同时按下了 Numpad1 。
    Numpad0 & Numpad2::Run Notepad

在上面的例子中，Numpad0 变成一个前缀键；而且也导致了通过它去按 Numpad0 它自己的时候失去了它原本/天生的功能。要避免这种情况，脚本可以像下面中的一种那样来配置 Numpad0 去执行一个新的动作：

    Numpad0::WinMaximize A ;最大化激活的/前台的窗口。
    Numpad0::Send {Numpad0} ;让 Numpad0 松开后去再生一个 Numpad0 键击。请见下面的内容。

上面的热键之一的存在都促使 Numpad0 松开后去执行指示的动作，但仅在 Numpad0 被按住时如果你没有去按其他任何键的情况下。

Numlock, Capslock 和 Scrolllock: 这些按键可以被强制变成 "AlwaysOn" 或 "AlwaysOff"。例如：SetNumlockState AlwaysOn

覆写 Explorer 的热键: 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。

## 鼠标滚轮热键 [Windows NT/2000/XP 或之后版本]

通过键名 WheelDown 和 WheelUp 可以支持在调节鼠标滚轮的时候激发热键。WheelLeft 和 WheelRight 需要 v1.0.48+ 以上支持, 但是在 Windows Vista 或以上没影响. 以下是 鼠标滚轮热键 的例子:

    MButton & WheelDown::MsgBox 你在按住鼠标中键的时候向后滚动了滚轮。
    ^!WheelUp::MsgBox 你在按住 Control+Alt 的时候向前旋转了滚轮。

在 v1.0.43.03+ ，内置变量 A_EventInfo 包含了通过调节滚轮得到的触点次数，它一般情况是 1。然而，在下面的情况下， A_EventInfo 可能大于或小于1：如果鼠标硬件报告的距离不足一个刻痕(你滚动滚轮感觉到的一下)，A_EventInfo 可能包含 0；当滚轮被快速地滚动(取决于鼠标类型)，A_EventInfo 可能大于 1。例子用法：~WheelDown::ToolTip %A_EventInfo%

鼠标滚轮的一些最有用的热键涉及交替窗口的文本滚动模式。例如，下面的一对热键在你按住左边的 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, 不管 Numlock 是否打开，这个热键都将被启用。
    return

如果波浪操作符 (~) 和一个前缀键即使一起使用了一次，前缀键也总是会被发送到激活的窗口。例如，下面两个热键中，激活的窗口会接收到所有的右键点击即使只有一个热键定义包含了波浪符：

    ~RButton & LButton::MsgBox 你在按住鼠标右键的同时按了鼠标左键。
    RButton & WheelUp::MsgBox 你在按住鼠标右键的同时向前推动了滚轮。

Suspend 命令能临时禁用所有热键除了你要免除的那些外。要得到更多的选择性，使用 #IfWinActive/Exist。

通过使用 Hotkey 命令，热键能在脚本运行过程中被动态地创建。Hotkey 命令也能单独地修改、禁用或启用已存在的脚本热键。

操纵杆热键目前不支持修饰键前缀例如 ^ (Control) 和 # (Win)。不过，你可以使用 GetKeyState 模仿下面例子中展示的这个效果：

    Joy2::
    if not GetKeyState("Control") ;左边或右边的 Control 都没有按下。
       return ;也就是什么也不做。
    MsgBox 你在按住 Control 键的同时按了首个操纵杆的第二个按钮。
    return

当一个热键在继续前要等它的修饰键被松开的时候可能需要一些时间。参考下面的例子：

    ^!s::Send {Delete}

按下 Control-Alt-S 会导致系统表现得像你按了 Control-Alt-Delete 一样(由于系统的侵略性的 Ctrl-Alt-Delete 探测)。要绕弯解决这种情况，使用 KeyWait 来等待那些键被松开；例如：

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

一个热键标记能被用作 Gosub 或 Goto 要跳转的目标。例如：Gosub ^!s

一个热键常用来开始和结束一个重复的动作，比如一系列的键击或鼠标点击。要得到这样一个例子，请看这个 FAQ 主题。

最后，每个脚本都是类似的多线程，其允许在前一个热键子程序还在运行时，一个新的热键也能被启动。例如，即使当一个 MsgBox 被当前热键调用显示时，新的热键也能被启动。

## Alt-Tab 热键

每个 Alt-Tab 热键必须是一个双键组合，其往往通过连接符 (&) 实现。在下面的例子中，你将按住右边的 Alt 键并按下 J 或 K 来浏览 alt-tab 菜单：

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

AltTab 和 ShiftAltTab 是两个特殊的命令，它们仅当和热键使用在同一行时才被识别。这里有一个完整的列表：

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 动作必须像上面的例子一样直接指定到一个热键(也就是它们不能像命令那样使用)。另外，alt-tab 菜单的存在能通过 IfWinExist ahk_class #32771 探测到。

自定义 alt-tab 动作也能通过热键来创建。在下面的例子中，你将按 F1 来显示菜单并原先在里面前移。然后你将按 F2 来激活选中的窗口(或按 Escape 来取消)：

    *F1::Send {Alt down}{tab} ;在这里需要星号。译注：因为按了后 Alt 处于 Down 状态，再次激发热键只能靠星号匹配 Alt 这种修饰键。
    !F2::Send {Alt up} ;松开 Alt 键激活选中的窗口。
    ~*Escape::
    IfWinExist ahk_class #32771
       Send {Escape}{Alt up} ;取消菜单而不激活选中的窗口。
    return

翻译：天堂之门 menk33@163.com 2008年11月22日