# GUI 控件类型

## 目录

- Text(文本), Edit(文本编辑区), UpDown(增减按钮组), Picture(图片)
- Button(按钮), Checkbox(多选按钮), Radio(单选按钮)
- DropDownList(静态下拉列表), ComboBox(可输入下拉列表)
- ListBox(简单列表), ListView(高级表格), TreeView(树形列表)
- Link(链接), Hotkey(热键), DateTime(时间日期选择器)
- MonthCal(月历), Slider(滑动条), Progress(进度条)
- GroupBox(分组框), Tab3(选项卡), StatusBar(状态栏)
- ActiveX(第三方控件控制器)(例如 Internet Explorer 控件)
- Custom(自定义控件)

## Text

描述: 包含用户不能编辑的无边界文本的区域. 常用来标识其他控件.

例如:

    Gui, Add, Text,, Please enter your name:

外观:

此时最后一个参数为要显示的字符串. 它可以包含换行符(`n) 来开始新行. 此外, 一个长行可以使用延续片段的方法分成较短的几行.

如果 Options 中指定了宽度(W) 而没有指定行数(R) 或高度(H), 那么在需要时文本将自动换行, 同时自动设置控件的高度.

因为控件的内容是 Gui 命令的最后一个参数, 所以可以直接使用逗号而需要转义. 对于其他所有命令的最后一个参数也是如此.

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户点击文本时 MySubroutine 标签会自动运行. 这可以用来模仿带下划线的蓝色超级链接, 如下面的可运行脚本所示:

    Gui, Font, underline
    Gui, Add, Text, cBlue gLaunchGoogle, Click here to launch Google.

    ; 或者可以使用 Link 控件:
    Gui, Add, Link,, Click <a href="www.google.com">here</a> to launch Google.
    Gui, Font, norm
    Gui, Show
    return

    LaunchGoogle:
    Run www.google.com
    return

通过检查 A_GuiEvent 是否包含单词 DoubleClick 可以检测到双击事件.

在文本中使用和符号(&) 可以让其中的某个字母带下划线显示. 例如:

    Gui, Add, Text,, &First Name:
    Gui, Add, Edit

在上述示例中, 字母 F 将被添加下划线, 这允许用户按下快捷键 `Alt`+`F` 将键盘焦点设置到此文本控件后添加的首个可输入型控件中. 要显示一个原义的和符号, 请指定两个连续的和符号(&&). 要取消控件中和符号的特殊含义, 请在控件的选项中包含 0x80.

请参阅常规选项来了解其他选项(例如 Right, Center 和 Hidden). 另请参阅: 控件的位置和大小.

## Edit

描述: 用户可以输入自由格式的文本区域.

例如:

    Gui, Add, Edit, r9 vMyEdit w135, Text to appear inside the edit control (omit this parameter to start off empty).

外观:

如果控件中有多行的文本, 则它将为多行的. 例如, 在 选项 中指定 `r3` 将创建一个拥有后面那些默认属性的 3 行编辑控件: 一个垂直滚动条, 启用自动换行并且捕获的 `Enter` 作为输入的一部分而不触发窗口的默认按钮.

要在多行编辑控件中开始新行, 请在最后一个参数中(内容) 包含单独的换行符(`n) 或回车换行符(`r`n). 这两种方法都会在 Edit 控件中产生原义的 `r`n 对. 然而, 当控件通过 Gui Submit 或 GuiControlGet 把内容保存到其变量时, 文本中的每对 `r`n 总是被转换成单独的换行符(`n). 要把文本写入到文件中, 请参照此例: `FileAppend, %MyEdit%, C:\Saved File.txt`.

如果控件启用了自动换行(对于多行编辑控件默认是启用的), 那么用户输入时任何自动换行的地方不会产生换行字符(仅 `Enter` 才会).

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户或脚本改变控件的内容时 MySubroutine 标签会自动运行.

提示: 要加载一个文本文件的内容到编辑控件中, 请使用 FileRead 和 GuiControl. 例如:

    Gui, Add, Edit, R20 vMyEdit
    FileRead, FileContents, C:\My File.txt
    GuiControl,, MyEdit, %FileContents%

### Edit 选项

要移除而非添加选项, 请在选项前加上负号:

Limit: 限制用户的输入在编辑区域的可见宽度内. 另外, 要限制输入指定数目的字符, 请在选项后跟着数字. 例如, `Limit10` 将允许输入不超过 10 个字符.

Lowercase: 把用户输入的字符自动转换成小写形式.

Multi: 让控件可以含有多行文本. 然而, 通常没必要指定此选项, 因为它会根据高度(H), 行数(R) 或内容(Text) 自动判断.

Number: 阻止用户输入数字以外的其他字符到编辑区域(然而, 还是可能粘贴非数字字符到里面). 强制输入数字的另一种方法是添加 UpDown 控件到 Edit 控件.

Password: 通过将用户的输入替代为屏蔽字符来隐藏用户的输入(例如密码). 如果想使用非默认的屏蔽字符, 请在单词 Password 后加上此符号. 例如, `Password*` 将使用星号而不是黑色圆(项目符号) 作为屏蔽符号, 这是 Windows XP 中的默认屏蔽符号. 注意: 此选项对于多行编辑控件没有效果.

ReadOnly: 阻止用户改变控件的内容. 不过, 仍然可以滚动, 选择文本或将文本复制到剪贴板.

Tn: 字母 T 可以用来设置多行编辑控件的制表位(因为制表位决定了原义的 TAB 字符跳转的列位置, 所以它们可以把文本格式成列). 如果没有使用字母 T, 则每 32 个对话框单位设置一次制表位(每个对话框单位的宽度由操作系统决定). 如果仅使用一次字母 T, 则每 n 个单位设置一次横跨整个控件宽度的制表位. 例如, `Gui, Add, Edit, vMyEdit r16 t64` 将设置制表位之间的距离为默认的两倍. 要自定义制表位, 请指定字母 T 多次, 例如: `Gui, Add, Edit, vMyEdit r16 t8 t16 t32 t64 t128`. 在列表中每个绝对的列位置设置一个制表位, 制表位数目最大可达 50 个. 注: 制表位仅用于多行编辑控件.

Uppercase: 把用户输入的字符自动转换成大写形式.

WantCtrlA [v1.0.44+]: 指定 `-WantCtrlA`(负 WantCtrlA) 阻止用户使用 `Ctrl`+`A` 来选择编辑控件中所有文本.

WantReturn: 指定 `-WantReturn`(负 WantReturn) 来阻止多行编辑控件捕获 `Enter`. 按下 `Enter` 相当于点击了窗口的默认按钮(如果有). 此时用户可以使用 `Ctrl`+`Enter` 来开始新行.

WantTab: 使得 `Tab` 产生制表符而不是导航到下一个控件. 如果没有这个选项, 则在多行编辑控件中用户可以按下 `Ctrl`+`Enter` 来产生制表符. 注意: WantTab 也可以用于单行编辑控件, 但在 Windows XP 和更低的系统中每个制表符显示为一个空框字符(不过实际保存的是真正的制表符).

Wrap: 指定 `-Wrap`(负 wrap) 来关闭多行编辑控件中的自动换行属性. 由于在控件创建后不能改变此样式, 所以需要使用下列方法的其中一个来改变它: 1) 销毁后重新创建窗口和其中的控件; 或 2) 创建两个重叠的编辑控件, 其中一个启用自动换行而另一个禁用. 当前没有使用的那个可以保持空的和/或隐藏.

请参阅常规选项来了解其他选项(例如 Right, Center 和 Hidden). 另请参阅: 控件的位置和大小.

更强大的编辑控件: HiEdit 是免费, 多选项卡, 支持大文件且消耗很少内存的编辑控件. 它可以编辑文本和二进制文件. 想了解详情和演示, 请参阅 HiEdit on GitHub.

## UpDown

描述: 一对箭头组成的按钮, 用户点击后会增加或减少值. 默认情况下, UpDown 控件自动依附于前一个添加的控件上. 这里的前一个控件被称为 UpDown 的 伙伴控件. 最常见的例子是 "微调器", UpDown 附加到 Edit 控件.

例如:

    Gui, Add, Edit
    Gui, Add, UpDown, vMyUpDown Range1-10, 5

外观:

在上面的例子中, Edit 控件是 UpDown 的伙伴控件. 每当用户按下了增减按钮的其中一个, Edit 控件中的数字会自动增加或减少.

UpDown 的伙伴控件也可以是 Text 控件或 ListBox. 然而, 由于操作系统的限制, 除了这些以外的其他控件类型(例如 ComboBox 和 DropDownList) 可能无法和 g-标签以及其他特性一起正常工作.

在最后一个参数中指定 UpDown 的初始位置(如果省略, 则初始为 0 或允许的范围中最接近 0 的数字).

使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到 UpDown 的当前的数字位置. 如果 UpDown 依附于编辑控件而且您不想确认用户的输入, 此时最好使用 UpDown 的值而不是编辑控件的. 这是因为 UpDown 总是产生一个允许范围内的数字, 即使用户在编辑控件中输入了非数字或超出范围的内容. 相关提示, 默认情况下超过三位的数字会添加千位分隔符(例如逗号). 这些分隔符保存在编辑控件的输出变量中, 但不在 UpDown 的变量中.

如果 UpDown 含有 g-标签, 则当用户点击增减按钮的其中一个或按下了键盘上的方向键时它将会运行. 每次运行 g-标签还会保存 UpDown 的位置到其关联输出变量(如果有).

### UpDown 选项

Horz(水平): 使控件的按钮点指向左/右而不是上/下. 默认情况下, Horz 还会让控件变成孤立的(没有伙伴控件). 通过在控件选项中指定 `Horz 16` 可以覆盖此特性.

Left: 把 UpDown 放在其伙伴控件的左边而不是右边.

Range: 使用 0 到 100 外的其他范围. 在单词 Range 后指定最小值, 破折号和最大值. 例如, `Range1-1000` 将允许选择一个介于 1 和 1000 之间的数字; `Range-50-50` 将允许介于 -50 和 50 之间的数字; 而 `Range-10--5` 将允许介于 -10 和 -5 之间的数字. 交换最小值和最大值可以让箭头往与正常方向相反的方向移动. 最大的允许范围是 -2147483648-2147483647. 最后, 如果伙伴控件为 ListBox, 那么垂直的默认范围是 32767-0, 而水平的则反向(Horz).

Wrap: 当用户试图超出最小值或最大值时使得控件返回到其范围的另一端. 如果没有 Wrap, 当达到最小值或最大值时控件会停止.

-16(负 16): 让垂直的 UpDown 成为孤立的; 即让它没有伙伴控件. 这还可以让控件符合任何指定的宽度, 高度和位置而不是适应于其伙伴控件的大小. 此外, 孤立的 UpDown 会内部跟踪它自己的位置. 使用 Gui Submit 可以正常获取此位置.

0x80: 在 选项 中包含 `0x80` 来省略伙伴控件中正常出现在每三位十进制数间的千位分隔符. 然而, 通常不使用此样式, 因为当脚本从 UpDown 控件(而不是其伙伴控件) 获取的数字中不包含分隔符.

使用 1 以外的其他增量: 在此脚本中, NumEric 演示了如何改变 UpDown 增量为 1 以外的其他值(例如 5 或 0.1).

十六进制数字格式: 在伙伴控件中显示的数字格式可以通过以下示例从十进制改为十六进制:

    Gui +LastFound
    SendMessage, 0x046D, 16, 0, msctls_updown321 ; 0x046D 是 UDM_SETBASE

但是, 这只影响伙伴控件, 而不影响 UpDown 报告的位置.

另请参阅: 控件的位置和大小.

## Picture(或 Pic)

描述: 包含图像的区域(请参阅最后两段来了解支持的文件类型). 最后一个参数是图像的文件名, 如果未指定绝对路径, 则假定在 A_WorkingDir 中.

例如:

    Gui, Add, Picture, w300 h-1, C:\My Pictures\Company Logo.gif

要保持图像的实际宽度和/或高度, 请省略 W 和/或 H 选项. 否则, 缩放图像的尺寸到指定的宽度和/或高度(此宽度和高度也决定了从多图标的 .ICO 文件中加载哪个图标). 要保持高宽比来缩放图像, 请在其中一个尺寸中指定 -1 而在另一个中指定正数. 例如, 指定 `w200 h-1` 将缩放图像到 200 像素的宽度同时自动设置其高度. 如果图片无法加载或显示(例如找不到文件), 则控件被留空且设置其宽度和高度为零.

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户点击图片时 MySubroutine 标签会自动运行. 通过检查 A_GuiEvent 是否包含单词 DoubleClick 可以检测到双击事件.

要使用图片作为其他控件的背景, 则应该在其他控件之前正常添加图片. 然而, 如果这些控件是可输入型且此图片控件含有 g-标签, 那么在其他控件后创建图片控件并在其 选项 中包含 `0x4000000`(这是 WS_CLIPSIBLINGS). 使用此技巧还可以把一个图片设为 Tab 控件或 ListView 的背景.

图标, 光标和动画光标: 图标和光标可以从下列类型的文件中加载: ICO, CUR, ANI, EXE, DLL, CPL, SCR 以及包含图标资源的其他类型. 要使用文件中的图标组而不是首个图标, 请在 选项 包含单词 Icon 和图标组编号. 在下面的例子中, 将使用第二个图标组中的默认图标: `Gui, Add, Picture, Icon2, C:\My Application.exe`.

在 选项 中指定单词 AltSubmit 会让程序使用微软的 GDIPlus.dll 来加载图像, 这可能让 GIF, BMP 和图标图像产生不同的外观. 例如, 它可以把含透明背景的 ICO/GIF 作为透明的位图进行加载, 这样允许 BackgroundTrans 选项才生效(不过从 [v1.1.23+] 开始, 透明图标可以不设置 AltSubmit 选项). 如果 GDIPlus 不可用(请参阅下个段落), 则 AltSubmit 选项会被忽略而使用常规方法加载图像.

在所有的操作系统中都支持 GIF, JPG, BMP, ICO, CUR 和 ANI 图像. 在 Windows XP 或更高版本中, 还支持其他图像格式, 例如 PNG, TIF, Exif, WMF 和 EMF. 比 XP 早的操作系统可以通过复制微软免费的 GDI+ DLL 到 AutoHotkey.exe 文件夹中来提供支持(但如果是已编译脚本, 则复制此 DLL 到脚本的文件夹). 要下载这个 DLL, 请在 www.microsoft.com 搜索下列短语: gdi redistributable

动态 GIF: 虽然 GIF 动画文件可以显示在图片控件中, 但实际上它们并不会动起来. 要解决此问题, 请使用 AniGIF DLL(对非商业用途免费), 演示的例子请参阅 Autohotkey 论坛. [v1.1.03+]: 此外, 可以使用 ActiveX 控件类型. 例如:

    ; 指定下面的路径到 GIF 文件以实现动态效果(也允许使用本地文件):
    pic := "http://www.animatedgif.net/cartoons/A_5odie_e0.gif"
    Gui, Add, ActiveX, w100 h150, % "mshtml:<img src='" pic "' />"
    Gui, Show

[v1.1.23+]: 位图或图标的句柄可完全替代文件名使用. 例如, `HBITMAP:%handle%`.

## Button

描述: 按下后可以触发动作的按钮. 此时最后一个参数为按钮的名称(显示在按钮上), 其中可以包含换行符(`n) 来开始新行.

