# 常见问答 (FAQ)

#### 语法

- 何时才能在命令和它们的参数中使用引号？
- 何时需要将变量名称装入百分号？
- 何时才应该将百分号和逗号转义？

#### 常见任务

- 为什么我脚本中的某些行总是无法执行？
- 为什么 Run 命令不能启动我的游戏或程序？
- 怎样获取命令行操作的输出？
- 怎样才能让一个脚本关闭、暂停或挂起其它的脚本？
- 怎样才能不退出脚本却可以停止重复的动作？
- 如何在玩游戏或平时 CPU 高负荷运行时改善性能？
- 如何在任意编辑器中使用上下文相关的 AutoHotKey 命令帮助？
- 如何探测一个网页何时加载完毕？
- 怎样操作或比较日期和时间？
- 为什么在某些游戏中，Hotstrings, Send 以及 MouseClick 不起作用？
- 如何控制 Winamp，即使是在它未激活时？
- 如何改变 MsgBox 的按钮名称？

#### 热键、热字符串和重映射

- 如何让我的热键和热字符串在 PC 启动时自动生效？
- 我在把鼠标按键作为热键使用时遇到问题。有什么建议吗？
- 如何将 Tab 和空格键定义为热键？
- 如何将按键或鼠标按钮重映射成其他键？
- 如何将热键或热字符串设置为在特定程序下专用？换句话说，我想让特定按键执行它原来的功能，在指定的窗口激活时除外。
- 如何让前置按键执行它原有的功能，而不是什么也不做？
- 如何修改或者禁用 Windows 内置的快捷键，比如 Win+U (辅助工具管理器) 和 Win+R (运行)？
- 我的数字小键盘上有个特殊的 000 键，能否将其设为热键？

## 语法

#### 何时才能在命令和它们的参数中使用引号？

双引号(")仅在表达式中有特殊的含义。在所有其它的地方，它们就像普通的字符一样被原义地对待。不过，当脚本启动一个程序或文档时，操作系统通常需要用引号把带空格的命令行参数括起来，比如此例：Run, Notepad.exe "C:\My Documents\Address List.txt"

#### 何时需要将变量名称装入百分号？

除了以下用粗体表示的情况外，总是用百分号将变量名括起来的：

1) 在参数里的输入或输出变量：StringLen, OutputVar, InputVar
2) 在赋值表达式的左侧：Var = 123abc
3) 在传统的(非表达式) if 语句的左侧：If Var1 < %Var2%
4) 在表达式的任意位置。例如：
If (Var1 <> Var2)
Var1 := Var2 + 100

#### 何时才应该将百分号和逗号转义？

原义的百分号必须通过在它们前面加重音符/反引号来转义。例如：MsgBox The current percentage is 25`%. 原义的逗号也必须转义 (`,)，除了用在 MsgBox 或任何命令的最后一个参数里时(这些情况下允许使用重音符，但不是必须的)。

当在表达式中，逗号或百分号被双引号括起时，允许使用重音符，但不是必须的。例如：Var := "15%"

## 常见任务

#### 为什么我脚本中的某些行总是无法执行？

任何想在脚本启动时立即执行的行都应该出现在脚本的顶部，要在首个 hotkey, hotstring 或 Return 之前。详见自动执行部分。

而且，一个有多行要执行的热键，必须将它的首行列在热键的下面，而不是同一行。例如：

    #space:: ; Win+空格
    Run Notepad
    WinWaitActive 无标题 - 记事本
    WinMaximize
    return

#### 为什么 Run 命令不能启动我的游戏或程序？

有些程序需要在它们自己的目录下运行(如果不能确定时，通常最好这样做)。例如：
Run, %A_ProgramFiles%\Some Application\App.exe, %A_ProgramFiles%\Some Application

#### 怎样获取命令行操作的输出？

测试显示，由于文件缓存的存在，对于较少量的输出，一个临时文件将生成得非常快。实际上，如果文件在使用后被立即删除，通常它并没有被真正地写到磁盘上。例如：

    RunWait %comspec% /c dir > C:\My Temp File.txt
    FileRead, VarToContainContents, C:\My Temp File.txt
    FileDelete, C:\My Temp File.txt

要避免使用临时文件的话(特别是如果输出较大时)，可以考虑使用 CmdRet。或者，也可用一个免费的小工具 cb.zip (4 KB)，它可以从一个命令或程序获取多达 512KB 的输出。文本被抓取到剪贴板，一个脚本可以通过剪贴板变量来访问该文本。例如：

    RunWait %comspec% /c dir | cb.exe
    MsgBox %clipboard%

