变量和表达式
变量
变量的类型: AutoHotkey 中没有明确的变量类型. 然而, 只包含数字 (可以含有小数点) 的变量进行数学运算或比较时, 会被自动转换为数值. (为了提高性能, 在内部会对数字进行缓存以避免与字符串之间的转换.)
变量的作用域和声明: 除了函数中的 局部变量, 其他所有变量都是全局的; 即可以在脚本的任意位置读取或修改它们的内容. 除了在函数页面注明的情况,变量都是不需要声明的;使用它们的时候它们就产生了(每个变量初始为空)。
变量的名称: 变量名不区分大小写 (例如, CurrentDate 等同于 currentdate). 变量名可以含有多达 253 个字符, 并且可以由字母, 数字以及后面的标点组成: # _ @ $
考虑到命名的惯例, 通常在命名变量时最好仅使用字母, 数字和下划线 (例如: CursorPosition, Total_Items 和 entry_is_valid). 这样的风格可以让熟悉其他计算机语言的人更容易理解您的脚本. 而且, 如果您在 AutoHotkey 和其他语言中使用相同的风格, 您会发现能更容易重新读懂自己的脚本.
尽管变量名可以完全由数字组成, 但通常这样的名称仅用于 传入的命令行参数. 这样数值名称的变量不能用在 表达式 中, 因为它们会被看成是数字而不是变量.
因为单词 AND, OR 和 NOT 作为表达式的 运算符 使用, 所以通常不应该把它们用作变量名称. 在表达式中使用这样的名称会无法正确计算.
给变量赋值: 要把字符串或数字保存到变量中, 有两种方法: 传统方法和表达式方法. 传统方法使用 等号运算符 (=) 来指定 没有加引号的 原义字符串或包围在百分号中的变量. 例如:
MyNumber = 123 MyString = This is a literal string. CopyOfVar = %Var% ; 和 = 运算符一起使用时, 需要使用百分号来获取变量的内容.
与之相比, 表达式方法使用 冒号等号运算符 (:=) 来保存数字, 加引号的 字符串和其他类型的 表达式. 下面的例子在功能上与前面的例子相同:
MyNumber := 123 MyString := "This is a literal string." CopyOfVar := Var ; 和前面段落中与其作用相同的语句不同, 百分号不和 := 运算符一起使用.
后一种方法由于其更清晰并且与其他许多语言几乎一致的 表达式语法 成为大多数人的首选方法.
从上面的例子中您可能已经想到了有两种方法来清除变量的内容 (即让变量为空):
MyVar = MyVar := ""
上面的这对空引号只能和 := 运算符一起使用, 因为和 = 运算符一起使用时, 则会在变量中保存两个原义的引号字符.
获取变量的内容: 如同赋值有两种方法, 获取变量的内容也有两种方法: 传统方法和表达式方法. 传统方法需要将变量名包围在百分号中来获取变量的内容. 例如:
MsgBox The value in the variable named Var is %Var%. CopyOfVar = %Var%
与之相比, 表达式方法省去了变量名两边的百分号, 但原义的字符串必须包围在双引号中. 所以, 下面的表达式作用等同于上面的例子:
MsgBox % "The value in the variable named Var is " . Var . "." ; 使用句点连接两个字符串. CopyOfVar := Var
在上面的 MsgBox 这行, 通过使用百分号和空格把参数从传统模式改变为表达式模式. 因为所有的命令默认情况下使用传统模式 (除了另外注明的那些), 所以这是必须的. 不过, 某些命令的特定参数已注明接受表达式, 此时前导的百分号可以省略. 例如, 下面的所有语句都是等效的, 因为 Sleep 的首个参数可以是表达式:
Sleep MillisecondsToWait Sleep %MillisecondsToWait% Sleep % MillisecondsToWait
变量的比较: 请阅读下面表达式部分中关于不同类型变量比较的重要提示, 尤其是关于何时使用小括号的内容.
表达式
表达式用来对一系列变量, 原义字符串和/或原义数字执行一个或多个操作.
表达式中的变量名称不用包围在百分号中(伪数组和其他的双重引用除外)。所以, 为了与变量区别, 原义的字符串必须用双引号包围. 例如:
if (CurrentSetting > 100 or FoundColor <> "Blue") MsgBox The setting is too high or the wrong color is present.
在上面的例子中, 因为 "Blue" 是原义字符串, 所以包围在双引号中. 要在原义字符串中包含真实的引号字符,请指定两个连续的引号,如同此例中的两次演示:"She said, ""An apple a day."""
。
重要说明:含有表达式的 if 语句与传统的 if 语句(例如 If FoundColor <> Blue
),可以通过单词“if”后是否有开括号来区分。尽管通常把整个表达式包围在括号中,不过也可以写成这样:if (x > 0) and (y > 0)
。此外, 如果单词 "if" 后的第一项为 函数调用 或类似 "not" 或 "!" 这样的运算符时, 开括号可以完全省略.
空字符串: 要在表达式中使用空字符串, 请指定一对空引号. 例如,当 MyVar 非空时语句 if (MyVar <> "")
的结果为真。然而, 在 传统 if 语句 中, 一对空引号会被视为原义的字符串. 例如,当 MyVar 仅包含一对真实的引号时语句 if MyVar = ""
结果为真。因此,要使用传统的 if 语句判断变量是否为空,则需要让 = 或 <> 的右侧为空,例如:if Var =
。
相关提示,任何无效的表达式例如 (x +* 3)
会产生空字符串。
保存表达式的结果: 要把结果赋值给变量, 请使用 := 运算符. 例如:
NetPrice := Price * (1 - Discount/100)
布尔值: 要计算表达式结果为真还是假时 (例如 IF 语句), 表达式结果为空或零被视为假, 而其他所有结果都视为真. 例如,仅当 ItemCount 为空或 0 时 if ItemCount
的结果才为假。类似地,表达式 if not ItemCount
将产生相反的结果。
像 NOT/AND/OR/>/=/< 这些运算符的运算会自动产生真值或假值的结果: 真值时结果为 1 而假值时为 0. 例如, 在下面的表达式中, 如果有一个条件为真则变量 Done 被赋值为 1:
Done := A_Index > 5 or FoundIt
如上面提示的那样, 简单地置空变量或为其赋值为 0 可以让它假值. 利用这种特性,可以使用简写语句 if Done
来检查变量 Done 是真还是假。
单词 true 和 false 是值分别为 1 和 0 的内置变量. 使用它们可以增加脚本的可读性, 例如:
CaseSensitive := false ContinueSearch := true
整数和浮点数: 在表达式中, 含有小数点的数字被视为浮点数; 否则视为整数. 对于大多数运算符(例如加法和乘法),只要其中的一个输入是浮点数,那么结果也将是浮点数。
不论在表达式中还是在表达式外的其他地方, 整数都可以表示成十六进制或十进制. 十六进制数必须以前缀 0x 开头. 例如,Sleep 0xFF
等同于 Sleep 255
。在 v1.0.46.11+,可以识别用科学计数法表示的浮点数;但只有在它们含有小数点时才行(例如 1.0e4
和 -2.1E-4
)。
强制使用表达式: 通过在表达式前加上百分号和空格或 tab, 能把表达式用在不直接支持表达式的参数中 (除了像 StringLen 的 OutputVar 和 InputVar 的那些参数). 这种技巧常用来访问 数组. 例如:
FileAppend, % MyArray%i%, My File.txt MsgBox % "The variable MyVar contains " . MyVar . "." Loop % Iterations + 1 WinSet, Transparent, % X + 100 Control, Choose, % CurrentSelection - 1
表达式中的运算符
优先级相同的运算符例如乘 (*) 和除 (/) 按从左到右的顺序计算, 下面另行注明的除外. 与之相比, 低优先级的运算符例如加 (+) 在更高优先级的运算符例如 (*) 之后 计算. 例如, 3 + 2 * 2 等价于 3 + (2 * 2). 使用括号可以改变优先级, 例如: (3 + 2) * 2
除了下面注明的情况, 其他时候在数学运算中包含的任何空值 (空字符串) 都 不会 被假定为零. 作为替代, 它会被视为错误, 这将导致那部分表达式的计算结果为空字符串. 例如, 如果变量 X 为空, 那么表达式 X+1 会产生空值而不是 1.
表达式运算符 (按优先级降序排列)
%Var% | 如果表达式中的变量包围在百分号中 (例如 %Var%), 不管此变量 包含 什么内容都会被假定为另一个变量 (如果不存在这样的变量, 那么 %Var% 会被解析为空字符串) 的名称或部分名称. 这种方法常用来引用 伪数组 元素, 例如: Var := MyArray%A_Index% + 100 为了向后兼容, 注明了 "可以使用表达式" 的命令参数把百分号中的孤立名称 (例如 %Var%, 但不是 Array%i%) 当作其两边的百分号不存在一样. 通过把引号包围在括号中可以避免这种情况;例如 [AHK_L 52+]: 除了普通变量, %Var% 还可以解析为 环境变量, 剪贴板或任何的 保留/只读的变量. 在修订号 52 之前, 在这些情况中 %Var% 会被当成空字符串. |
x.y | [AHK_L 31+]: 对象访问. 从对象 x 中取值或为其存入值或调用其方法, 此处 y 是个原义值. 请参阅 对象语法. |
new | [v1.1.00+]:基于其他对象创建新对象。例如,x := new y 通常等价于 x := {base: y} 。new 后应该跟着变量或 GlobalClass.NestedClass 形式的简单类名,还可以像 x := new y(z) 那样加上可选参数(其中 y 是变量而非函数名)。更多细节请参阅自定义对象。 |
++ -- | 前置和后置的自增/自减. 从变量中增加或减去 1 (但在 1.0.46 之前的版本中, 只有把它们放在一行中才能用; 此行中不能使用其他运算符). 运算符可以放在变量名的前面或后面. 如果放在变量名的 前面, 会立即执行运算并把结果用于后面的运算. 例如,Var := ++X 让 X 自增后才把它的值赋给 Var。相反地, 如果运算符放在变量名的 后面, 在后面的运算使用了变量 之后 才对其进行自增运算. 例如,Var := X++ 把 X 的当前值赋给 Var 后才进行自增。由于向后兼容性,仅当空变量在单独一行时运算符 ++ 和 -- 才把它们视为零;例如 y:=1, ++x 和 MsgBox % ++x 当 x 为空时结果都为空。 |
** | 幂. 底数和指数都可以为小数. 如果指数为负数, 即使底数和指数都为整数, 结果也会被格式化为浮点数. 因为 ** 的优先级高于一元负号,所以 -2**2 的计算过程和 -(2**2) 一样且得到结果 -4。因此,要让负号的优先级高于幂运算,需要把它们包围在括号中,例如 (-2)**2 。注意:不支持底数为负数且指数为分数的情况,例如 (-2)**0.5 ;它会产生空字符串。但 (-2)**2 和 (-2)**2.0 都是支持的。 |
- ! ~ & * | 一元负号(-):尽管它和减运算符使用相同的符号,但一元负号仅应用于单项或子表达式,如此例中的两次演示: 逻辑非(!): 如果运算数为空或 0, 那么逻辑非的结果为 1, 这表示 "真". 否则, 结果为 0 (假). 例如: 按位非 (~): 此运算符对运算数按位取反. 如果运算数为浮点数, 则在计算前把它截取成整数. 如果运算数介于 0 和 4294967295 (0xffffffff) 之间, 那么它会被视为 无符号的 32 位值. 否则, 它被视为 有符号的 64 位值. 例如, 取址(&): 解除引用(*): |
* / // | 乘 (*): 如果两个输入都为整数, 则结果为整数; 否则结果为浮点数. 真除 (/): 与 EnvDiv 不同, 即使两个输入都是整数, 真除的结果也为浮点数. 例如, 向下舍除 (//): 如果两个输入都是整数, 那么双斜线运算符使用高效的整数除法. 例如, *= 和 /= 运算符是用变量的值乘以或除以另一个值的一种简写形式. 例如, 除数为零时结果为空 (空字符串). |
+ - | 加 (+) 和 减 (-). 相关提示, += 和 -= 运算符是从变量中增加或减少值的一种简写形式. 例如, |
<< >> | 按位左移 (<<) 和 右移 (>>). 用法示例:Value1 << Value2 。任何浮点数在计算前会被截取成整数. 左移 (<<) 相当于把 Value1 乘以 "2 的 Value2 次幂". 右移(>>)相当于把 Value1 除以“2 的 Value2 次幂”并把结果往下取整到最近的整数;例如,-3>>1 结果为 -2。 |
& ^ | | 按位与 (&), 按位异或 (^) 和 按位或 (|). 这三个运算符中, & 优先级最高而 | 优先级最低. 任何浮点数在计算前会被截取成整数. |
. | 连接. 句点运算符用于把两个项目组合成单个字符串 (在句点的两边至少必须有一个空格). 省略句点也可以达到相同的目的(除非表达式中有不明确的关系,例如 还可以用来连接子表达式. 例如: 以句点 (或其他任何运算符) 开始的行会自动 附加到 前一行的末尾. |
~= | [AHK_L 31+]: RegExMatch 的简写形式. 例如,"abc123" ~= "\d" 会设置 ErrorLevel 为 0 并得到结果 4(首个数字的位置)。在 v1.1.03 之前, 此运算符和 等号 (=) 运算符优先级相同, 却完全没有说明. |
> < >= <= | 大于(>)、小于(<)、大于或等于(>=)和小于或等于(<=)。如果某个输入不是数字, 则按字母顺序比较 (加了引号的原义字符串例如 "55" 在这种情况中总是被当成是非数值的). 仅当 StringCaseSense 打开时, 比较才区分大小写. 另请参阅: Sort |
= == <> != | 等号(=)、区分大小写等于(==) 和 不等于(<> 或 !=)。运算符 != 和 <> 功能完全相同。当两个输入都是数字时,运算符 == 和 = 是一样的,当某个输入不是数字时,== 总是区分大小写,而 = 总是不区分大小写(不区分大小写的方法由 StringCaseSense 决定)。与之相比,<> 和 != 都遵循 StringCaseSense。注意: 加了引号的字符串例如 "55" 在这种情况下总是被当成非数值的. |
NOT | 逻辑非. 除了优先级较低外, 其他的与 ! 运算符相同. 例如,not (x = 3 or y = 3) 等同于 !(x = 3 or y = 3) 。 |
AND && | 这两个运算符都是 逻辑与. 例如:x > 3 and x < 10 。要提高性能, 则要应用 求值优化. 此外, 以 AND/OR/&&/|| (或其他任何运算符) 开始的行会自动 附加到 前一行的末尾. |
OR || | 这两个运算符都是 逻辑或. 例如:x <= 3 or x >= 10 。要提高性能, 则要应用 求值优化. |
?: | 三元运算符 [v1.0.46+]. 此运算符是 if-else 语句 的简写形式. 它计算左侧的条件来决定两个分支中哪个作为最终结果. 例如,var := x>y ? 2 : 3 ,当 x 大于 y 时保存 2 到 Var;否则保存 3。为了提高性能,只计算决定性的分支(请参阅求值优化)。 |
:= += -= *= /= //= .= |= &= ^= >>= <<= | 赋值. 对变量的内容进行运算, 然后把结果保存到同一个变量中 (但在 1.0.46 之前的版本中, 这些运算符只能在一行中最左边使用, 且仅支持前五个运算符). 最简单的赋值运算符为 冒号等号 (:=), 它把表达式的结果保存到变量中. 关于其他运算符的功能说明, 请参阅这个表格中它们的相关条目. 例如, 与其他大多数运算符不同, 赋值运算是从右往左执行的. 因此, 如果使用赋值运算的结果作为其他某些运算符的输出, 那么输入的值是变量自身. 例如,如果变量 Var 新增值后大于 50,那么表达式 需要避免语法错误或提供更直观的操作时, 会自动提升赋值运算符的优先级. 例如: 由向后兼容引起的已知限制(可能会在未来的版本中解决):1) 当 /= 为表达式中最左边的运算符并且它不是多语句表达式的一部分时,而且输入都不是浮点数时,它会执行向下舍除(在其他所有情况中,/= 会执行真除);2) 仅当 += 和 -= 为一行中最左边的运算符时,它们才支持日期/时间的计算;3) 运算符 +=, -= 和 *= 仅在空变量在单独一行时才把它们视为零;例如, |
, | 逗号 (多语句) [v1.0.46+]. 逗号可以用来在单行中书写多个子表达式. 最常用于把多个赋值或函数调用聚集在一起. 例如: 在 v1.0.46.01+, 当逗号后紧跟着变量和等号时, 则这个等号会被自动当成赋值 赋值 (:=). 例如,后面所有的都是赋值: |
mod() | 这些和其他内置数学函数在 这里 阐述. |
func.() | [AHK_L 48+]: 试图调用对象 func 的命名的空方法. 按照约定, 这是对象的 "默认" 方法. 如果 func 不是对象, 则调用 默认基对象. [v1.0.95+]: 如果 func 为函数名, 则调用这个命名的函数. |
F(p*) | [AHK_L 60+]: 请参阅 可变参数函数. |
x[y] | [AHK_L 31+]: 对象访问. 从对象 x 中取值或为其存入值或调用其方法, 这里的 y 是参数列表或计算方法名. 请参阅 数组语法 和 对象语法. |
性能:在 v1.0.48+,使用逗号运算符常常比分开写单独的表达式速度更快,尤其是把一个变量的值赋给另一个变量时(例如 x:=y, a:=b
)。当越多的表达式联合成单个表达式时, 性能会持续得到提升; 例如, 把五个或十个简单的表达式联合成单个表达式速度可能提升 35%.
内置变量
下列变量内置于程序中, 可以在任何脚本中引用. 除了 Clipboard, ErrorLevel 和 命令行参数, 其他变量都是只读的; 即它们的内容无法在脚本中直接修改.
目录
- 特殊字符: A_Space, A_Tab
- 脚本属性: 命令行参数, A_WorkingDir, A_ScriptDir, A_ScriptName, (...更多...)
- 日期和时间: A_YYYY, A_MM, A_DD, A_Hour, A_Min, A_Sec, (...更多...)
- 脚本设置: A_IsSuspended, A_BatchLines, A_TitleMatchMode, (...更多...)
- 用户空闲时间: A_TimeIdle, A_TimeIdlePhysical
- GUI 窗口和菜单栏: A_Gui, A_GuiControl, A_GuiEvent, A_EventInfo
- 热键, 热字串和自定义菜单项: A_ThisHotkey, A_EndChar, A_ThisMenuItem, (...更多...)
- 操作系统和用户信息: A_OSVersion, A_ScreenWidth, A_ScreenHeight, (...更多...)
- 杂项: A_Cursor, A_CaretX, A_CaretY, Clipboard, ClipboardAll, ErrorLevel
- 循环: A_Index, (...更多...)
特殊字符
A_Space | 此变量包含单个空格字符. 请参阅 AutoTrim 了解详情. |
A_Tab | 此变量包含单个 tab 字符. 请参阅 AutoTrim 了解详情. |
脚本属性
1, 2, 3 等 | 每当启动带命令行参数的脚本时, 会自动创建这些变量. 可以像普通变量一样修改和引用它们 (例如: %1%). 变量 %0% 包含了命令行参数的数目 (如果没有则为 0). 需了解详情请参阅 命令行参数. |
A_WorkingDir | 脚本当前工作目录, 这是脚本访问文件的默认路径. 除非是根目录, 否则路径末尾不包含反斜线. 两个示例: C:\ 和 C:\My Documents. 使用 SetWorkingDir 可以改变当前工作目录. |
A_ScriptDir | 当前脚本所在目录的绝对路径. 不包含最后的反斜线(根目录同样如此)。 |
A_ScriptName | 当前脚本的文件名称, 不含路径, 例如 MyScript.ahk. |
A_ScriptFullPath | 上面两个变量的组合, 包含了当前脚本的完整路径和名称, 例如 C:\My Documents\My Script.ahk |
A_ScriptHwnd [v1.1.01+] | 脚本隐藏主窗口的唯一 ID (HWND/句柄). |
A_LineNumber | 当前脚本中正在执行的行所在的行号 (或其 "ListLines.htm">ListLines 显示的一致;它可以用在报告错误的时候,例如: 由于 已编译脚本 已经把它所有的 #Include 文件 合并成一个大脚本, 所以它的行号可能与它在未编译模式运行时不一样. |
A_LineFile | A_LineNumber 所属文件的完整路径和名称, 除非当前行属于未编译脚本的某个 "">A_ScriptFullPath 相同. |
A_ThisFunc [v1.0.46.16+] | 当前正在执行的 自定义函数 的名称 (没有则为空); 例如: MyFunction. 另请参阅: IsFunc() |
A_ThisLabel [v1.0.46.16+] | 当前正在执行的 标签 (子程序) 的名称 (没有则为空); 例如: MyLabel. 每当脚本执行 Gosub/Return 或 Goto 时会更新此变量的值. 执行自动调用的标签时也会更新此变量的值,例如计时器、GUI 线程、菜单项、热键、热字串、OnClipboardChange 和 OnExit。不过,当执行从前面的语句“进入”一个标签时不会更新 A_ThisLabel 的值,即此时它还是保持原来的值。另请参阅: A_ThisHotkey 和 IsLabel() |
A_AhkVersion | 在 1.0.22 之前的版本, 此变量为空. 否则, 它包含了运行当前脚本的 AutoHotkey 主程序的版本号, 例如 1.0.22. 在 已编译脚本 中, 它包含了原来编译时使用的主程序的版本号. 格式化的版本号使得脚本可以使用 > 或 >= 来检查 A_AhkVersion 是否大于某个最小的版本号,例如:if A_AhkVersion >= 1.0.25.07 。 |
A_AhkPath | 对于未编译脚本: 实际运行当前脚本的 EXE 文件的完整路径和名称. 例如: C:\Program Files\AutoHotkey\AutoHotkey.exe 对于 已编译脚本: 除了通过注册表条目 HKEY_LOCAL_MACHINE\SOFTWARE\AutoHotkey\InstallDir 获取 AutoHotkey 目录外, 其他的和上面相同. 如果找不到这个注册表条目, 则 A_AhkPath 为空. |
A_IsUnicode | 当字符串为 Unicode (16 位) 时值为 1, 字符串为 ANSI (8 位) 时为空字符串 (这会被视为 false). 字符串的格式取决于用来运行当前脚本的 AutoHotkey.exe, 如果为已编译脚本, 则取决于用来编译它的主程序. |
A_IsCompiled | 如果当前运行的脚本为 已编译 EXE 时此变量值为 1, 否则为空字符串 (这会被视为 false). |
A_ExitReason | 最近一次要求脚本终止的原因. 除非脚本含有 OnExit 子程序并且此子程序当前正在运行或被退出尝试至少调用过一次, 否则此变量为空. 请参阅 OnExit 了解详情. |
日期和时间
A_YYYY | 4 位数表示的当前年份 (例如 2004). 与 A_Year 含义相同. 注意:要获取符合您区域设置和语言的格式化时间或日期,请使用 FormatTime, OutputVar (时间和长日期)或 FormatTime, OutputVar,, LongDate (获取长格式日期)。 |
A_MM | 2 位数表示的当前月份 (01-12). 与 A_Mon 含义相同. |
A_DD | 2 位数表示的当前月份的日期 (01-31). 与 A_MDay 含义相同. |
A_MMMM | 使用当前用户语言表示的当前月份的全称, 例如 July |
A_MMM | 使用当前用户语言表示的当前月份的简称, 例如 Jul |
A_DDDD | 使用当前用户语言表示的当前星期几的全称, 例如 Sunday |
A_DDD | 使用当前用户语言表示的当前星期几的 3 个字母的简称, 例如 Sun |
A_WDay | 1 位数表示的当前星期经过的天数 (1-7). 在所有区域设置中 1 都表示星期天. |
A_YDay | 当前年份中经过的天数 (1-366). 不会使用零对变量的值进行填充, 例如会获取到 9, 而不是 009. 要对变量的值进行零填充,请使用:FormatTime, OutputVar, , YDay0 。 |
A_YWeek | 符合 ISO 8601 标准的当前的年份和周数 (例如 200453). 要分离年份和周数,请使用 StringLeft, Year, A_YWeek, 4 和 StringRight, Week, A_YWeek, 2 。A_YWeek 的准确定义为: 如果含有 1 月 1 日的星期有四天以上在新年里, 则它被认为是新年的第一个星期. 否则, 它为前一年的最后一个星期, 而下一星期为新年的第一星期. |
A_Hour | 在 24 小时制 (例如, 17 表示 5pm) 中 2 位数表示的当前小时数 (00-23). 要获取带 AM/PM 提示的 12 小时制的时间,请参照此例:FormatTime, OutputVar, , h:mm:ss tt |
A_Min | 2 位数表示的当前分钟数 (00-59). |
A_Sec | 2 位数表示的当前秒数 (00-59). |
A_MSec | 3 位数表示的当前毫秒数 (000-999). 要移除前导零,请参照此例:Milliseconds := A_MSec + 0 。 |
A_Now | YYYYMMDDHH24MISS 格式的当前本地时间. 注意: 使用 EnvAdd 和 EnvSub 可以对日期和时间进行计算. 此外, 使用 FormatTime 可以根据您的区域设置或选项来格式化日期和/或时间. |
A_NowUTC | YYYYMMDDHH24MISS 格式的当前的协调世界时 (UTC). UTC 本质上和格林威治标准时间 (GMT) 一致. |
A_TickCount | 计算机重启后经过的毫秒数. 通过把 A_TickCount 保存到变量中, 经过一段时间后从最近的 A_TickCount 值中减去那个变量, 可以计算出所经过的时间. 例如: StartTime := A_TickCount Sleep, 1000 ElapsedTime := A_TickCount - StartTime MsgBox, %ElapsedTime% milliseconds have elapsed. 如果您需要比 A_TickCount 的10ms 更高的精确度, 请使用 QueryPerformanceCounter(). |
脚本设置
A_IsSuspended | 当脚本 挂起时 值为 1, 否则为 0. |
A_IsPaused [v1.0.48+] | 当紧随当前线程的 线程 被 暂停 时值为 1. 否则为 0. |
A_IsCritical [v1.0.48+] | 当前线程 的 Critical 设置关闭时值为 0. 否则它包含大于零的整数, 即 Critical 使用的 消息检查频率. 因为 Critical 0 关闭了当前线程的关键性,所以 Critical 的当前状态可以这样来保存和恢复:Old_IsCritical := A_IsCritical ,后来执行 Critical %Old_IsCritical% 。 |
A_BatchLines | (同义于 A_NumBatchLines) 由 SetBatchLines 设置的当前值. 例如: 200 或 10ms (取决于格式). |
A_TitleMatchMode | 由 SetTitleMatchMode 设置的当前模式: 1, 2, 3 或 RegEx. |
A_TitleMatchModeSpeed | 由 SetTitleMatchMode 设置的当前匹配速度 (fast 或 slow). |
A_DetectHiddenWindows | 由 DetectHiddenWindows 设置的当前模式 (On 或 Off). |
A_DetectHiddenText | 由 DetectHiddenText 设置的当前模式 (On 或 Off). |
A_AutoTrim | 由 AutoTrim 设置的当前模式 (On 或 Off). |
A_StringCaseSense | 由 StringCaseSense 设置的当前模式 (On, Off 或 Locale). |
A_FileEncoding | [AHK_L 46+] 包含了多个命令使用的默认编码; 请参阅 FileEncoding. |
A_FormatInteger | 由 SetFormat 设置的当前整数格式 (H 或 D). [AHK_L 42+]: 此变量还可能为小写字母 h. |
A_FormatFloat | 由 SetFormat 设置的当前浮点数格式. |
A_KeyDelay | 由 SetKeyDelay 设置的当前延迟 (总是十进制数, 不是十六进制). 此延迟适用于传统的 SendEvent 模式, 不适用于 SendPlay. |
A_WinDelay | 由 SetWinDelay 设置的当前延迟 (总是十进制数, 不是十六进制). |
A_ControlDelay | 由 SetControlDelay 设置的当前延迟 (总是十进制数, 不是十六进制). |
A_MouseDelay | 由 SetMouseDelay 设置的当前延迟 (总是十进制数, 不是十六进制). 此延迟适用于传统的 SendEvent 模式, 不适用于 SendPlay. |
A_DefaultMouseSpeed | 由 SetDefaultMouseSpeed 设置的当前速度 (总是十进制数, 不是十六进制). |
A_RegView | [v1.1.08+]:由 SetRegView 设置的当前注册表视图。 |
A_IconHidden | 托盘图标当前隐藏时值为 1, 否则为 0. 此图标可以使用 https://www.xnip.cn/shouce/1165/74667.html 命令进行隐藏. |
A_IconTip | 如果使用 Menu, Tray, Tip 为托盘图标指定了自定义的工具提示时,变量的值为这个提示的文本,否则为空。 |
A_IconFile | 如果使用 Menu, tray, icon 指定了自定义的托盘图标时,变量的值为图标文件的完整路径和名称,否则为空。已知限制:如果脚本原来传递相对路径给系统的 DLL,那么此变量中的路径可能不正确;例如 Menu, Tray, Icon, user32.dll, 2 。 |
A_IconNumber | 当 A_IconFile 为空时此变量为空. 否则, 它的值为 A_IconFile 中的图标编号 (通常为 1). |
用户空闲时间
A_TimeIdle | 从系统最后一次接收到键盘, 鼠标或其他输入后所经过的毫秒数. 这可以用来判断用户是否离开. 用户的物理输入和由 任何 程序或脚本生成的模拟输入 (例如 Send 或 MouseMove 命令) 会让此变量重置为零. 由于此变量的值趋向于以 10 的增量增加, 所以不应该判断它是否等于另一个值. 相反, 应该检查此变量是否大于或小于另一个值. 例如:IfGreater, A_TimeIdle, 600000, MsgBox, The last keyboard or mouse activity was at least 10 minutes ago 。 |
A_TimeIdlePhysical | 与上面类似, 但在安装了相应的钩子 (键盘 或 鼠标) 后会忽略模拟的键击和/或鼠标点击; 即此变量仅反应物理事件. (这样避免了由于模拟键击和鼠标点击而误以为用户存在.) 如果两种钩子都没有安装, 则此变量等同于 A_TimeIdle. 如果仅安装了一种钩子, 那么仅此类型的物理输入才会对 A_TimeIdlePhysical 起作用 (另一种/未安装钩子的输入, 包括物理的和模拟的, 都会被忽略). |
GUI 窗口和菜单栏
A_Gui | 启动了 当前线程 的 GUI 的名称或编号. 除非当前线程是由 Gui 控件, 菜单项或 Gui 事件 (例如 GuiClose/GuiEscape) 启动的, 否则此变量为空. |
A_GuiControl | 启动 当前线程 的 GUI 控件的关联变量名. 如果那个控件没有 关联变量, 则 A_GuiControl 包含此控件的文本/标题中前 63 个字符 (这常用来避免给每个按钮分配变量名). 出现后面这些情况时 A_GuiControl 为空: 1) A_Gui 为空; 2) GUI 菜单项或事件 (例如 GuiClose/GuiEscape) 启动了当前线程; 3) 那个控件没有关联变量, 也没有标题; 或 4) 最初启动当前线程的控件已经不存在 (可能由于 Gui Destroy 的原因). |
A_GuiWidth A_GuiHeight | 在 GuiSize 子程序 中引用时, 它们分别包含了 GUI 窗口的宽度和高度. 它们对应于窗口的工作区, 这是窗口中不包括标题栏, 菜单栏和边框的区域. [v1.1.11+]:这些值会受 DPI 缩放的影响。 |
A_GuiX A_GuiY | 它们包含了 GuiContextMenu 和 GuiDropFiles 事件中的 X 和 Y 坐标. 这里的坐标相对于窗口的左上角. [v1.1.11+]:这些值会受 DPI 缩放的影响。 |
A_GuiEvent 或 A_GuiControlEvent | 启动当前线程的事件类型。如果当前线程不是由 GUI 动作 启动的,则此变量为空。否则, 它为下列字符串的其中一个: Normal: 此事件是由左键单击和键击 (方向键, TAB 键, 空格键, 带下划线的快捷键等) 触发的. 此变量的值还可以用于菜单项和特殊的 Gui 事件, 例如 GuiClose 和 GuiEscape. DoubleClick: 此事件是由双击触发的. 注意: 双击中的首次点击仍会引起 Normal 事件首先被接收到. 换句话说, 双击时子程序会运行两次: 一次在首次点击时, 再次是在第二次点击时. RightClick: 仅出现在 GuiContextMenu, ListViews 和 TreeViews. 上下文相关值:要了解详情请参阅 GuiContextMenu、GuiDropFiles、Slider、MonthCal、ListView 和 TreeView。 |
A_EventInfo | 包含下列事件的额外信息:
|
注意: 与类似 A_ThisHotkey 这样的变量不同, 每个 线程 会为 A_Gui, A_GuiControl, A_GuiX/Y, A_GuiEvent 和 A_EventInfo 保存它自己本身的值. 因此, 如果一个线程被另一个中断, 在这个线程恢复时它仍将看到这些变量的原来/正确的值.
热键, 热字串和自定义菜单项
A_ThisMenuItem | 最近选择的 自定义菜单项 的名称 (没有则为空). |
A_ThisMenu | A_ThisMenuItem 所在菜单的名称. |
A_ThisMenuItemPos | 表示 A_ThisMenuItem 在 A_ThisMenu 当前 位置的编号. 菜单中首个项目为 1, 第二项为 2, 依此类推. 菜单分隔线也计算在内. 如果 A_ThisMenuItem 为空或已不存在于 A_ThisMenu 中, 则此变量为空. 如果 A_ThisMenu 已不存在, 则此变量也为空. |
A_ThisHotkey | 最近执行的 热键 或 非自动替换热字串 的按键名称 (如果没有则为空), 例如 "https://www.xnip.cn/doc/AutoHotkey-Threads">当前线程 被其他热键中断, 那么此变量的值会变化, 所以如果之后需要在子程序中使用原来的值, 则必须马上把它复制到另一个变量中. 首次创建热键时 (通过 Hotkey 命令 或 双冒号标签 ), 其键名以及修饰符的顺序成为此热键的固定名称. 另请参阅: A_ThisLabel |
A_PriorHotkey | 除了保存前一次热键的名称外, 其他的与上面相同. 如果没有它会为空. |
A_PriorKey | [v1.1.01+]: 在最近按键按下或按键释放前最后按下的按键名称, 如果在按键历史中没有适用的按键按下则为空. 不包括由 AutoHotkey 脚本生成的所有输入. 要使用此变量, 首先必须安装 键盘 或 鼠标钩子 同时启用 按键历史. |
A_TimeSinceThisHotkey | 从 A_ThisHotkey 按下后到现在经过的毫秒数. 如果 A_ThisHotkey 为空, 则此变量的值为 -1. |
A_TimeSincePriorHotkey | 从 A_PriorHotkey 按下后到现在经过的毫秒数. 如果 A_PriorHotkey 为空, 则此变量的值为 -1. |
A_EndChar | 用户最近按下的触发了 非自动替换热字串 的 终止符. 如果不需要终止符 (由于使用了 * 选项), 那么此变量将为空. |
操作系统和用户信息
ComSpec [v1.0.43.08+] | 此变量的值与系统环境变量 ComSpec 一样 (例如 C:\Windows\system32\cmd.exe). 常与 Run/RunWait 一起使用. 注意: 此变量不带 A_ 前缀. |
A_Temp [v1.0.43.09+] | 存放临时文件的文件夹的完整路径和名称 (例如 C:\DOCUME~1\UserName\LOCALS~1\Temp). 它的值从下列的其中一个位置获取 (按顺序): 1) 环境变量 TMP, TEMP 或 USERPROFILE; 2) Windows 目录. |
A_OSType | 正在运行的操作系统类型。由于 AutoHotkey 1.1 仅支持基于 NT 的操作系统,所以此变量总是为 WIN32_NT。旧版本的 AutoHotkey 运行在 Windows 95/98/ME 时会返回 WIN32_WINDOWS。 |
A_OSVersion | 下列字符串的其中一个:WIN_7 [需要 v1.1+ 或 AHK_L]、WIN_8 [需要 v1.1.08+]、WIN_8.1 [需要 v1.1.15+]、WIN_VISTA、WIN_2003、WIN_XP、WIN_2000。 ; 这个示例已过时了,里面的这些操作系统都不再受支持。 if A_OSVersion in WIN_NT4,WIN_95,WIN_98,WIN_ME ; 注:逗号两边没有空格。 { MsgBox This script requires Windows 2000/XP or later. ExitApp } |
A_Is64bitOS | [v1.1.08+]:当操作系统为 64 位则值为 1(真),为 32 位则为 0(假)。 |
A_PtrSize | [AHK_L 42+]: 包含指针的大小值, 单位为字节. 值为 4(32 位)或 8(64位),取决于运行当前脚本的执行程序的类型。 |
A_Language | 当前系统的默认语言, 值为 这些 4- 位数字编码 的其中一个. |
A_ComputerName | 在网络上看到的计算机名称. |
A_UserName | 运行当前脚本的用户的登录名. |
A_WinDir | Windows 目录. 例如: C:\Windows |
A_ProgramFiles 或 ProgramFiles | Program Files 目录 (例如 C:\Program Files). 在 v1.0.43.08+, 前缀 A_ 可以省略, 这样有助于自然过渡到 #NoEnv. |
A_AppData [v1.0.43.09+] | 当前用户的应用程序数据文件夹的完整路径和名称. 例如: C:\Documents and Settings\Username\Application Data |
A_AppDataCommon [v1.0.43.09+] | 所有用户的应用程序数据文件夹的完整路径和名称. |
A_Desktop | 当前用户的桌面文件夹的完整路径和名称. |
A_DesktopCommon | 所有用户的桌面文件夹的完整路径和名称. |
A_StartMenu | 当前用户的开始菜单文件夹的完整路径和名称. |
A_StartMenuCommon | 所有用户的开始菜单文件夹的完整路径和名称. |
A_Programs | 当前用户的开始菜单中程序文件夹的完整路径和名称. |
A_ProgramsCommon | 所有用户的开始菜单中程序文件夹的完整路径和名称. |
A_Startup | 当前用户的开始菜单中启动文件夹的完整路径和名称. |
A_StartupCommon | 所有用户的开始菜单中启动文件夹的完整路径和名称. |
A_MyDocuments | 当前用户 "我的文档" 文件夹的完整路径和名称. 与大多数类似变量不同, 当此文件夹为驱动器的根目录时, 此变量的值不包含最后的反斜线. 例如, 它的值我 M: 而不是 M:\ |
A_IsAdmin | 如果当前用户有管理员权限, 则此变量的值为 1. 否则为 0. 在 Windows Vista 或更高版本中, 一些脚本可能需要管理员权限才能正常运行 (例如与使用管理员权限执行的进程和窗口进行交互的脚本). 要做到这点,请把下列语句添加到脚本的顶部: if not A_IsAdmin { Run *RunAs "%A_ScriptFullPath%" ; 需要 v1.0.92.01+ ExitApp } |
A_ScreenWidth | 主监视器的宽度和高度, 单位为像素 (例如 1024 和 768). 要获取多显示器系统中其他显示器的尺寸, 请使用 SysGet. 要获取整个桌面(即使它横跨多个显示器)的宽度和高度,请使用下面的例子: SysGet, VirtualWidth, 78 SysGet, VirtualHeight, 79 此外, 使用 SysGet 可以获取显示器的工作区域, 它比显示器的整个区域小, 因为它不包括任务栏和其他注册的桌面工具栏. |
A_ScreenDPI [v1.1.11+] | 在屏幕宽度上每逻辑寸的像素数。在多显示器的系统中,这个值对于所有的显示器都是一样的。在大多数系统中该值为 96;它取决于系统文本大小(DPI)设置。另请参阅 Gui -DPIScale。 |
A_IPAddress1 到 4 | 计算机中前 4 个网卡的 IP 地址. |
杂项
A_Cursor | 当前显示的鼠标光标类型. 其值为下列单词的其中一个: AppStarting, Arrow, Cross, Help, IBeam, Icon, No, Size, SizeAll, SizeNESW, SizeNS, SizeNWSE, SizeWE, UpArrow, Wait, Unknown. 与 size 指针类型一起的首字母表示方向, 例如 NESW = NorthEast+SouthWest. 手型指针 (点击和抓取) 属于 Unknown 类别. |
A_CaretX A_CaretY | 当前光标 (文本插入点) 的 X 和 Y 坐标. 如果没有使用 CoordMode 使得坐标相对于整个屏幕, 默认坐标相对于活动窗口. 如果没有活动窗口或无法确定文本插入点的位置, 则这两个变量为空. 下面这个脚本可以让您在四处移动文本插入点时, 查看显示在自动更新工具提示上的当前位置. 注意在某些窗口 (例如某些版本的 MS Word) 会不管文本插入点的实际位置如何都报告同样的位置. #Persistent SetTimer, WatchCaret, 100 return WatchCaret: ToolTip, X%A_CaretX% Y%A_CaretY%, A_CaretX, A_CaretY - 20 return 如果以很高的频率 (即每 500 ms 或更快) 重复获取这些变量的内容, 那么可能会干扰用户双击鼠标. 没有已知的解决方法. |
Clipboard | 操作系统剪贴板的内容, 可以从中读取或写入内容. 请参阅 剪贴板 章节. |
ClipboardAll | 剪贴板中的完整内容 (包含格式和文本). 请参阅 ClipboardAll. |
ErrorLevel | 请参阅 ErrorLevel. |
A_LastError | 操作系统 GetLastError() 函数或最近 COM 对象调用返回的结果. 要了解详情, 请参阅 DllCall() 和 Run/RunWait. |
循环
A_Index | 当前循环重复的次数 (64 位整数). 例如, 当脚本首次执行此循环体时, 此变量的值为 1. 要了解详情请参阅 Loop 或 While 循环. |
A_LoopFileName 等 | 此变量和其他相关变量仅在 文件循环 中有效. |
A_LoopRegName 等 | 此变量和其他相关变量仅在 注册表循环 中有效. |
A_LoopReadLine | 请参阅 文件读取循环. |
A_LoopField | 请参阅 解析循环. |
环境变量与 "普通" 变量
环境变量由操作系统维护. 在命令提示符中输入 SET 并回车后, 您可以看到环境变量列表.
脚本中可以使用 EnvSet 创建新的环境变量或改变现有环境变量的内容. 但是, 这样的添加和改变都是私有的; 它们不会被系统的其他部分看到. 一个例外是当脚本使用 Run 或 RunWait 运行程序时 (甚至是另一个脚本): 这样的程序会继承其父脚本的环境变量的副本, 包括私有的那些.
在 v1.0.43.08+, 推荐在所有新脚本中使用以下方式获取环境变量, 例如 Path:
EnvGet, OutputVar, Path ; 想了解含义, 请参阅 #NoEnv.
变量的容量和占用内存
- 每个变量最多可以含有64MB的文本(使用#MaxMem可以突破这个限制)。
- 当赋值给变量比当前更长的内容时, 会自动分配额外的系统内存给这个变量.
- 通过赋值为空可以释放大变量占用的内存,例如
Var := ""
。 - 脚本可以创建的变量数量没有限制. 程序设计用来支持至少几百万的变量而不会出现明显的性能下降.
- 接受数值输入的命令, 函数和表达式通常可以支持 15 位的浮点数精度. 对于整数, 可以支持 64 位有符号整数, 其范围从 -9223372036854775808 (-0x8000000000000000) 到 9223372036854775807 (0x7FFFFFFFFFFFFFFF). 此范围外的任何整数不受支持, 并可能产生错误的结果. 与之相比, 整数的算数运算结果超出此范围时会产生溢出 (例如 0x7FFFFFFFFFFFFFFF + 1 = -0x8000000000000000).