例如:

    Gui, Add, Button, Default w80, OK

外观:

上面的例子在其 选项 中包含单词 Default 来让 "OK" 成为默认按钮. 每当用户按下 `Enter` 时会自动触发默认按钮的动作, 除非此时键盘焦点在另一个按钮上或含有 WantReturn 样式的多行编辑控件中. 以后要改变默认按钮为另一个按钮, 请参照此例, 这里让 Cancel 按钮成为默认按钮: `GuiControl, +default, Cancel`. 以后要让窗口没有默认按钮, 请参照此例: `GuiControl, -default, OK`.

在按钮名称中使用和符号(&) 可以让其中的某个字母带下划线显示. 例如:

    Gui, Add, Button,, &Pause

在上述示例中, 字母 P 将被添加下划线, 这允许用户按下 `Alt`+`P` 作为其快捷键. 要显示一个原义的和符号, 请指定两个连续的和符号(&&).

如果一个按钮没有明确的 g-标签, 则使用自动标签. 例如, 如果首个 GUI 窗口包含一个 OK 按钮, 则当按下此按钮时将运行 ButtonOK 标签(如果存在). 对于非首个 GUI 窗口, 则需要在按钮的自动标签前加上窗口编号; 例如: `2ButtonOK`.

如果按钮上的文本包含空格或 &`r`n`t` 集合中的任意一个字符, 则在其自动标签中会删去这些字符. 例如, 名为 "&Pause" 的按钮其自动标签的名称将为 ButtonPause. 同样地, 名为 "Save && Exit" 的按钮其自动标签的名称将为 ButtonSaveExit(两个连续的和符号用来显示单个原义的和符号).

已知限制: 某些桌面主题可能无法正确的显示按钮文本. 如果遇到此情况, 请尝试在控件的选项中包含 `-Wrap`(负 Wrap). 不过这样也使得按钮名称中无法包含多行文本.

## Checkbox

描述: 一个小方框, 可以选中或取消选中来表示 On/Off, Yes/No, 等等.

例如:

    Gui, Add, CheckBox, vShipToBillingAddress, Ship to billing address?

外观:

最后一个参数是紧跟着方框显示的标注, 这通常是关于复选框用途的提示或描述. 它可以包含换行符(`n) 来开始新行. 如果 选项 中指定了宽度(W) 而没有指定行数(R) 或高度(H), 那么在需要时控件的文本将自动换行, 同时自动设置控件的高度. 在选中时复选框的关联输出变量(如果有) 接收到数字 1, 未选中时为 0, 而灰色不确定时为 -1.

在 选项 中指定单词 Check3 来启用第三种状态即显示灰色的选择标记而不是黑色的(灰色状态表示复选框既不处于选中状态也不处于未选中状态). 在 选项 中指定单词 Checked 或 CheckedGray 可以让复选框初始状态分别为黑色选中状态或灰色状态. 单词 Checked 后面可以紧跟着 0, 1 或 -1 来表示初始状态. 换句话说, `Checked` 和 `Checked%VarContainingOne%` 是一样的.

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户点击或改变复选框时 MySubroutine 标签会自动运行.

已知限制: 某些桌面主题可能无法正确的显示 Checkbox 的文本. 如果遇到此情况, 请尝试在控件的选项中包含 `-Wrap`(负 Wrap). 不过这样也使得按钮名称中无法包含多行文本.

## Radio

描述: 单选按钮是一个小空圆, 可以被选中(打开) 或不选中(关闭).

例如:

    Gui, Add, Radio, vMyRadioGroup, Wait for all items to be in stock before shipping.

外观:

此控件经常出现在 单选按钮组, 每组包含两个或多个单选按钮. 当用户点击一个单选按钮来打开它时, 其所在的单选按钮组中其他所有的单选按钮会自动关闭(在单选按钮组中用户也可以使用方向键导航). 在所有连续添加的单选按钮周围会自动创建一个单选按钮组. 要开始一个新组, 请在新组的首个单选按钮的 选项 中指定单词 Group, 或者在新组和之前的组之间简单地添加一个非单选按钮控件, 因为这样会自动开始一个新组.

在最后一个参数中指定的标注会显示在单选按钮的右侧. 此标注通常作为提示或描述, 它可以包含换行符(`n) 来开始新行. 如果在 选项 中指定了宽度(W) 而没有指定行数(R) 或高度(H), 那么在需要时控件的文本将自动换行, 同时自动设置控件的高度.

在 选项 中指定单词 Checked 来让按钮初始为选中状态. 可以在单词 Checked 后紧跟着 0 或 1 来表示初始状态: 0 表示未选中, 而 1 表示选中. 换句话说, `Checked` 和 `Checked%VarContainingOne%` 是一样的.

选中时单选按钮的关联输出变量(如果有) 接收到数字 1 而未选中时为 0. 但是, 如果单选组中仅有一个按钮含有关联变量, 则此变量将接收当前选择按钮的编号: 首个单选按钮为 1(根据原来的创建顺序), 第二个为 2, 依此类推. 如果没有选择的按钮, 则保存 0.

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户选中按钮时 MySubroutine 标签会自动运行. 与之前段落中的单变量模式不同, 这里必须为单选按钮组中每个按钮指定 g-标签, 这样选中某个按钮时相应的标签才会运行. 这样可以灵活地忽略某些按钮的点击. 最后, 通过检查 A_GuiEvent 是否包含单词 DoubleClick 可以检测到双击事件.

已知限制: 某些桌面主题可能无法正确的显示单选按钮的文本. 如果遇到此情况, 请尝试在控件的选项中包含 `-Wrap`(负 Wrap). 不过这样也使得按钮名称中无法包含多行文本.

## DropDownList(或 DDL)

描述: 当按下一个小按钮时显示的选择列表. 此时, 最后一个参数是管道分隔的选择列表, 例如 `Choice1|Choice2|Choice3`.

例如:

    Gui, Add, DropDownList, vColorChoice, Black|White|Red|Green|Blue

外观:

要在窗口初次出现时预选其中的某项, 请在此项后包含两个管道符(例如 `Red|Green||Blue`). 或者, 在 选项 中包含单词 Choose 紧跟着想预选的项目的编号. 例如, `Choose5` 会预选第五项(和其他选项一样, 它也可以为变量, 例如 `Choose%Var%`). 要在控件创建后改变选择或添加/移除列表中的条目, 请使用 GuiControl.

在 选项 中指定单词 Uppercase 或 Lowercase 来把列表中的所有项目自动转换成大写字母或小写字母. 指定单词 Sort 来按字母顺序自动排列列表的内容(这也会影响后面通过 GuiControl 添加的所有项目). Sort 选项还会启用在弹出下拉列表时的增量搜索; 这使得可以通过输入一个项目名称的前几个字符来选择此项.

当使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到当前选择项目的文本. 但是, 如果控件含有 AltSubmit 属性, 则输出变量将接收到项目的位置编号(首个项目为 1, 第二个为 2, 等等.).

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户选择新项目时 MySubroutine 标签会自动运行.

使用 R 或 H 选项来控制弹出列表的高度. 例如, 指定 `R5` 会设置列表为 5 行高, 而 `H400` 会设置选区字段和列表的总高度为 400 像素. 如果同时省略 R 和 H 选项, 则列表会自动扩展到用户桌面的可用高度(但是在早于 Windows XP 的操作系统中默认会显示 3 行).

要设置选区字段或列表项的高度, 请使用 CB_SETITEMHEIGHT 消息, 示例如下:

    Gui Add, DDL, vcbx w200 hwndhcbx, One||Two
    ; CB_SETITEMHEIGHT = 0x0153
    PostMessage, 0x0153, -1, 50,, ahk_id %hcbx%  ; 设置选区字段的高度.
    PostMessage, 0x0153,  0, 50,, ahk_id %hcbx%  ; 设置列表项的高度.
    Gui Show, h70, Test

字段间的分隔符可以改变为管道符(|) 外的其他字符. 例如 `Gui +Delimiter`n` 将改变分隔符为换行符而 `Gui +DelimiterTab` 将改变为 tab(`t).

## ComboBox

描述: 和 DropDownList 一样, 不过还允许输入自由格式的文本作为列表中可选的项目.

例如:

    Gui, Add, ComboBox, vColorChoice, Red|Green|Blue|Black|White

外观:

除了可以使用上面描述的所有 DropDownList 选项外, 选项 中还可以包含单词 Limit 来限制用户的输入在 ComboBox 编辑区域的可见宽度内. 此外, 可以指定单词 Simple 来让 ComboBox 表现的像一个下方带有 ListBox 的 Edit 区域.

当使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到当前选择项目的文本. 但是, 如果控件含有 AltSubmit 属性, 则输出变量将接收到项目的位置编号(首个项目为 1, 第二个为 2, 等等.). 在这两种情况中, 如果没有选择的项目, 则输出变量将被设置为 ComboBox 编辑区域的内容.

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户选择新项目时 MySubroutine 标签会自动运行.

## ListBox

描述: 一个包含选择列表的较高的框. 此时, 最后一个参数是管道分隔的选择列表, 例如 `Choice1|Choice2|Choice3`.

例如:

    Gui, Add, ListBox, vColorChoice, Red|Green|Blue|Black|White

外观:

要在窗口初次出现时预选其中的某个或某些项目, 请在这些项目中的每个后面包含两个管道符(如果要预选多个项目, 则需要 Multi 选项). 或者, 在 选项 中包含单词 Choose 紧接着预选的项目的编号. 例如, `Choose5` 会预选第五项. 要在控件创建后改变选择或添加/移除列表中的条目, 请使用 GuiControl.

当使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到当前选择项目的文本. 但是, 如果控件含有 AltSubmit 属性, 则输出变量将接收到项目的位置编号(首个项目为 1, 第二个为 2, 等等).

g-标签例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户选择新项目时 MySubroutine 标签会自动运行. 如果用户双击一个项目, 则内置变量 A_GuiEvent 会包含字符串 DoubleClick 而不是 Normal. 此外, 变量 A_EventInfo 将包含被双击项目的位置(首个项目为 1, 第二个为 2, 等等).

当添加大量项目到 ListBox 时, 在操作前使用 `GuiControl, -Redraw, MyListBox` 并且在操作后使用 `GuiControl, +Redraw, MyListBox` 也许会提高性能.

### ListBox 选项

Choose: 请参阅上面.

Multi: 允许使用 shift-click 和 control-click 同时选择多个项目(如果不希望使用 shift/control-click, 请指定数字 8 代替单词 Multi). 此时, Gui Submit 会保存管道分隔的项目字符串列表到控件的输出变量. 不过, 如果存在 AltSubmit 选项, 则 Gui Submit 保存管道分隔的项目编号列表. 例如, `1|2|3` 表示选择了前三个项目. 要提取每个项目, 请使用解析循环, 例如:

    Loop, Parse, MyListBox, |
    {
        MsgBox Selection number %A_Index% is %A_LoopField%.
    }