#### 怎样才能让一个脚本关闭、暂停或者挂起其它的脚本？

首先，这有个关闭另一个脚本的例子：

    DetectHiddenWindows On ;允许探测到一个隐藏的脚本主窗口。
    SetTitleMatchMode 2 ;避免了需要给下面的文件指定完全路径。
    WinClose Script's File Name.ahk - AutoHotkey ;按脚本的名称更新这里的标题(区分大小写)。

要挂起或者暂停另一个脚本，将上面脚本的最后一行替换为下列命令中的一个：

    PostMessage, 0x111, 65305,,, Script's File Name.ahk - AutoHotkey ;挂起。
    PostMessage, 0x111, 65306,,, Script's File Name.ahk - AutoHotkey ;暂停。

#### 怎样才能不退出脚本却可以停止重复的动作？

要通过按键来暂停或恢复整个脚本，只要像下例那样给 Pause 命令指定一个热键：

    ^!p::Pause ;按 Ctrl+Alt+P 来暂停。再按一次则恢复。

要想停止循环内的动作，参考下例，这是一个可以启用和停止它自身重复动作的热键。换言之，按一次热键将启动循环，再按同个热键将停止循环。

    #MaxThreadsPerHotkey 3
    #z:: ; Win+Z 热键 (可根据你的设置修改这个热键)。
    #MaxThreadsPerHotkey 1
    if KeepWinZRunning ;这意味着一个潜在的线程正在下面的循环中运行。
    {
       KeepWinZRunning := false ;向那个线程的循环发出停止的信号。
       return ;结束此线程，以便下面的线程恢复并得知上一行所做的更改。
    }
    ;否则：
    KeepWinZRunning := true
    Loop
    {
       ;以下四行是你要重复的动作(可根据你的设置修改它们)：
       ToolTip, 再按一次 Win-Z 将停止本提示闪动。
       Sleep 1000
       ToolTip
       Sleep 1000
      ;但是不要修改下面剩下的内容。
       if not KeepWinZRunning ;用户通过再次按下 Win-Z 来对循环发出停止信号。
          break ;跳出此循环。
    }
    KeepWinZRunning := false ;重置，为下一次按热键做准备。
    return

#### 如何在玩游戏或平时 CPU 高负荷运行时改善性能？

当 CPU 高负荷运行时，如果脚本里的 Hotkey, Click 或者 Send 命令明显比平时慢，那么提高脚本的进程优先级可能会有所帮助。要这样做的话，请在接近脚本的顶部包含下面这行命令：
Process, Priority, , High

#### 如何在任意编辑器中使用上下文相关的 AutoHotKey 命令帮助？

这个脚本由 Rajat 创建。

#### 如何探测一个网页何时加载完毕？

用 Internet Explorer 的话，或许最可靠的方法就是使用 DllCall 和 COM，如 www.autohotkey.com/forum/topic19256.html 所示。做一个相关提示，地址栏和状态栏的内容是可以被获取的，如 www.autohotkey.com/forum/topic19255.html 所示。

较早的，不太可靠的方法：下面例子中的技术对用微软的 Internet Explorer 浏览大多数的页面来说都会有效。相似的技术用在其它浏览器上也可能会奏效。

    Run, http://ahkbbs.cn
    MouseMove, 0, 0 ;防止状态栏显示鼠标悬停处的链接来代替“完成”。
    WinWait,AutoHotKey中文论坛
    WinActivate
    StatusBarWait, Done, 30
    if ErrorLevel
       MsgBox 等待超时或者窗口被关闭。
    else
       MsgBox 页面加载完毕。

#### 怎样操作或比较日期和时间？

EnvAdd 命令可以将 YYYYMMDDHH24MISS 格式的时间字符串加上或减去一些天数、小时、分钟或者秒数。下面的例子将指定的时间减去了 7 天：
EnvAdd, VarContainingTimestamp, -7, days

要计算两个日期或时间之间的间隔，请看 EnvSub，它给出了一个示例。此外，内置变量 A_Now 包含了当前本地的时间。最后，还有一些内置的日期/时间变量，以及 FormatTime 命令，它可用来创建自定义的日期/时间字符串。

#### 为什么在某些游戏中，Hotstrings, Send 以及 Click 命令不起作用？

有些游戏专门使用 DirectInput。作为副作用，它们可能忽略所有模拟的键击和鼠标点击。要绕弯解决的话，尝试下列方法之一(或联合使用)：