字段间的分隔符可以改变为管道符(|) 外的其他字符. 例如 `Gui +Delimiter`n` 将改变分隔符为换行符而 `Gui +DelimiterTab` 将改变为 tab(`t).

ReadOnly: 对选择的项目不进行高亮显示(但 Gui Submit 仍会保存选择的项目).

Sort: 按字母顺序自动排列列表的内容(这也会影响后面通过 GuiControl 添加的所有项目). Sort 选项还会启用增量搜索; 这使得可以通过输入一个项目名称的前几个字符来选择此项.

Tn: 字母 T 可以用来设置制表位, 它可以把文本格式成列. 如果没有使用字母 T, 则每 32 个对话框单位设置一次制表位(每个对话框单位的宽度由操作系统决定). 如果仅使用一次字母 T, 则每 n 个单位设置一次横跨整个控件宽度的制表位. 例如, `Gui, Add, ListBox, vMyListBox t64` 将设置制表位之间的距离为默认的两倍. 要自定义制表位, 请指定字母 T 多次, 例如: `Gui, Add, ListBox, vMyListBox t8 t16 t32 t64 t128`. 在列表中每个绝对的列位置设置一个制表位, 制表位数目最大可达 50 个.

0x100: 在 选项 中包含 0x100 来打开 LBS_NOINTEGRALHEIGHT 样式. 此选项强制 ListBox 准确符合指定的高度而不是适应于避免在底部的行只显示一部分的高度. 此选项也避免了其字体改变时 ListBox 缩小的情况.

要指定文本的行数(或高度和宽度), 请参阅控件的位置和大小.

## ListView 和 TreeView

请参阅 ListView 和 TreeView 的单独页面.

## Link [v1.1.06+]

描述: 一个包含可点击链接的文本控件. 链接控件使用类似 HTML 的标记语法, 但只支持 <A> 标签. 在开标签内, 可以以 `href="value"` 或 `id="value"` 指定属性.

例如:

    Gui, Add, Link,, This is a <a href="https://www.autohotkey.com">link</a>
    Gui, Add, Link,, Links may be used anywhere in the text like <a id="A">this</a> or <a id="B">that</a>

外观:

如果设置了 href 属性, 并包含一个有效的可执行的命令或 URL, 则它的执行就像是通过 Run 命令执行一样. 但是, 可执行命令不能包含双引号. URL 通常可以包含百分号的字符, 如 ``%22`, 但这些都是由用户的 Web 浏览器解释的, 而不是链接控件.

如果控件有 g-标签, 比如 `gMySubroutine`, 点击链接子程序将被启动, 无论链接有没有 href 属性, 或者命令或 URL 执行失败. 这个子程序可以参考以下变量:

- A_GuiEvent 包含的事件类型; 目前总是单词 "Normal".
- A_EventInfo 包含链接的一维索引.
- ErrorLevel 包含的链接 href 属性的值, 如果有的话; 否则, 链接的 id 属性的值或空字符串.

如果 g-标签是一个函数, 它可以接受以下参数:

    MyFunction(CtrlHwnd, GuiEvent, LinkIndex, HrefOrID)

## Hotkey

描述: 一个看起来像单行编辑控件的框, 但它接受用户按下的按键组合. 例如, 在英语键盘布局的系统中如果用户按下 `Ctrl`+`Alt`+`C`, 那么此框中将显示 "Ctrl + Alt + C".

例如:

    Gui, Add, Hotkey, vChosenHotkey

外观:

使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到热键修饰符和按键名称, 它们与 Hotkey 命令中的按键名称是一致的. 例如: `^!C`, `+!Home`, `+^Down`, `^Numpad1`, `!NumpadEnd`. 如果控件中没有热键, 则输出变量被置空.

注意: 一些按键即使它们作为不同的名称获取也显示为相同的名称. 例如, `^Numpad7` 和 `^NumpadHome` 都可能显示为 Ctrl + Num 7.

默认情况下, 控件在初始时不含有热键. 要让控件含有默认的热键, 请在最后一个参数中指定热键修饰符和按键名称, 例如: `Gui, Add, Hotkey, vChosenHotkey, ^!p`. 支持的修饰符仅包含 ^(Control), !(Alt) 和 +(Shift). 请参阅按键列表了解可用的按键名称.

g-标签, 例如 `gMySubroutine` 可以使用在此控件的选项中. 这使得当用户改变热键时 MySubroutine 标签会自动运行. 每次运行 g-标签还会保存热键到控件的关联输出变量(如果有).

注意: 即使控件中存在不完整的热键时 g-标签也会运行. 例如, 如果用户按住 `Ctrl`, 则 g-标签会运行一次, 此时输出变量仅包含抑扬符(^). 当用户按完热键后, g-标签会再次运行, 此时输出变量包含完整的热键.

要限制用户可以使用的热键类型, 请在选项中包含单词 Limit 接着一个或多个下列数字的和:

- 1: 阻止不含修饰符的键
- 2: 阻止修饰符仅含 `Shift` 的键
- 4: 阻止修饰符仅含 `Ctrl` 的键
- 8: 阻止修饰符仅含 `Alt` 的键
- 16: 阻止修饰符含 `Shift`+`Ctrl` 的键
- 32: 阻止修饰符含 `Shift`+`Alt` 的键
- 64: 不支持这个值(它不会正确执行).
- 128: 阻止修饰符含 `Shift`+`Ctrl`+`Alt` 的键.

例如, `Limit1` 将阻止输入不含修饰符的热键(例如字母和数字), 而 `Limit15` 则要求至少有两个修饰键. 如果用户输入了被禁止的修饰键组合, 则自动使用 `Ctrl`+`Alt` 组合代替.

Hotkey 控件对热键的支持有限. 例如, 它不支持鼠标/游戏杆热键或 `Win`(LWin 和 RWin). 解决此问题的一种方法是提供一个或多个 checkbox 作为用户启用额外的修饰键(例如 `Win`) 的工具.

## DateTime

描述: 一个看起来像单行编辑控件的框, 不过它接受日期和/或时间. 同时提供下拉日历.

例如:

    Gui, Add, DateTime, vMyDateTime, LongDate

外观:

最后一个参数可以为下列的其中一个:

(省略): 省略时, 使用区域设置的短日期格式. 例如, 在某些区域设置中它看起来像这样: 6/1/2005

LongDate: 使用区域设置的长日期格式. 例如, 在某些区域设置中它看起来像这样: Wednesday, June 01, 2005

Time: 仅显示时间, 使用区域设置的时间格式. 尽管不显示日期, 但它仍然存在于控件中并且与 YYYYMMDDHH24MISS 格式的时间一起被获取. 例如, 在某些区域它看起来像这样: 9:37:45 PM

(自定义格式): 指定日期和时间格式的任意组合. 例如, `M/d/yy HH:mm` 格式显示的时间看起来像 6/1/05 21:37. 同样, `dddd MMMM d, yyyy hh:mm:ss tt` 格式显示的时间看起来像 Wednesday June 1, 2005 09:37:45 PM. 想要原义显示的字母和数字应该括在一对单引号中, 例如: `'Date:' MM/dd/yy 'Time:' hh:mm:ss tt`. 与之相比, 非字母数字字符(例如空格, tab, 斜杠, 冒号, 逗号和其他标点) 不需要包围在单引号中. 例外情况是单引号字符本身: 要产生原义的单引号, 请使用四个连续的单引号(''''), 不过如果它们已经包含在一对外部引号中则仅使用连续的两个就行了.

### DateTime 用法

要预选今天外的其他日期, 请在 选项 中包含单词 Choose 紧跟着 YYYYMMDD 格式的日期. 例如, `Choose20050531` 将预选 May 31, 2005(和其他选项一样, 它还可以为变量, 例如 `Choose%Var%`). 要不预选日期/时间, 请指定 ChooseNone. ChooseNone 还会在控件中创建一个复选框, 只要控件中不含日期则此复选框为未选中状态. 当控件中没有选择日期时, Gui Submit 和 GuiControlGet 会获取到空值(空字符串).

日期的时间部分是可选的. 但是, 当进入或离开控件时, 时间部分必须总是在日期之前. 时间部分的格式为 HH24MISS(小时数, 分钟数, 秒数), 其中 HH24 含义是用 24 小时格式表示; 例如, 09 为 9am, 而 21 为 9pm. 因此, 完整的日期时间字符串的格式应为 YYYYMMDDHH24MISS.

当指定了 YYYYMMDDHH24MISS 格式的日期时, 只有前导部分是不能缺少的. 其他任何省略的元素将使用下列默认值代替: MM: 月份 01, DD: 日期 01, HH24: 小时 00, MI: 分钟 00, SS: 秒 00.

在下拉日历中, 可以点击底部的今日字符串来选择今天的日期. 此外, 还可以点击年份和月份名称来方便地导航到新的月份或年份.

使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到所选择的 YYYYMMDDHH24MISS 格式表示的日期和时间. 日期和时间都存在, 不论它们在控件中实际是否可见.

如果控件含有 g-标签, 则当用户改变日期或时间时此标签会运行. 每次运行时, 控件的关联输出变量(如果有) 会自动更新为当前选择的日期/时间.

### DateTime 选项

Choose: 请参阅上面.

Range: 限制可以选择的日期范围. 在单词 Range 后指定以 YYYYMMDD 格式表示的最小和最大的日期(它们之间使用破折号连接). 例如, `Range20050101-20050615` 将限制可选择的日期为 5.5 年的前 5 个半月. 最小或最大的日期可以省略, 此时控件中在这个方向上的日期不受限制. 例如, `Range20010101` 将禁止选择早于 2001 年的日期而 `Range-20091231`(有前导的破折号) 将禁止选择迟于 2009 年的日期. 如果不含 Range 选项, 则可以选择介于 1601 和 9999 年份之间的任何日期. 无法限制日期的时间部分.

Right: 让下拉日历在控件的右边而不是左边拉下.

1: 在 选项 中指定数字 1 会在此控件的右边提供一个增减控件来修改日期和时间的值, 这会取代其他地方可用的下拉月历的修改按钮. 这不能和上面所述的 LongDate 格式选项联用.

2: 在 选项 中指定数字 2 在控件中提供复选框, 用户可以取消此复选框选择来表示没有选择日期/时间. 控件创建后无法改变此选项.

下拉式日历内的颜色: 下拉式日历中天数的颜色由 Gui Font 命令或 c(Color) 选项设置. 要改变日历其他部分的颜色, 如下例所示:

    Gui +LastFound
    SendMessage, 0x1006, 4, 0xFFAA99, SysDateTimePick321 ; 0x1006 为 DTM_SETMCCOLOR. 4 为 MCSC_MONTHBK(背景颜色). 颜色必须以 BGR 格式指定, 而不是 RGB 格式(红蓝分量互换).

## MonthCal

描述: 一个又高又宽的控件, 其中以日历的格式显示一个月中的所有日子. 用户可以选择单个日期或日期范围.

例如:

    Gui, Add, MonthCal, vMyCalendar

外观:

要预选今天外的其他日期, 请在最后一个参数中指定 YYYYMMDD 格式的日期(例如 `20050531`). 通过在两个日期间包含破折号可以预选一个日期范围(例如 `20050525-20050531`).

通常最好忽略 MonthCal 的宽度(W) 和高度(H), 这样它会自动调整大小来准确适应一个月份. 要垂直地显示多个月份, 请在 选项 中指定 `R2` 或更高. 要水平地显示多个月份, 请指定 `W-2`(W 负 2) 或更高. 这两个选项可以同时出现, 此时会在两个方向上扩展.

可以点击控件底部的今日字符串来选择今天的日期. 此外, 还可以点击年份和月份名称来方便地选择新的月份或年份.

键盘导航: 在 Windows Vista 及以后版本中, 在 MonthCal 中完全支持键盘导航, 但只有当它具有键盘焦点时才支持. 有关支持的键盘快捷方式, 请参阅DateTime 的键盘导航(带有下拉日历).

使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到所选择的 YYYYMMDD 格式表示的日期(不带任何时间部分). 但是, 存在多选选项时, 会得到以破折号连接的最小和最大日期(例如 `20050101-20050108`). 在可以多选的日历中如果仅选择单个日期, 则最小和最大日期都会存在但它们是相同的. 可以使用 StrSplit() 或 StringSplit 把两个日期分离开来. 例如, 后面的命令将把最小日期保存在 Date1 而最大日期保存在 Date2: `StringSplit, Date, MyMonthCal, -`.

如果 MonthCal 含有g-标签, 则它每次运行时会更新控件的关联输出变量(如果有) 为当前选择的日期或范围. 默认情况下, 只有当用户更改选择时才会启动标签. 在 Windows XP 和更早的版本中, 由于操作系统的怪癖, 每隔两分钟也会启动标签, 以应对新的一天已经到来这种情况. 但是, 如果控件的 选项 中包含单词 AltSubmit, 则 g-标签会运行地更频繁, 而内置变量 A_GuiEvent 在改变日期时包含单词 Normal, 点击一个日期时包含数字 1, 而当 MonthCal 释放 "鼠标捕获" 时包含数字 2. 例如, 如果用户双击一个新日期, 则标签会运行五次: 其中一次为 Normal, 两次为 1, 还有两次为 2. 通过计算两次数字 1 实例之间的时间间隔可以检测双击.

指定 YYYYMMDD 格式的日期时, MM 和/或 DD 部分可以省略, 此时它们默认为 1. 例如, `200205` 被视为 20020501, 而 `2005` 被视为 20050101.

### MonthCal 选项

Multi: 多选. 允许用户使用 shift-click 或 click-drag 来选择一个连续的日期范围(此时用户仍然可以选择单个日期). 可以明确指定此选项或在创建控件时通过指定一个选择范围的方法来让此选项自动生效. 例如: `Gui, Add, MonthCal, vMyCal, 20050101-20050108`. 控件创建后无法改变此选项.

Range: 限制日历中可以选择的时间范围. 在单词 Range 后指定以 YYYYMMDD 格式表示的最小和最大的日期(它们之间使用破折号连接). 例如, `Range20050101-20050615` 将限制选区为 2005 年的前 5 个半月. 最小或最大的日期可以省略, 此时日历中在这个方向上的日期不受限制. 例如, `Range20010101` 将禁止选择早于 2001 年的日期而 `Range-20091231`(有前导的破折号) 将禁止选择迟于 2009 年的日期. 如果不含 Range 选项, 则可以选择介于 1601 和 9999 年份之间的任何日期.

4: 在 选项 中指定数字 4 来在每行日期的左边显示周数(1-52). Week 1 被定义为至少包含四天的第一周.

8: 在 选项 中指定数字 8 来禁止控件中当前日期往复循环.

16: 在 选项 中指定数字 16 来禁止在控件的底部显示今天的日期.

Colors: 日历中天数的颜色由 Gui Font 命令或 c(Color) 选项设置. 要改变日历其他部分的颜色, 如下例所示:

    Gui +LastFound
    SendMessage, 0x100A, 5, 0xFFAA99, SysMonthCal321 ; 0x100A 为 MCM_SETCOLOR. 5 为 MCSC_TITLETEXT(标题文本颜色). 颜色必须以 BGR 格式指定, 而不是 RGB 格式(红蓝分量互换).

## Slider

描述: 用户可以沿着垂直或水平轨道移动的滑动条. 在任务栏托盘中的标准音量控件就是滑动条的一个例子.

例如:

    Gui, Add, Slider, vMySlider, 50

外观:

请在最后一个参数中指定滑动条的初始位置. 如果省略最后一个参数, 则滑动条初始位置为 0 或允许的范围中最接近 0 的数字.

用户可以通过下列方法滑动控件: 1) 使用鼠标拖拉滑动条; 2) 用鼠标在滑动条的轨道区域点击; 3) 当焦点在控件上时转动鼠标滚轮; 或 4) 当焦点在控件上时使用下列按键: `↑`, `→`, `↓`, `←`, `PgUp`, `PgDn`, `Home` 和 `End`.

使用 Gui Submit 命令后, 控件的关联输出变量(如果有) 会接收到滑动条当前的数字位置. 每当控件的 g-标签运行时也会将此位置保存到输出变量中.

如果滑动条含有 g-标签, 默认情况下仅当用户停止移动滑块时它才运行(例如在拖拉滑块后释放了鼠标按钮). 但是, 如果控件的 选项 中包含单词 AltSubmit, 则所有滑动条事件发生时 g-标签都会运行, 同时内置变量 A_GuiEvent 将包含下列数字或字符串的其中一个:

- 0: 用户按下了 `←` 或 `↑` 方向键.
- 1: 用户按下了 `→` 或 `↓` 方向键.
- 2: 用户按下了 `PgUp`.
- 3: 用户按下了 `PgDn`.
- 4: 用户用鼠标滚轮移动了滑块或已经把滑块拖放到新的位置.
- 5: 用户正用鼠标拖动滑块, 即鼠标按钮当前是按住的.
- 6: 用户按下了 `Home` 键来移动滑块到左端或顶部.
- 7: 用户按下了 `End` 来移动滑块到右端或底部.
- Normal: 用户已经使用鼠标或键盘移动了滑块. 注意: 除了鼠标滚轮移动(#4) 之外, g-标签将再次为 "normal" 事件启动, 即使它已经由上面的某个数字-事件启动过一次.

### Slider 选项

Buddy1 和 Buddy2: 最多可以指定两个现有的控件来自动定位到滑动条的两侧. Buddy1 显示在左边或顶部(取决于是否存在 Vertical 选项). Buddy2 显示在右侧或底部. 在单词 Buddy1 或 Buddy2 后指定现有控件的变量名. 例如, `Buddy1MyTopText` 将分配变量名为 MyTopText 的控件.

Center: 滑块(用户移动的滑动条) 两端将是钝的, 而不是指向一端(尖的).

Invert: 反转控件, 把较低值作为右边/底端而不是左边/顶端. 此选项常用来让垂直滑动条在传统的音量控件方向上移动. 注: 下面描述的工具提示选项不会遵循反转, 因此不应该在这种情况下使用.

Left: 滑块(用户移动的滑动条) 将指向上方而不是下方(原文中为顶端和底端, 这里用上/下放是为了避免和滑动条的顶端/底端混淆). 但如果存在 Vertical(垂直) 选项, 则滑块将指向左边而不是右边.

Line: 指定当用户按下其中一个方向键时要移动的位置数. 在单词 Line 后指定移动的位置数. 例如: `Line2`.

NoTicks: 不在轨道旁边显示刻度标记.

Page: 指定当用户按下 `PgUp` 或 `PgDn` 时移动的位置数. 在单词 Page 后指定移动的位置数. 例如: `Page10`.

Range: 使用 0 到 100 外的其他范围. 在单词 Range 后指定最小值, 破折号和最大值. 例如, `Range1-1000` 将允许选择一个介于 1 和 1000 之间的数字; `Range-50-50` 将允许介于 -50 和 50 之间的数字; 而 `Range-10--10` 将允许介于 -10 和 -5 之间的数字.

Thick: 指定滑块的长度. 在单词 Thick 后指定以像素为单位的厚度(例如 `Thick30`). 在 Windows XP 或更高版本中, 要超过一定的厚度可能需要指定 Center 选项或移除控件的主题(通过在控件的选项中指定 `-Theme` 来实现).

TickInterval: 在轨道旁边指定间隔的位置显示刻度标记. 在单词 TickInterval 后指定间隔来显示附加的刻度标记(如果省略从未设置, 则默认为 1). 例如, `TickInterval10` 将每隔 10 位置显示一个刻度标记.

ToolTip: 创建工具提示, 当用户拖动滑动条时显示它的数字位置. 要让工具提示不显示在默认位置, 请指定下列单词的其中一个代替: `ToolTipLeft` 或 `ToolTipRight`(对于水平滑动条); `ToolTipTop` 或 `ToolTipBottom`(对于垂直滚动条).

Vertical: 让控件上下滑动而不是左右滑动.

在控件创建后可以使用 GuiControl 改变上面的选项.

## Progress

描述: 一个双彩条, 通常用来指示一个操作接近完成的程度.

例如:

    Gui, Add, Progress, w200 h20 cBlue vMyProgress, 75

外观:

在最后一个参数中指定进度条的初始位置(如果省略, 则进度条的初始位置为 0 或允许的范围中最接近 0 的数字). 之后要改变进度条的位置, 请参照下面的例子, 它们都是操作关联变量名为 MyProgress 的进度条:

    GuiControl,, MyProgress, +20  ; 增加 20 到当前位置.
    GuiControl,, MyProgress, 50  ; 设置当前位置为 50.

对于水平进度条, 进度条的厚度等于控件的高度. 对于垂直进度条它等于控件的宽度.

### Progress 选项

Cn: 改变进度条的颜色. 指定 n 为 16 种 HTML 基础颜色之一或 6 位的 RGB 颜色值. 例如: `cRed`, `cFFFF33`, `cDefault`. 如果从没有使用过 C 选项(或指定 `cDefault`), 则使用系统默认的进度条颜色.

BackgroundN: 改变进度条的背景颜色. 指定 n 为 16 种 HTML 基础颜色之一或 6 位的 RGB 颜色值. 例如: `BackgroundGreen`, `BackgroundFFFF33`, `BackgroundDefault`. 如果从没有使用过 Background 选项(或指定 `BackgroundDefault`), 则使用窗口的或进度条后选项卡控件的颜色作为背景颜色.

Range: 使用 0 到 100 外的其他范围. 在单词 Range 后指定最小值, 破折号和最大值. 例如, `Range0-1000` 将允许一个介于 0 和 1000 之间的数字; `Range-50-50` 将允许介于 -50 和 50 之间的数字; 而 `Range-10--5` 将允许介于 -10 和 -5 之间的数字.

Smooth: 指定 `-Smooth`(负 Smooth) 显示一段段的长度而不是一个平滑连续的进度条. 指定 `-Smooth` 也是在 Windows XP 或更高版本中显示含主题的进度条的其中一个要求. 其他的要求是没有使用自定义的颜色, 即同时省略了 C 和 Background 选项.

Vertical: 让进度条垂直上升或下降而不是水平移动.

在控件创建后可以使用 GuiControl 改变上面的选项.

## GroupBox

描述: 一个矩形的框, 常用来封装一组相关的控件. 此时最后一个参数为分组框的标题, 其(如果存在) 显示在分组框的左上角.

例如:

    Gui, Add, GroupBox, w200 h100, Geographic Criteria

外观:

默认情况下, 分组框的标题可以只有一行文本. 在 选项 中指定 `Wrap` 可以改变此特性.

要指定控件中的行数(或高度和宽度), 请参阅控件的位置和大小.

## Tab3

描述: 一个包含多个页面的大型控件, 其中每个页面包含其他控件. 从这里开始, 这些页面被称为 "选项卡(标签页)".

选项卡控件有以下三种类型:

- Tab3 [v1.1.23.00+]: 修复若干影响 Tab2 和 Tab 的问题. 各控件位于一个可见的 "tab dialog(标签页对话框)", 其位置和大小随选项卡控件的移动和大小的改变而改变. 选项卡控件使用默认主题.
- Tab2 [v1.0.47.05+]: 修正了原有 Tab 控件罕见的重绘问题, 但是引入了一些其他问题.
- Tab: 保留向后兼容性, 因为在 Tab2/Tab3 和 Tab 之间有着行为差异.

例如:

    Gui, Add, Tab3,, General|View|Settings

外观:

上述的最后一个参数是管道分隔的选项卡名称列表. 要在窗口初次出现时预选其中的某个选项卡, 请在它后面包含两个管道符(例如 `Red|Green||Blue`). 或者, 在 选项 中包含单词 Choose 紧跟着想预选的选项卡的编号. 例如, `Choose5` 会预选第五个选项卡(和其他选项一样, 它也可以为变量, 例如 `Choose%Var%`). 要在控件创建后改变选择的选项卡, 请使用 GuiControl.

创建选项卡控件后, 随后添加的控件自动属于其首个选项卡. 这可以在任何时候改变, 请参照这些例子:

    Gui, Tab  ; 随后的控件不属于任何选项卡控件的一部分.
    Gui, Tab, 3  ; 随后的控件属于当前选项卡控件的第三个选项卡.
    Gui, Tab, 3, 2  ; 随后的控件属于第二个选项卡控件的第三个选项卡.
    Gui, Tab, Name  ; 随后的控件属于名称以 Name(不区分大小写) 开始的选项卡.
    Gui, Tab, Name,, Exact  ; 与上面相同, 不过这里需要准确匹配(并区分大小写).

还可以使用上面的每个例子分配控件到还不存在的选项卡或选项卡控件(不包括使用 Name 方法的情况). 但在此情况下, 不支持下面描述的相对位置选项.

位置: 当一个选项卡控件的每个选项卡接收到其首个子控件, 此子控件在下列情况下将具有特殊的默认位置: 1) 同时省略 X 和 Y 坐标, 此时首个子控件放在选项卡控件内部的左上角(带有标准的边距), 而首个子控件后的其他子控件放在之前控件的下面; 2) 指定了 X+n 和/或 Y+n 位置选项, 此时子控件放在相对于选项卡控件内部的左上角的位置. 例如, 指定 `x+10 y+10` 会把控件放置在左上角往右和往下各 10 个像素的位置.

V: 当 Gui Submit 命令使用时, 控件的关联输出变量(如果有) 接收当前选定选项卡的名称. 然而, 如果控件有 AltSubmit 属性, 输出变量将接收选项卡的位置号(第一个选项卡为1, 第二个选项卡为2, 以此类推.).

G: g-标签(例如 `gMySubroutine`) 可以在控件的选项中列出. 这将导致当用户切换到一个新的选项卡时 MySubroutine 标签将自动启动. 如果选项卡控件同时具有 g-标签和输出变量, 当用户切换到一个新的选项卡, 输出变量将会设置为先前选中的选项卡名称(或者在具有 AltSubmit 属性时为位置号).

键盘导航: 用户可以按下 `Ctrl`+`PgDn`/`PgUp` 来在选项卡控件的页面间导航; 如果键盘焦点在不属于选项卡的控件上, 则会导航到窗口的首个选项卡控件. 也可以使用 `Ctrl`+`Tab` 和 `Ctrl`+`Shift`+`Tab`, 除非当前焦点控件在多行编辑控件中(此时它们不起作用).

限制: 每个窗口的选项卡控件不能超过 255 个. 每个选项卡控件不能含有超过 256 个选项卡(页面). 此外, 选项卡控件不能包含其他选项卡控件.

### Tab3 vs. Tab2 vs. Tab

父窗口: 控件的父窗口影响控件的位置和可见性以及 Tab 键的导航顺序. 如果控件添加到已存在的 Tab3 选项卡控件, 其父窗口是 "tab dialog", 该父窗口填充选项卡控件的显示区域. 大部分其他控件, 包括 Tab 或 Tab2 中的子控件, 没有父窗口除了 Gui 界面本身.

位置: 对于 Tab 和 Tab2, 子控件不需要在他们的选项卡控件的边界内: 当标签页是激活或未激活时他们总是会显示和隐藏. 这种行为特别适合下面描述的 "按钮" 样式.

对于 Tab3, 在标签页控件创建之 前 添加子控件的行为与 Tab 或 Tab2 是一致的. 所有其他子控件只在选项卡控件的显示区域内可见.

如果 Tab3 控件移动, 他的子控件也随之移动. Tab 和 Tab2 控件没有这个行为.

在极少数情况下 WinMove(或等效的 DllCall) 用于移动控件, 坐标必须相对于控件的父窗口, 而不是 Gui(参阅上面的信息). 相比之下, GuiControl 移动使用 GUI 坐标和 ControlMove 使用窗口坐标, 这些与控件的父窗口无关.

自动尺寸: 如果脚本没有指定, 在下列情况下 Tab3 控件的宽度 和/或 高度将会自动计算(在控件创建后以先到者为准):

- 第一次 Tab3 控件不再是当前标签页控件. 这可能是调用了 Gui Tab(有或没有参数) 或创建另一个标签页控件所导致的.
- 特别的 Gui 首次调用 Gui Show.

存在的子控件计算尺寸时, 自动调整的尺寸再加上默认边距. 尺寸只计算一次, 即使添加控件也不会重新计算. 如果 Tab3 控件是空的, 与 Tab 或 Tab2 控件相同的默认大小.

Tab 和 Tab2 控件不会自动计算尺寸; 它们接受任意默认大小.

Tab 键导航顺序: `Tab` 导航顺序通常取决于控件创建的顺序. 当选项卡控件激活时, 顺序也取决于选项卡控件的类型:

- Tab 和 Tab2 允许其子控件与其他控件混合.
- Tab2 将标签页按钮置于其子控件之后.
- Tab3 的子控件组合在一起并置于标签页按钮之后.

通知消息(Tab3): 命令和自定义控件通常向他们的父窗口发送通知消息. Tab3 控件的 tab dialog 接收到的任何 WM_COMMAND, WM_NOTIFY, WM_VSCROLL, WM_HSCROLL 或 WM_CTLCOLOR 消息转发到 GUI 窗口和能被 OnMessage() 检测. 如果标签页控件使用主题并且其子控件没有 +BackgroundTrans 选项, tab dialog 处理 WM_CTLCOLORSTATIC 消息而不转发. 其他的通知消息(例如自定义消息) 不被支持.

Tab2 选项卡控件的已知问题:

- 背景透明度在 Tab2 控件中没有效果.
- WebBrowser(网页浏览) 控件重绘不正确.
- 动态窗口和其他的某些 Win32 API 调用导致其中的控件不显示.

Tab 选项卡控件的已知问题:

- 通过单击界面窗口中的某个控件来激活界面窗口, 例如滚动条, 将会出现重绘不正确的情况.
- 背景透明度没有效果如果 Tab 控件包含 ListView 控件.
- WebBrowser(网页浏览) 控件不可见.

### Tab 选项

Choose: 请参阅上面.

Background: 指定 `-Background`(负 background) 取消窗口的自定义背景颜色, 而使用系统默认的选项卡控件的颜色. 指定 `+Theme -Background` 来让选项卡控件适应于当前桌面主题. 然而, 在这样选项卡控件内的大多数类型的控件看起来会很奇怪, 因为它们的背景颜色不匹配选项卡控件的背景颜色. 对于某些类型的控件(例如 Text), 这种情况可以在它们的选项中添加 BackgroundTrans 来修复.

Buttons: 在控件的顶部创建一系列按钮而不是选项卡(此时在默认情况下将没有边界, 因为显示的区域实际并不包含控件).

Left/Right/Bottom: 指定这些单词的其中一个让选项卡显示在左边, 右边或底部而不是顶部. 请参阅 TCS_VERTICAL 了解对于 Left 和 Right 的限制.

Wrap: 指定 `-Wrap`(负 Wrap) 阻止选项卡占用多行(此时为了适应过多的选项卡, 会显示箭头按钮以允许用户滑动来查看更多选项卡).

要指定控件中文本的行数(或高度和宽度), 请参阅控件的位置和大小.

在选项卡中添加图标: 通过 SendMessage 可以在每个选项卡的名称/文本旁边显示图标. 演示的例子请参阅论坛主题 Icons in tabs.

## StatusBar [v1.0.44+]

描述: 附加到窗口底部的一行文本和/或图标, 通常用来报告状态的变化.

例如:

    Gui, Add, StatusBar,, Bar's starting text (omit to start off empty).
    SB_SetText("There are " . RowCount . " rows selected.")

外观:

状态栏最简单的用法是每当应该报告给用户一些状态改变时调用 SB_SetText(). 要报告多片的信息, 请使用 SB_SetParts() 把状态栏分成多段. 要在状态栏中显示图标, 请使用 SB_SetIcon().

### StatusBar 函数

下列所有的状态栏函数操作于当前线程的默认 GUI 窗口(这可以使用 `Gui, 2:Default` 进行改变). 如果默认窗口不存在或不含有状态栏, 则所有 SB 函数会返回 0 来表明此问题.

#### SB_SetText

在状态栏指定部分显示 NewText.

    SB_SetText(NewText , PartNumber, Style)

如果省略 PartNumber, 则使用默认值 1. 否则, 请指定介于 1 和 256 之间的整数. 如果省略 Style, 则使用默认值 0, 此时使用让状态栏那部分看起来凹陷的传统边界. 否则, 指定 1 为无边框, 2 为带边框, 让状态栏看起来是凸起的. 最后, 在 NewText 中任意地方可以使用最多两个 tab 字符(`t): 在首个 tab 字符右边的任何内容显示在此部分中心, 而在第二个 tab 右边的内容显示为右对齐. SB_SetText() 成功时返回 1, 而失败时为 0.

#### SB_SetParts

根据指定的宽度(单位为像素) 把状态栏分成多个部分.

    SB_SetParts(Width1, Width2, ... Width255)

如果省略所有参数, 则状态栏恢复为只有一个很长的部分. 否则, 指定除了最后一部分外的其他每个部分的宽度(最后一部分将填充状态栏的剩余宽度). 例如, `SB_SetParts(50, 50)` 将创建三个部分: 前两个部分的宽度都为 50, 而最后一部分占据剩余的所有宽度.

注意: SB_SetParts() "删除" 的任何部分下次显示时都不会显示文本(而且它们的图标会自动销毁).

成功后, SB_SetParts() 返回非零值(状态栏的 HWND). 失败时返回 0.

#### SB_SetIcon

在指定部分的文本左边显示一个小图标.

    SB_SetIcon(Filename , IconNumber, PartNumber)

如果省略 PartNumber, 则默认为 1. Filename 为图标(.ICO), 光标(.CUR) 或动画光标(.ANI) 文件的名称(动画光标在状态栏上实际将不会动). 图标的其他来源包含下列类型的文件: EXE, DLL, CPL, SCR 以及包含图标资源的其他类型. 要使用文件中第一个以外的图标组, 请为 IconNumber 指定其编号. 例如, `SB_SetIcon("Shell32.dll", 2)` 将使用第二个图标组中的默认图标. 如果 IconNumber 为负数, 则假定其绝对值表示可执行文件中图标的资源 ID. SB_SetIcon() 成功时返回图标的 HICON, 而失败时返回 0. HICON 是一种系统资源, 它可以被大多数脚本安全地忽略, 因为当状态栏的窗口被销毁时它会被自动销毁. 同样, 当 SB_SetIcon() 用新图标替换旧图标时会销毁旧图标. 这种情况可以使用以下方法避免:

    Gui +LastFound
    SendMessage, 0x040F, part_number - 1, my_hIcon, msctls_statusbar321  ; 0x040F 为 SB_SETICON.