- 通过：1) SendPlay 命令；2) 使用 SendMode Play 和/或 3) 热字符串选项 SP 来使用 SendPlay。
- 增加 SetKeyDelay。例如：
  SetKeyDelay, 0, 50
  SetKeyDelay, 0, 50, Play
- 尝试用 ControlSend，在其它 Send 模式失效的地方，它可能会有用。

#### 如何控制 Winamp，即使是在它未激活时？

请看 Automating Winamp。

#### 如何改变 MsgBox 的按钮名称？

这里有个示例。

## 热键、热字符串和重映射

#### 如何让我的热键和热字符串在 PC 启动时自动生效？

在开始菜单中有个文件夹叫做启动。如果你将脚本的快捷方式放入此文件夹，那么每次你启动 PC 的时候脚本将自动运行。要创建快捷方式的话：

1. 在资源管理器中选中脚本文件并按下 Control-C。
2. 右键点击开始按钮并选择“浏览所有用户”。
3. 定位到程序文件夹中的启动文件夹。
4. 从菜单栏选择编辑 > 粘贴快捷方式。脚本的快捷方式就会出现在启动文件夹中。

#### 我在把鼠标按键作为热键使用时遇到问题。有什么建议吗？

注意鼠标热键当前在 Windows 95/98/Me 上不可用。在其它操作系统上，鼠标左键和右键应该可以正常地被指定(例如，"#LButton::" 是 Win+左键的热键)。相似地，鼠标中键以及鼠标滚轮的转动应该也可以正常地被指定，除非鼠标驱动直接控制那些按键。

第四个按键(XButton1)和第五个按键(XButton2)也可以被指定，如果你的鼠标驱动允许它们的点击被系统看见。如果它们不可见，或者你的鼠标除你用到的 5 个按键外还有更多的按键，你可以尝试配置鼠标附带的软件(有时在开始菜单或控制面板中)，每当你按下这些键后就使其发送一个键击。这样的键击随后可在脚本中被定义为热键。例如，假设你配置第四个按键来发送 Control+F1，随后在脚本里你可以通过使用 ^F1:: 来间接地将那个按键作为热键来配置。

如果你有一个五个键的鼠标，它的第四个和第五个按键不能被系统看见，那么你可以尝试把你的鼠标驱动改变为操作系统内含的默认驱动。这里假设你特别的鼠标会有可用的驱动并且你可以容忍不使用由鼠标自定义软件所提供的特性。

#### 如何将 Tab 和空格键定义为热键？

使用按键的名称 (Tab 和 Space) 而不是它们的字符。例如，#Space 是 Win+空格，^!Tab 是 Control+Alt+Tab。

#### 如何将按键或鼠标按钮重映射成其他键？

这被写在重映射页面。

#### 如何将热键或热字符串设置为在特定程序下专用？换句话说，我想让特定按键执行它原来的功能，在指定的窗口激活时除外。

首选的方法是 #IfWinActive。例如：

    #IfWinActive, ahk_class Notepad
    ^a::MsgBox 在记事本激活时你按下了 Control-A。

Windows 95/98/Me：虽然上述方法奏效了，但是在记事本以外的窗口中按下 Control-A 将没有任何作用(甚至没有它本来的功能)。要绕弯解决这种情况，请用：

    $^a::Send ^a ; 在 Windows 9x 上，该热键必须首先列出。前缀 & 允许热键“发送它本身”。
    #IfWinActive, ahk_class Notepad
    ^a::MsgBox 在记事本激活时你按下了 Control-A。

#### 如何让前置按键执行它原有的功能，而不是什么也不做？

参考下面这个使用 Numpad0 作为前置按键的示例：

    Numpad0 & Numpad1::MsgBox, 在按住 Numpad0 的同时你按下了 Numpad1。

现在，要让 Numpad0 在它没被用来触发上述热键的时候发送一个真正的 Numpad0 键击，可增加下面的热键：

     $Numpad0::Send, {Numpad0}

需要用前缀 $ 阻止产生一个关于无限循环的警告对话框(因为热键“发送了它自己”)。此外，上述动作在释放按键的时候发生。

#### 如何修改或者禁用 Windows 内置的快捷键，比如 Win+U (辅助工具管理器) 和 Win+R (运行)？

这里有些示例。

#### 我的数字小键盘上有个特殊的 000 键，能否将其设为热键？

可以，但仅适用于 Windows NT, 2000, XP 及以上版本。这个示例脚本将 000 键设为等号键。你可以用你选择的行替换 "Send, =" 这行来改变动作。

翻译：lwjiee 修正：天堂之门 menk33@163.com 2008年11月13日