[v1.1.23+]: 图标句柄可替代文件名. 例如, `SB_SetIcon("HICON:" handle)`.

[v1.1.27+]: 非图标图片文件和位图句柄支持替代 文件名. 例如, `SB_SetIcon("HBITMAP:" handle)`.

#### SB_SetProgress()

创建和控制状态栏中的进度条. 此函数可以从 www.autohotkey.com/forum/topic37754.html 获取

### StatusBar 的使用

G-标签通知: g-标签(例如 `gMySubroutine`) 可以使用在此控件的选项中. 这使得当用户点击状态栏时 MySubroutine 标签会自动运行. 此子程序中可引用内置变量 A_Gui 和 A_GuiControl. 更重要的是, 它可以参考 A_GuiEvent, 其包含下列字符串的其中一个(考虑到和未来版本的兼容性, 脚本不应假定这些字符串是唯一可能的值):

- Normal: 用户左键单击了状态栏. 变量 A_EventInfo 包含目标部分的编号(然而, 如果用户点击状态栏右边靠近大小调整手柄的地方时, 目标部分的编号可能是很大的整数).
- RightClick: 用户右键单击了状态栏. 变量 A_EventInfo 包含目标部分的编号. 注: 如果状态栏含有 g-标签将不会调用 GuiContextMenu. 此外, 当脚本需要知道用户点击的是哪个部分的编号(A_EventInfo) 时, 应该使用 g-标签的 RightClick 事件代替 GuiContextMenu.
- DoubleClick: 用户双击了状态栏. 变量 A_EventInfo 包含目标部分的编号.
- R: 用户 右键双击 了状态栏. 变量 A_EventInfo 包含目标部分的编号.

字体和颜色: 尽管字体大小, 外观和样式可以使用 Gui Font 设置(像普通控件一样), 但是无法改变文本颜色. 而且, 不遵循 Gui Color 的颜色设置; 代替的方法是, 状态栏的背景颜色可以通过在 选项 中指定单词 Background 紧跟着颜色名称(请参阅颜色图表) 或 RGB 值(0x 前缀可以省略)来改变. 例如: `BackgroundSilver`, `BackgroundFFDD99`, `BackgroundDefault`.

隐藏状态栏: 创建时, 可以使用 `Gui, Add, StatusBar, Hidden vMyStatusBar` 隐藏状态栏. 要在创建后某个时候隐藏它, 请使用 `GuiControl, Hide, MyStatusBar`. 要显示, 请使用 `GuiControl, Show, MyStatusBar`. 注意: 隐藏状态栏不会降低窗口的高度. 如果希望这样, 一个简便的方法是 `Gui, Show, AutoSize`.

样式(很少使用): 请参阅状态栏样式表.

已知限制: 1) 如果某个控件的位置和状态栏重叠, 那么它有可能会被绘制在状态栏的上方. 避免这种情况的一种方法是通过 GuiSize 标签动态地缩小这样的控件. 2) 每个窗口只允许有一个状态栏控件.

示例: 示例 #1 在 TreeView 页面底部演示了一个多部分的状态栏.

## ActiveX [v1.1.03+]

ActiveX 组件(例如 MSIE 浏览器控件) 可以嵌入到 GUI 窗口, 请参照此例. 有关下面使用的 ActiveX 组件及其方法的详细信息, 请参阅 WebBrowser object (Microsoft Docs) 和 Navigate method (Microsoft Docs).

    Gui Add, ActiveX, w980 h640 vWB, Shell.Explorer  ; 最后一个参数是 ActiveX 组件的名称.
    WB.Navigate("https://www.autohotkey.com/docs/")  ; 该句只适用于 web 浏览器控件.
    Gui Show

创建控件时, ActiveX 对象被储存到控件的关联变量中(如果有). 可以使用 GuiControlGet 来获取此对象.

要处理由对象公开的事件, 请使用 ComObjConnect(), 如下所示. 有关事件的详情, 请参阅 NavigateComplete2 event(Microsoft Docs).

    Gui Add, Edit, w930 r1 vURL, https://www.autohotkey.com/docs/
    Gui Add, Button, x+6 yp w44 Default, Go
    Gui Add, ActiveX, xm w980 h640 vWB, Shell.Explorer
    ComObjConnect(WB, WB_events)  ; 连接 WB 事件到 WB_events 类对象.
    Gui Show
    ; 继续加载初始页面:
    ButtonGo:
    Gui Submit, NoHide
    WB.Navigate(URL)
    return

    class WB_events
    {
        NavigateComplete2(wb, NewURL)
        {
            GuiControl,, URL, %NewURL%  ; 更新 URL 编辑控件.
        }
    }

    GuiClose:
    ExitApp

ComObjType() 可以用来判断保存在控件变量中的对象类型.

## Custom [v1.1.10+]

AutoHotkey 不直接支持的控件还可以嵌入到 GUI 窗口. 要实现这样的操作, 在 Options 中包含单词 Class 后跟所需控件的 Win32 类名. 示例:

    Gui, Add, Custom, ClassComboBoxEx32  ; 添加 ComboBoxEx 控件.
    Gui, Add, Custom, ClassScintilla  ; 添加 Scintilla 控件. 注意必须加载 SciLexer.dll 库后才能添加此控件.

AutoHotkey 通过 Gui Add, GuiControl 或 GuiControlGet 使用标准的 Windows 操作方法来获取或替换控件中的文本.

G-标签通知: 类似 `gMySubroutine` 这样的 g-标签可以使用在控件的选项中, 这样可以捕获控件中的事件. 此子程序中可引用内置变量 A_Gui 和 A_GuiControl. 更重要的是, 它可以参考 A_GuiEvent, 其包含下列字符串的其中一个(考虑到和未来版本的兼容性, 脚本不应假定这些字符串是唯一可能的值):

- Normal: 接收到 WM_COMMAND 消息. 内置变量 A_EventInfo 包含了控件定义的通告码(相当于 C/C++ 中的 `HIWORD(wParam)`).
- N: 接收到 WM_NOTIFY 消息. 内置变量 A_EventInfo 包含了到控件通知结构体(NMHDR) 的指针. 把它赋值给 ErrorLevel 则可以向控件返回一个 32 位的有符号整型值(默认会把 g-标签线程的 ErrorLevel 设为零). 无效的值被视为零.

下面这个例子演示了如何添加 IP 地址控件:

    Gui, Add, Custom, ClassSysIPAddress32 r1 w150 hwndhIPControl gIPControlEvent
    Gui, Add, Button, Default, OK
    IPCtrlSetAddress(hIPControl, A_IPAddress1)
    Gui, Show
    return

    GuiClose:
    ExitApp

    ButtonOK:
    Gui, Hide
    ToolTip
    MsgBox % "You chose " IPCtrlGetAddress(hIPControl)
    ExitApp

    IPControlEvent:
    if (A_GuiEvent = "Normal")
    {
        ; 接收到 WM_COMMAND.

        if (A_EventInfo = 0x0300)  ; EN_CHANGE
            ToolTip Control changed!
    }
    else if (A_GuiEvent = "N")
    {
        ; 接收到 WM_NOTIFY.

    	; 获取通告码. 一般情况下这个字段是 UInt 类型, 但 IP 地址
        ; 控件使用负值, 所以为了方便我们把它作为有符号整型读取出来.
        nmhdr_code := NumGet(A_EventInfo + 2*A_PtrSize, "int")
        if (nmhdr_code != -860)  ; IPN_FIELDCHANGED
            return

        ; 从 NMIPADDRESS 结构体中提取信息
        iField := NumGet(A_EventInfo + 3*A_PtrSize + 0, "int")
        iValue := NumGet(A_EventInfo + 3*A_PtrSize + 4, "int")
        if (iValue >= 0)
            ToolTip Field #%iField% modified: %iValue%
        else
            ToolTip Field #%iField% left empty
    }
    return

    IPCtrlSetAddress(hControl, IPAddress)
    {
        static WM_USER := 0x400
        static IPM_SETADDRESS := WM_USER + 101

        ; 把 IP 地址打包成 32 位字以用于 SendMessage.
        IPAddrword := 0
        Loop, Parse, IPAddress, .
            ipaddrword := (IPAddrword * 256) + A_LoopField
        SendMessage IPM_SETADDRESS, 0, IPAddrword,, ahk_id %hControl%
    }

    IPCtrlGetAddress(hControl)
    {
        static WM_USER := 0x400
        static IPM_GETADDRESS := WM_USER + 102

        VarSetCapacity(AddrWord, 4)
        SendMessage IPM_GETADDRESS, 0, &addrword,, ahk_id %hControl%
        return NumGet(AddrWord, 3, "UChar") "." NumGet(AddrWord, 2, "UChar") "." NumGet(AddrWord, 1, "UChar") "." NumGet(AddrWord, 0, "UChar")
    }

## 相关页面

ListView, TreeView, Gui, GuiControl, GuiControlGet, Menu

dftg