Gui 对象

class Gui extends Object

提供一个接口, 用于创建窗口, 添加控件, 修改窗口和检索有关窗口的信息. 这些窗口可以用作数据输入表单或自定义用户界面.

Gui 对象可以通过 Gui() 来创建, 也可以通过 GuiFromHwnd 来检索.

下面使用 "MyGui" 作为任何 Gui 对象的占位符(和示例中的变量名), 因为 "Gui" 就是类本身.

除了从 Object 继承的方法和属性外, Gui 对象还具有以下预定义的方法和属性.

目录

静态方法

Call

创建一个新的窗口.

MyGui := Gui(Options, Title, EventObj)
MyGui := Gui.Call(Options, Title, EventObj)

参数

Options

类型: 字符串

Gui.Opt 支持的任何选项.

Title

类型: 字符串

如果省略, 则默认为 A_ScriptName. 否则, 请指定窗口的标题.

EventObj

类型: 对象

一个 "事件接收器", 或绑定事件的对象. 如果指定了 EventObj, 那么 OnEvent, OnNotifyOnCommand 可以用来注册 EventObj 的方法, 以便在事件发生时被调用.

返回值

类型: Object

此方法返回一个 Gui 对象.

方法

Add

添加新的控件到窗口.

GuiCtrl := MyGui.Add(ControlType , Options, Text)
GuiCtrl := MyGui.AddControlType(Options, Text)

参数

ControlType

类型: 字符串

下列的其中一个: ActiveX, Button, CheckBox, ComboBox, Custom, DateTime, DropDownList(或 DDL), Edit, GroupBox, Hotkey, Link, ListBox, ListView, MonthCal, Picture(或 Pic), Progress, Radio, Slider, StatusBar, Tab, Tab2, Tab3, Text, TreeView, UpDown

例如:

MyGui := Gui()
MyGui.Add("Text",, "Please enter your name:")
MyGui.AddEdit("vName")
MyGui.Show
Options

类型: 字符串

如果为空或省略, 则该控件从其默认值开始. 否则, 指定以下一个或多个选项和样式, 每个选项和样式之间使用一个或多个空格或制表符分隔.

控件的位置和大小

如果在 Options 中省略了某些尺寸和/或坐标, 则会根据前一个控件确定它的位置, 根据控件的类型和内容确定它的大小.

支持下列选项:

Rn: 文本的行数(其中 n 为任意数字, 甚至可以为浮点数, 如 r2.5). R 通常比指定 H(高度) 更合适. 如果同时指定 R 和 H 选项, 则 R 优先考虑. 对于 GroupBox, 此选项设置是指在框内保留空间的控件数量. 对于 DropDownList, ComboBoxListBox, 它是指在控件的列表部分内一次可见的项目数(但对于 DropDownList 和 ComboBoxit 通常最好省略 RH 选项, 因为弹出列表会自动利用用户桌面的可用高度). 对于其他控件类型, R 是指可视的容纳在控件内的文本行数.

Wn: 宽度(其中 n 为任意数字, 单位为像素). 如果省略, 对于某些控件则根据其内容自动计算宽度. Tab 默认为 30 倍的当前字体大小加上 3 倍的行边距; 垂直进度条默认为两倍的当前字体大小, 水平进度条, 水平滑动条, DropDownList, ComboBox, ListBox, GroupBox, Edit 和 Hotkey: 15 倍的当前字体大小(GroupBox 除外, 其默认宽度为 18 倍, 这样可以显示内部的边距).

Hn: 高度(其中 n 为任意数字, 单位为像素). 如果同时省略 HR 选项, DropDownList, ComboBox, ListBox 和空的多行 Edit 控件默认为 3 行; GroupBox 默认为 2 行; 垂直滑动条和进度条默认为 5 行; 水平滑动条默认为 30 像素(在没有指定其厚度时); 水平进度条默认为 2 倍的当前字体大小; Hotkey 控件默认为 1 行; 而 Tab 控件默认为 10 行. 对于其他类型的控件, 根据它们的内容自动计算高度. 请注意对于 DropDownList 和 ComboBox, H 为控件总是可见的部分(大概指列表上面的框) 和其列表部分相加的高度(但即使高度设置很小, 也至少会在下拉列表中显示一个项目). 同时对于所有类型的控件, 通过 R 选项指定行数比使用 H 更可取, 因为这样可以避免在控件中显示部分/不完整的文本行.

WP±n, HP±n(其中 n 为任意数字, 单位为像素) 用来设置控件的宽度和/或高度等于前一个添加控件的宽度或高度, 可以使用加号或减号进行调整. 例如, wp 将设置控件的宽度等于之前的控件, 而 wp-50 则设置宽度为之前的控件宽度减去 50 像素.

Xn, Yn: X-坐标, Y-坐标(where n is any number in pixels). 例如, 指定 x0 y0 将把控件放置到窗口工作区的左上角, 窗口工作区是在标题栏和菜单栏(如果有) 下面的区域.

X+n, Y+n (其中 n 可以为任意数字, 单位为像素): 可以包括一个可选的加号, 以相对于前一个添加的控件的右边缘或底边缘(分别) 定位一个控件. 例如, 指定 y+10 将把控件放置在前一个控件底部下面 10 个像素的位置, 而不使用标准的填充间距. 同样地, 指定 x+10 将把控件放置在前一个控件右边缘的右边 10 个像素的位置. 由于负数如 x-10 表示绝对的位置, 因此要使用负的位置偏移, 需要在前面加上一个加号. 例如: x+-10.

对于 X+ 和 Y+, 可以用字母 M 来代替窗口的当前边距. 例如, x+m 使用前一个控件的右边缘位置加上标准填充间隔. xp y+m 将控件放置于前一个之下, 而单独指定一个相对的 X 坐标(使用 XP 或 X+), 相当于默认情况下隐式的 yp.

XP±n, YP±n (其中 n 可以为任意数字, 单位为像素) 可以用来指定控件相对于前一个控件左上角的位置, 此选项常用于 GroupBox 中的封装控件.

XM±n and YM±n (其中 n 可以为任意数字, 单位为像素)可以用来将一个控件分别定位在窗口的最左边和最上面的边距, 并可选带有一个正/负号来调整.

XS±n and YS±n (其中 n 可以为任意数字, 单位为像素): 这些与 XM 和 YM 类似, 只是它们是相对于前一个选项中带有 Section 单词的控件所保存的坐标(窗口的第一个控件总是开始一个新列, 即使这个单词没有在其选项中指定). 例如:

MyGui := Gui()
MyGui.Add("Edit", "w600")  ; 在窗口的顶部添加一个非常宽的编辑控件.
MyGui.Add("Text", "Section", "First Name:")  ; 保存此控件位置并定义一个新控件段.
MyGui.Add("Text",, "Last Name:")
MyGui.Add("Edit", "ys")  ; 在此控件段中开始一个新列.
MyGui.Add("Edit")
MyGui.Show

XS 和 YS 后面可以跟着一个加号/减号和一个数字. 并且, 还可以在控件的选项中同时指定单词 Section 和 XS/YS; 这样可以让当前控件使用之前的控件段, 但为后续控件定义一个新段.

省略 X, Y 的其中一个或同时省略, 有助于 GUI 布局自动调整, 以适应将来可能对控件大小或字体所做的任何更改. 相比之下, 为每个控件指定绝对位置可能需要手动移动正在放大或缩小的控件下面和/或右侧的所有控件的位置.

如果 X 和 Y 都被省略, 控件将使用标准填充距离(当前边距) 被放置在前一个控件的下面. 连续的 Text 或 Link 控件被赋予额外的垂直填充, 因此在 Edit, DDL 或类似尺寸的控件列后来被添加到它们的右边的情况下, 它们通常会更好地对齐. 要只使用标准的垂直边距, 请指定 Y+M 或任何 X 值.

如果只省略了一个组件, 它的默认值取决于使用哪个选项来指定其他组件:

指定了 XY 的默认值
Xn 或 XM在所有之前控件的下方(最大 Y 范围加边距).
XS在最近一次使用 Section 选项后的所有之前控件的下方.
X+n 或 XP+非零值等同于前一个控件的顶部边缘(YP).
XP 或 XP+0前一个控件的下方(底部边缘加上边距).
指定了 YX 的默认值
Yn 或 YM在所有之前控件的右边(最大 X 范围加边距).
YS自最近一次使用 Section 选项以来, 所有先前控件的右边.
Y+n 或 YP+非零值等同于前一个控件的左边缘(XP).
YP or YP+0前一个控件的右边(右边缘加上边距).

存储和响应用户的输入

V: 设置控件的名称. 在字母 V 后指定一个名称, V 不包含在名称中. 例如, 指定 vMyEdit 会将控件命名为 "MyEdit".

Events: 事件处理程序(如当用户点击或更改控件时自动调用的函数) 不能在控件的 Options 中进行设置. 而是, 使用 OnEvent 可以为每个感兴趣的事件注册一个回调函数或方法.

控件的常用样式和选项

注意: 选项前的符号省略时, 默认为加号; 例如, Wrap 等同于 +Wrap. 相反地, -Wrap 将去除自动换行属性.

AltSubmit: 使用替代的提交方法. 对于 DropDownList, ComboBox, ListBox 和 Tab, 会让 Gui.Submit 保存选择项目的位置而不是其文本. 如果没有选择项目, 则对于 ComboBox 命令保存选项项目的位置而不是其文本. 如果没有选择项目, 则对于 ComboBox 会保存其编辑区域的文本.

C: 文本颜色(对按钮状态栏控件无效). 指定字母 C 后面紧跟着颜色名称(请参阅颜色图表) 或 RGB 值(0x 前缀可以省略). 例如: cRed, cFF2211, c0xFF2211, cDefault.

Disabled: 让可输入型控件变为灰色禁用状态, 这样可以防止取得焦点或用户改变其内容. 以后可以使用 GuiCtrl.Enabled 来启用控件. 注意: 要让编辑控件为只读状态, 请指定字符串 ReadOnly 代替. 并且, 还可以在单词 Disabled 后紧跟着 0 或 1 来表示控件的初始状态(0 为启用而 1 为禁用). 换句话说, Disabled"Disabled" VarContainingOne 是一样的.

Hidden: 让控件初始为隐藏状态. 以后可以使用 GuiCtrl.Visible 来让它显示. 可以在单词 Hidden 后跟着 0 或 1 来表示初始状态(0 为可见而 1 为隐藏). 换句话说, Hidden"Hidden" VarContainingOne 是一样的.

Left: 在控件的可用宽度内左对齐控件的文本. 该选项会影响以下控件: Text, Edit, Button, CheckBox, Radio, UpDown, Slider, Tab, Tab2, GroupBox, DateTime.

Right: 在控件的可用宽度内右对齐控件的文本. 对于复选框和单选按钮, 此选项也同时把框放置在控件的右边而不是左边. 该选项会影响以下控件: Text, Edit, Button, CheckBox, Radio, UpDown, Slider, Tab, Tab2, GroupBox, DateTime, Link.

Center: 在控件的可用宽度内居中对齐控件的文本. 该选项会影响以下控件: Text, Edit, Button, CheckBox, Radio, Slider, GroupBox.

Section: 定义一个新的控件段并保存当前控件的位置, 以便以后使用上面描述的 XSYS 定位选项.

Tabstop: 使用 -Tabstop(负 Tabstop) 可以让用户按 Tab 导航时跳过输入型控件.

Wrap: 让控件的文本自动换行. 因为几乎所有类型的控件初始状态都启用了自动换行, 所以需要通过 -Wrap 禁用它.

VScroll: 当控件支持时为其提供一个垂直滚动条.

HScroll: 当控件支持时为其提供一个水平滚动条. 这个段落的剩余部分仅适用于 ListBox. 水平滚动宽度默认为 ListBox 宽度的 3 倍. 要使用其他的滚动宽度, 请在单词 HScroll 后紧跟着一个数字表示. 例如, HScroll500 将在 ListBox 中使用 500 像素的滚动栏宽度. 但是, 如果指定的滚动宽度小于 ListBox 的宽度, 则不显示滚动条(不过在这种含有 HScroll 的情况下, 可以在之后通过 MyScrollBar.Opt("+HScroll500"), 来添加水平滚动条, 否则是无法添加的).

控件的不常用选项和样式

BackgroundTrans: 使用透明的背景, 允许任何位于 Text, Picture 或 GroupBox 后面的控件显示出来. 例如, 在 Picture 控件上显示一个透明背景的 Text 可以让文字看起来就像图片的一部分. 以后可以使用 GuiCtrl.Opt("+Background") 移除此选项. 有关透明图像的更多信息, 请参阅 Picture 控件的 AltSubmit 部分. 已知限制: 对包含了 ListViewTab 控件内的其他控件, BackgroundTrans 可能无法正确应用. 如果控件类型不支持这个选项, 则抛出错误.

BackgroundColor: 更改控件的背景色. 用颜色名称(请参阅颜色图表) 或 RGB 值(0x 前缀可以省略) 替换 Color. 例如: BackgroundSilver, BackgroundFFDD99. 如果不使用这个选项, 或 +Background 不带后缀使用, Text, Picture, GroupBox, CheckBox, Radio, Slider, TabLink 控件使用 Gui.BackColor 设置的背景色(如果没有设置或其他控件类型, 则为系统默认的背景色). 指定 BackgroundDefault-Background 会应用系统的默认背景色. 例如, 控件可以通过 LV.Opt("+BackgroundDefault") 恢复到系统的默认颜色. 如果控件类型不支持这个选项, 则抛出错误.

Border: 为控件增加一个细边框. 对于大多数控件不需要使用此选项, 因为它们已经含有特定于类型的边框. 添加边框到 现有 控件时, 可能需要给控件的宽度和高度增加 1 个像素.

Redraw: 当与 GuiCtrl.Opt 一起使用时, 该选项通过向控件发送 WM_SETREDRAW 消息来启用或禁用控件的重绘(可视化更新). 有关详情, 请参阅 Redraw.

Theme: 使用此选项可以让新建的控件忽略窗口当前的主题设置. 它对于现有控件没有效果; 不过, 这种情况可能在将来的版本中改变. 请参阅 GUI 的 +/-Theme 选项了解详情.

(未命名样式): 在十进制或十六进制的样式编号前加上加号或减号表示添加或删除此样式. 如果省略了符号, 则默认为加号.

(未命名扩展样式): 在字母 E 和十进制或十六进制的扩展样式编号前加上加号或减号表示添加或删除此扩展样式. 如果省略了符号, 则默认为加号. 例如, E0x200 表示添加 WS_EX_CLIENTEDGE 样式, 它可以为图片和其他控件增加一个下沉的边框样式. 这里没有列出其他的扩展样式编号(因为它们极少使用), 有关完整列表, 前参阅 Extended Window Styles | Microsoft Docs.

Text
根据指定的控件类型, 可以是字符串, 数字或数组.

返回值

类型: Object

此方法返回一个 GuiControl 对象.

Destroy

移除窗口及其所有控件, 并释放其占用的内存和系统资源.

MyGui.Destroy()

如果没有使用 MyGui.Destroy(), 那么当 Gui 对象被删除时, 窗口会被自动销毁(详见通用备注). 当脚本退出时, 所有的 GUI 窗口都会被自动销毁.

Flash

闪烁任务栏中的窗口按钮.

MyGui.Flash(Blink)

参数

Blink

类型: 布尔值

如果省略, 默认为 1(true)

如果为 true, 任务栏中的窗口按钮将闪烁. 这是通过反转窗口的标题栏和/或任务栏按钮(如果有的话) 的颜色来实现的.

如果为 false, 可恢复标题栏和任务栏按钮的原始颜色(但实际行为可能因操作系统版本而异).

在下面的例子中, 窗口将闪烁三次, 因为每对闪烁都会反转, 然后恢复其外观:

Loop 6
{
    MyGui.Flash
    Sleep 500  ; 这个时间值十分敏感, 改变它可能引起异常.
}

GetClientPos

检索窗口客户端区域的位置和大小.

MyGui.GetClientPos(&X, &Y, &Width, &Height)

参数

&X, &Y

类型: VarRef

如果省略, 则不存储相应的值. 否则, 指定对输出变量的引用, 以存储控件左上角的 X 和 Y 坐标(以像素为单位).

&Width, &Height

类型: VarRef

如果省略, 则不存储相应的值. 否则, 指定对输出变量的引用, 以存储控件的宽度和高度.

Width 是客户端左右两侧的水平距离, 而 height 是上下两侧的垂直距离(以像素为单位).

备注

客户端区域是窗口中可以包含控件的部分. 它不包括窗口的标题栏, 菜单(如果它有标准的) 和边框. 与 Gui.GetPos 返回的值相比, 客户端区域的位置和大小对操作系统版本和主题的依赖性较小.

WinGetClientPos, 不同, 该方法将 DPI 缩放应用于 WidthHeight(除非使用了 -DPIScale 选项).

GetPos

检索窗口的位置和大小.

MyGui.GetPos(&X, &Y, &Width, &Height)

参数

&X, &Y

类型: VarRef

如果省略, 则不存储相应的值. 否则, 指定对输出变量的引用, 以存储窗口左上角在屏幕坐标中的 X 和 Y 坐标(以像素为单位).

&Width, &Height

类型: VarRef

如果省略, 则不存储相应的值. 否则, 指定对输出变量的引用, 以存储窗口的宽度和高度.

Width 是窗口左右两侧的水平距离, 而 height 是上下两侧的垂直距离(以像素为单位).

备注

由于此方法返回的坐标包括窗口的标题栏, 菜单和边框, 因此它们可能取决于操作系统版本和主题. 为了在不同的系统中获得更一致的值, 可以考虑使用 Gui.GetClientPos 代替.

WinGetPos 不同, 该方法将 DPI 缩放应用于 WidthHeight(除非使用了 -DPIScale 选项).

Hide

隐藏窗口.

MyGui.Hide()

Maximize

取消隐藏窗口(如有必要) 并将其最大化.

MyGui.Maximize()

Minimize

取消隐藏窗口(如有必要) 并将其最小化.

MyGui.Minimize()

Move

移动和/或调整窗口的大小

MyGui.Move(X, Y, Width, Height)

Parameters

X, Y

类型: 整数

如果省略其中任何一个, 则不会更改在该维度中的位置. 否则, 指定窗口新位置左上角在屏幕坐标中的 X 和 Y 坐标.

Width, Height

类型: 整数

如果省略其中任何一个, 则不会更改该维度中的大小. 否则, 指定窗口的新宽度和高度(以像素为单位).

备注

WinMove 不同, 该方法将 DPI 缩放应用于 WidthHeight(除非使用了 -DPIScale 选项).

示例

MyGui.Move(10, 20, 200, 100)
MyGui.Move(VarX+10, VarY+5, VarW*2, VarH*1.5)

; 左右两边扩大 10 个像素.
MyGui.GetPos(&x,, &w)
MyGui.Move(x-10,, w+20)

OnEvent

注册一个函数或方法, 当给定的事件被触发时调用.

MyGui.OnEvent(EventName, Callback , AddRemove)

有关详情, 请参阅 OnEvent.

Opt

为窗口的外观和行为设置各种选项和样式.

MyGui.Opt(Options)

参数

Options

类型: 字符串

以下零个或多个选项和样式, 每个选项和样式之间用一个或多个空格或制表符分隔.

处于性能原因, 最好在一行中设置所有选项, 并在创建窗口之前(即在使用 MyGui.Add 等其他方法之前) 进行设置.

这个参数的效果是累加的; 也就是说, 它只改变那些明确指定的设置, 而其他所有选项则保持不变.

在选项前指定加号表示增加此选项, 而减号表示移除它. 例如: MyGui.Opt("+Resize -MaximizeBox").

AlwaysOnTop: 使窗口保持在所有其他窗口的顶部, 这与 WinSetAlwaysOnTop 的效果相同.

Border: 为窗口增加细边框. 此选项不常用.

Caption(默认具有此选项): 为窗口增加标题栏和粗边框. 当从将使用 WinSetTransColor 的窗口中移除标题时, 只有在设置 TransColor 后才能移除.

Disabled: 禁用窗口, 阻止用户和窗口中的控件交互. 此选项常用于含有子窗口的窗口(请参阅 Owner).

DPIScale: 使用 MyGui.Opt("-DPIScale") 禁用 DPI 缩放, 它默认是启用的. 如果启用了 DPI 缩放, 传递给或从 Gui 和 GuiControl 的方法/属性获取的坐标和大小会根据屏幕 DPI 自动缩放. 例如, 对于 144(150 %) 的 DPI, MyGui.Show("w100") 会让 Gui 宽度为 150(100 * 1.5) 像素, 如果通过鼠标或 WinMove 将窗口大小调整为 200 像素宽, 会导致 MyGui.GetClientPos(,,&W) 设置 W 为 133(200 // 1.5). A_ScreenDPI 包含了系统当前 DPI.

DPI 缩放只适用于 Gui 和 GuiControl 方法/属性, 所以直接来自其他来源的坐标, 如 ControlGetPos 或 WinGetPos 将无法使用. 有很多方法可以处理这个问题:

  • 尽可能避免使用硬编码坐标. 例如, 使用 XP, XS, XMX+M 选项来定位控件, 并以文本的行数而不是像素来指定高度.
  • 根据需要, 启用(Gui.Opt("+DPIScale")) 和禁用(Gui.Opt("-DPIScale")) 缩放. 更改这个设置并不会影响已经设置过的坐标或大小.
  • 手动缩放坐标. 例如, x*(A_ScreenDPI/96) 将 x 从逻辑/GUI 坐标转换为物理/非 GUI 坐标.

LastFound: 设置窗口为上次找到的窗口(对于 GUI 线程这是不必要的, 因为它自动设置了), 这样允许类似 WinGetStyleWinSetTransparent 这样的函数对此窗口进行操作, 即使它当前为隐藏状态(即不需要使用 DetectHiddenWindows). 需要在显示窗口之前改变其属性时, 这是非常有用的. 例如:

MyGui.Opt("+LastFound")
WinSetTransColor(CustomColor " 150", MyGui)
MyGui.Show()

MaximizeBox: 启用标题栏上的最大化按钮. 下面的 Resize 也含有此效果.

MinimizeBox (默认含有此选项): 启用标题栏上的最小化按钮.

MinSizeMaxSize: 限定窗口的最小尺寸和最大尺寸, 例如当用户拖动窗口边框改变其大小的时候. 指定 +MinSize 和/或 code>+MaxSize(如没有后缀) 来使用窗口当前尺寸作为限制大小(如果没有窗口当前尺寸, 则使用首次 MyGui.Show 时显示的大小). 还可以在后面加上宽度, 跟着 X 和高度; 例如: Gui.Opt("+Resize +MinSize640x480"). 它们指定了以像素为单位的窗口工作区(不包括边框, 标题栏和菜单栏). 指定每个数字为十进制, 而不是十六进制.

可以省略高度或宽度, 使其保持不变(例如 +MinSize640x+MinSizex480). 此外, 可以多次指定 Min/MaxSize 以便在一个维度上使用窗口的当前尺寸, 在另一个维度上使用显式尺寸. 例如, +MinSize +MinSize640x 表示最小高度限制为窗口当前的大小, 而最小宽度限制为 640.

如果从没有使用 MinSize 和 MaxSize, 则使用操作系统的默认值(同样地, 可以使用 MyGui.Opt("-MinSize -MaxSize") 恢复为默认值). 注意: 窗口必须有 +Resize, 以允许用户调整大小.

OwnDialogs: MyGui.Opt("+OwnDialogs") 应该在每个线程中指定(如 Button 控件的事件处理函数) 随后显示的 MsgBox, InputBox, FileSelectDirSelect 对话框应该由窗口拥有. 这类对话框成为模式对话框, 这意味着用户不能与 GUI 窗口进行交互, 直到解除对话框. 相反, ToolTip 窗口即使有拥有者, 也不会成为模式的; 它们只是会一直停留在其拥有者之上. 在这两种情况下, 任何拥有的对话框或窗口都会在其 GUI 窗口被销毁时自动销毁.

一般情况下打开这个设置后不需要再切换到关闭, 因为它不影响其他线程. 但是, 如果一个线程需要显示从属和非从属对话框, 则可以使用 MyGui.Opt("-OwnDialogs") 关闭此设置.

Owner: 使用 +Owner 可以让当前窗口从属于另一个窗口. 从属的窗口默认不显示在任务栏, 并且它总是显示在其父窗口的上面. 当其父窗口销毁时它也被自动销毁. +Owner 可以在父窗口创建之前或之后使用. 两种方法可以使用 +Owner, 如下所示:

MyGui.Opt("+Owner" OtherGui.Hwnd)  ; 让 GUI 成为 OtherGui 的子窗口.
MyGui.Opt("+Owner")  ; 让 GUI 成为脚本主窗口的子窗口, 这样可以阻止其任务栏按钮的显示.

+Owner 后面可以紧跟着任何顶级窗口的 HWND.

在某个从属窗口显示时要防止用户与其父窗口交互, 请使用 MyGui.Opt("+Disabled"). 禁用父窗口. 之后(当子窗口取消或销毁时), 通过 MyGui.Opt("-Disabled"). 来重新启用父窗口. 在取消或销毁子窗口前这样做可以让父窗口自动恢复有效.

Parent: 使用 +Parent 后面紧跟着任何窗口或控件的 HWND, 将其作为这个窗口的父窗口. 要恢复 Gui 为顶级窗口, 请使用 -Parent. 在窗口创建后此选项也有效. 已知限制:

  • 如果新的父窗口总是在顶部, 而子窗口不是, Running with UI access 阻止 +Parent 选项在现有窗口上工作.
  • 如果父窗口是外部的, +Parent 选项可能在 GUI 创建过程中失败, 但可能在 GUI 创建后工作. 这是由于样式应用方式的不同.

Resize: 此选项允许用户重新调整窗口的大小并启用标题栏上的最大化按钮. 要禁用最大化按钮, 请指定 +Resize -MaximizeBox.

SysMenu(默认含有此选项): 指定 -SysMenu(负 SysMenu) 可以删除点击窗口左上角时弹出的系统菜单和图标. 同时也删除标题栏上的最小化, 最大化和关闭按钮.

Theme: 通过指定 -Theme, 可以让随后在窗口中创建的所有控件具有经典主题的外观. 之后要创建其他使用当前主题的控件时, 请使用 +Theme 把设置切换回来. 注意: 如果经典主题有效, 这个选项就没有效果. 最后, 每个控件在创建时, 可以通过在其选项中指定 +Theme-Theme 来改变该设置.

ToolWindow: 让窗口显示细标题栏, 同时去除任务栏按钮. 无论是否存在 WS_MAXIMIZEBOXWS_MINIMIZEBOX 样式, 这总是隐藏了最大化和最小化按钮.

(未命名样式): 在十进制或十六进制的样式编号前加上加号或减号表示添加或删除此样式.

(未命名扩展样式): 在字母 E 和十进制或十六进制的扩展样式编号前加上加号或减号表示添加或删除此扩展样式. 例如, +E0x40000 表示添加 WS_EX_APPWINDOW 样式, 此样式让窗口显示任务栏按钮. 这里没有列出其他的扩展样式编号(因为它们极少使用), 有关完整列表, 请参阅 Extended Window Styles | Microsoft Docs.

Restore

显示窗口(如有必要) 并取消最小化或最大化.

MyGui.Restore()

SetFont

为在此处之后创建的控件设置字体字型, 大小, 样式和/或颜色.

MyGui.SetFont(Options, FontName)

参数

Options

类型: 字符串

零个或多个选项. 每个选项要么是一个字母后面紧跟着一个值, 要么是一个单词. 若要指定多个选项, 请在每个选项之间使用空格. 例如: cBlue s12 bold.

支持以下单词: bold, italic, strike, underline 和 norm. Norm 将字体恢复到标准的粗细, 并关闭斜体, 删除和下划线(但保留现有的颜色和大小). 可以使用 norm 去除所有属性然后有选择的设置其他属性. 例如, 指定 norm italic 将设置字体为标准然后增加斜体属性.

C: 颜色名称(请参阅颜色图表) 或 RGB 值 -- 或指定单词 Default 来恢复到系统默认颜色(大多数系统的默认颜色为黑色). 例如: cRed, cFFFFAA, cDefault. 注意: Button状态栏不遵循自定义颜色. 此外, 可以通过包含 C 选项创建带有字体颜色的特殊控件不会受到当前选项的影响. 例如: MyGui.Add("Text", "cRed", "My Text").

S: 尺寸(单位为磅). 例如: s12(指定十进制, 而不是十六进制)

W: 粗细, 这是介于 1 和 1000 之间的数字(400 为标准大小而 700 为粗体). 例如: w600(指定十进制, 而不是十六进制)

Q: 文本渲染质量. 例如: q3. Q 后应跟着下表中的一个数字:

数字 Windows 常量 描述
0 DEFAULT_QUALITY 字体的外观并不重要.
1 DRAFT_QUALITY 字体的外观不如使用 PROOF_QUALITY 值时重要.
2 PROOF_QUALITY 字体的字符质量比逻辑字体属性的精确匹配更重要.
3 NONANTIALIASED_QUALITY 字体从不进行抗锯齿处理, 即不进行字体平滑处理.
4 ANTIALIASED_QUALITY 如果字体支持抗锯齿, 并且字体大小不是太小或太大, 那么字体是抗锯齿或平滑的.
5 CLEARTYPE_QUALITY 如果设置, 则使用 ClearType 抗锯齿方法渲染文本(在可能的情况下).

关于这些值含义的更多细节, 请参阅 Microsoft Docs: CreateFont.

由于默认设置通常是最好的品质, 所以这个功能往往用于在特殊情况时禁用抗锯齿效果, 这样可以让文本更清晰.

FontName

类型: 字符串

FontName 可以是任意字体的名称, 例如字体表的其中一个. 如果省略 FontName 或此字体在系统中不存在, 则使用之前的字体字型(如果没有, 则使用系统默认的 GUI 字型). 即使某些系统缺少首选字体, 这种特性也可以让窗口在多个系统上具有类似的字体. 例如, 按顺序执行下列命令, 则 Verdana 字体优先于 Arial, 而 Arial 字体优先于 MS Sans Serif:

MyGui.SetFont(, "MS Sans Serif")
MyGui.SetFont(, "Arial")
MyGui.SetFont(, "Verdana")  ; 优选字体.

备注

省略两个参数可以让字体恢复为系统默认的 GUI 字型, 大小和颜色. 否则, 任何未指定的字体属性将从之前的字体中复制.

相关提示, 操作系统提供了标准的对话框, 提示用户选取字体, 颜色或图标. 这些对话框可以通过 DllCallcomdlg32\ChooseFont, comdlg32\ChooseColorshell32\PickIconDlg 的组合来显示. 请在论坛中搜索示例.

Show

默认情况下, 这将使窗口可见, 取消最小化(如果需要) 并激活它.

MyGui.Show(Options)

参数

Options

类型: 字符串

省略后面的 X, Y, W 和 H 选项则让窗口保持原来的大小和位置. 如果之前没有设置过位置, 则在后面提到的 X 和/或 Y 选项没有指明的坐标上窗口将自动居中. 如果之前没有设置过大小, 则窗口会根据它所包含控件的大小和位置自动调整大小.

Options 中可以包含零个或多个下列字符串(指定每一个数字为十进制, 而不是十六进制):

Wn: 指定 n 为窗口工作区的宽度(单位为像素), 窗口工作区指除了窗口边框, 标题栏和菜单栏的区域.

Hn: 指定 n 为窗口工作区的高度, 单位为像素.

Xn: 指定 n为窗口在屏幕中的 X-坐标, 单位为像素. 0 表示屏幕最左边首列可见像素的位置.

Yn: 指定 n 为窗口在屏幕中的 Y-坐标, 单位为像素. 0 表示屏幕最左边首列可见像素的位置.

Center: 让窗口在屏幕的水平和垂直方向上居中.

xCenter: 让窗口在屏幕的水平方向上居中. 例如: MyGui.Show("xCenter y0").

yCenter: 让窗口在屏幕的垂直方向上居中.

AutoSize: 根据窗口当前包含的可见控件调整窗口的大小. 这常在添加新控件, 调整现有控件的大小或隐藏/显示现有控件后用来调整窗口的大小. 例如: MyGui.Show("AutoSize Center").

还可能存在以下情况之一:

Minimize: 最小化当前窗口并激活其下方的窗口.

Maximize: 最大化并激活窗口.

Restore: 必要时, 将窗口取消最小化或最大化(还原窗口). 如有必要, 还将显示并激活窗口.

NoActivate: 当窗口处于最小化或最大化状态时, 还原窗口. 窗口显示但不进行激活.

NA: 显示窗口但不进行激活. 如果窗口处于最小化状态, 那么它仍保持这种状态, 但可能提升它的 z 顺序(这是在 alt-tab 选择器中看到的顺序). 如果窗口之前是隐藏的, 则此参数可能会让它显示在当前仍处于活动状态的窗口上面.

Hide: 隐藏窗口并激活其下方的窗口. 这与 MyGui.Hide 的功能相同, 只是它允许移动或调整隐藏窗口的大小, 而不显示它. 例如: MyGui.Show("Hide x55 y66 w300 h200").

Submit

从命名的控件中收集值, 并将它们组合成一个对象. 可选择隐藏窗口.

NamedCtrlValues := MyGui.Submit(Hide)

参数

Hide

类型: 布尔值

如果省略, 则默认为 true.

如果为 true, 则窗口将被隐藏.

如果为 false, 则窗口不会被隐藏.

返回值

类型: Object

此方法返回一个对象, 其中每个命名控件包含一个自己的属性, 如 NamedCtrlValues.%GuiCtrl.Name% := GuiCtrl.Value, 但下列例外情况除外. 只有具有输入能力的控件支持 GuiCtrl.Value, 并被赋予名称的控件才会被包含在内. 使用 NamedCtrlValues.NameOfControl 来检索一个单独的值或 OwnProps 来枚举所有的值.

对于 DropDownList, ComboBox, ListBoxTab, 如果控件 没有 AltSubmit 选项, 或者如果 ComboBox 的文本与列表项不匹配, 则存储所选项目/Tab 的文本而不是其位置编号. 否则, 将存储 Value(项目的位置编号).

如果单选组中只有一个 Radio 按钮有名称, 则 Submit 将存储当前选中的按钮的编号, 而不是控件的 Value. 1 是第一个单选按钮(根据原来的创建顺序), 2 是第二个, 以此类推. 如果没有选择按钮, 则存储 0.

因为它们不具备输入功能, 排除以下控件: Text, Pic, GroupBox, Button, Progress, Link, StatusBar.

也不包括: ListView, TreeView, ActiveX, Custom.

__Enum

枚举窗口的控件.

For Ctrl in MyGui
For Hwnd, Ctrl in MyGui

返回一个新的枚举器. 这个方法通常不被直接调用. 取而代之的是, Gui 对象被直接传递给 for-loop, 其调用 __Enum 一次, 然后在循环的每次迭代中调用枚举器一次. 每次调用枚举数都会返回下一个控件. For-loop 的变量对应于枚举数的参数, 它们是:

Hwnd

类型: 整数

控件的 HWND. 这只存在于双参数模式中.

Ctrl

类型: Object

控件的 GuiControl 对象.

例如:

For Hwnd, GuiCtrlObj in MyGui
    MsgBox "Control #" A_Index " is " GuiCtrlObj.ClassNN

__New

构造一个新的 Gui 实例.

MyGui.__New(Options, Title, EventObj)

Gui 子类可以覆盖 __New 并调用 super.__New(Options, Title, this) 来处理它自己的事件. 在这种情况下, 主窗口的事件(如关闭) 不会传递一个显式的 Gui 参数, 因为 this 已经包含了对 Gui 的引用.

The Gui retains a reference to EventObj for the purpose of calling event handlers, and releases it when the window is destroyed. If EventObj itself contains a reference to the Gui, this would typically create a circular reference which prevents the Gui from being automatically destroyed. However, an exception is made for when EventObj is the Gui itself, to avoid a circular reference in that case.

如果窗口已经被构造或销毁, 则抛出异常.

属性

BackColor

检索或设置窗口的背景色.

CurrentColor := MyGui.BackColor
MyGui.BackColor := NewColor
是此属性之前设置的当前颜色的 6-位 RGB 值, 如果使用的是默认颜色, 则是一个空字符串.

NewColor 是 16 种主要 HTML 颜色名称之一, 十六进制 RGB 颜色值(0x 前缀可以省略), 纯数字 RGB 颜色值, 或者对于默认颜色指定单词 Default(或空字符串). 例如: "Silver", "FFFFAA", 0xFFFFAA, "Default", "".

默认情况下, 窗口的背景颜色为系统按钮的颜色.

菜单栏及其子菜单的颜色可以这样改变: MyMenuBar.SetColor "White".

要让窗口的背景透明, 请使用 WinSetTransColor. 然而, 如果在进行这样的操作前没有使用 Gui.BackColor 为窗口设置自定义的颜色, 那么按钮也将变成透明的. 要避免此问题, 应首先为窗口设置自定义的颜色, 然后让此颜色透明. 例如:

MyGui.BackColor := "EEAA99"
WinSetTransColor("EEAA99", MyGui)

此外, 如果要移除背景透明的窗口的边框和标题栏, 使用下面的方法: MyGui.Opt("-Caption")

为了阐明上面的情况, 请参阅此页面底部的屏幕显示(OSD) 的例子.

FocusedCtrl

检索窗口的焦点控件的 GuiControl 对象.

GuiCtrlObj := MyGui.FocusedCtrl

注意: 为了达到效果, 一般不能将窗口最小化或隐藏.

Hwnd

检索窗口的窗口句柄(HWND).

CurrentHwnd := MyGui.Hwnd

GUI 的 HWND, 通常与 PostMessage, SendMessageDllCall 一起使用. 它也可以直接用于 WinTitle 参数中.

MarginX

检索或设置边和后续创建的控件之间的水平边距大小.

CurrentValue := MyGui.MarginX
MyGui.MarginX := NewValue

CurrentValue 是当前水平边距的像素数.

NewValue 是在自动定位任何没有明确 X 坐标的控件时, 在窗口左右两边留出的空间像素数. 同时, 边距也被用来确定自动定位的控件之间的水平距离. 最后, 在第一次使用 MyGui.Show 计算窗口的大小时(当没有指定明确的大小时), 会考虑到边距.

默认情况下, 边距与当前选择字体的大小成正比(左右字体高度的 1.25 倍).

MarginY

检索或设置边和后续创建的控件之间的垂直边距大小.

CurrentValue := MyGui.MarginY
MyGui.MarginY := NewValue

CurrentValue 是当前垂直边距的像素数.

NewValue 是在自动定位任何没有明确 Y 坐标的控件时, 在窗口的顶部和底部留出的空间像素数. 同时, 边距也被用来确定自动定位的控件之间的垂直距离. 最后, 在第一次使用 MyGui.Show 计算窗口的大小时(当没有指定明确的大小时), 会考虑到边距.

默认情况下, 边距与当前选择字体的大小成正比(顶部和底部 0.75 倍字体高度).

Name

检索或设置窗口的自定义名称.

CurrentName := MyGui.Name
MyGui.Name := NewName

Title

检索或设置窗口的标题.

CurrentTitle := MyGui.Title
MyGui.Title := NewTitle

__Item

检索与指定名称, 文本, ClassNN 或 HWND 关联的 GuiControl 对象.

GuiCtrlObj := MyGui[Name]
GuiCtrlObj := MyGui.__Item[Name]

使用 Tab 可以在 GUI 窗口中导航, 它会移动键盘焦点到下一个可输入型控件中(跳过移除了 Tabstop 样式的控件). 导航的顺序由控件添加的顺序决定. 当首次显示一个窗口时, 键盘焦点将在首个具有 Tabstop 样式(默认情况下大多数类型的控件都具有) 的可输入型控件上, 除非该控件是一个 Button, 并且有一个默认按钮, 在这种情况下, 后者会具有焦点.

可以在某些控件的名称中包含和符号(&) 来创建此控件的键盘快捷键, 在控件名称中的快捷键字母会加上下划线显示(取决于系统设置). 用户可以通过按下 Alt 和相应的字符来触发这样的快捷键. 对于按钮, 复选框和单选按钮, 按下相应的快捷键等于点击了按钮. 对于 GroupBox 和 Text 控件, 按下相应的快捷键则移动键盘焦点到此控件后(不是指位置, 是创建顺序) 首个具有 tabstop 样式的可输入型控件中. 然而, 如果多个控件含有相同的快捷键, 则按下此快捷键会让键盘焦点在这些控件中交替.

要在上面提及类型的控件中显示一个原义的和符号, 请指定两个连续的和符号, 如此例所示: MyGui.Add("Button",, "Save && Exit").

窗口外观

对于其图标, GUI 窗口使用创建窗口时有效的托盘图标. 因此, 要想拥有不同的图标, 请在创建窗口前更改托盘图标. 例如: TraySetIcon("MyIcon.ico"). 也可以为一个窗口拥有一个不同于其小图标的大图标(大图标显示在 alt-tab 任务切换器中). 这可以通过 LoadPictureSendMessage 来实现; 例如:

iconsize := 32  ; alt-tab 任务切换器中图标的理想尺寸在不同版本的系统中有所不同.
hIcon := LoadPicture("My Icon.ico", "Icon1 w" iconsize " h" iconsize, &imgtype)
MyGui := Gui()
SendMessage(0x80, 1, hIcon, MyGui)  ; 0x80 是 WM_SETICON; 1 表示 ICON_BIG(vs. 0 表示 ICON_SMALL).
MyGui.Show()

由于操作系统的限制, Checkbox, Radio button 和 GroupBox 控件中的文本不是使用默认颜色时将显示为经典主题外观.

相关主题: 窗口的边距.

备注

使用 GuiControl 对象对 GUI 窗口中的单个控件进行操作.

每个 GUI 窗口最多可以包含 11,000 个控件. 然而, 当控件数量超过 5000 时需要谨慎, 因为此时某些类型的控件可能让系统不稳定.

当 Gui 对象被删除时, GUI 窗口会自动销毁, 当它的引用计数达到零时, 就会发生这种情况. 然而, 这通常不会在窗口可见时发生, 因为 Show 会自动增加引用计数. 当窗口可见时, 用户可以与之交互并触发由脚本处理的事件. 当用户关闭窗口或窗口被 Hide 隐藏, ShowSubmit, 这个额外的引用就会被释放.

为了保持 GUI 窗口的 "活力" 而不调用 Show 或保留对其 Gui 对象的引用, 脚本可以使用 ObjAddRef 增加对象的引用计数(在这种情况下, 当不再需要该窗口时, 必须调用 ObjRelease). 例如, 当使用一个隐藏的 GUI 窗口来接收消息时, 或者当窗口被 "外部" 的方法, 如 WinShow 显示时(由这个脚本或任何其他脚本), 就可以这样做.

如果脚本不是因为任何其他原因而持续运行, 它将在最后一个可见的 GUI 关闭后退出; 或者是在最后一个线程完成时退出, 或者是在没有线程运行时立即退出.

GuiControl 对象, GuiFromHwnd, GuiCtrlFromHwnd, 控件类型, ListView, TreeView, Menu 对象, Control 函数, MsgBox, FileSelect, DirSelect

示例

创建弹窗.

MyGui := Gui(, "Title of Window")
MyGui.Opt("+AlwaysOnTop +Disabled -SysMenu +Owner")  ; +Owner 避免显示任务栏按钮.
MyGui.Add("Text",, "Some text to display.")
MyGui.Show("NoActivate")  ; NoActivate 让当前活动窗口继续保持活动状态.

创建一个要求输入姓名的简单输入框.

MyGui := Gui(, "Simple Input Example")
MyGui.Add("Text",, "First name:")
MyGui.Add("Text",, "Last name:")
MyGui.Add("Edit", "vFirstName ym")  ; ym 选项开始一个新的控件列.
MyGui.Add("Edit", "vLastName")
MyGui.Add("Button", "default", "OK").OnEvent("Click", ProcessUserInput)
MyGui.OnEvent("Close", ProcessUserInput)
MyGui.Show()

ProcessUserInput(*)
{
    Saved := MyGui.Submit()  ; 将命名控件的内容保存到一个对象中.
    MsgBox("You entered '" Saved.FirstName " " Saved.LastName "'.")
}

创建带有多个选项卡的选项卡控件, 每个选项卡包含不同的控件与之交互.

MyGui := Gui()
Tab := MyGui.Add("Tab3",, ["First Tab","Second Tab","Third Tab"])
MyGui.Add("CheckBox", "vMyCheckBox", "Sample checkbox") 
Tab.UseTab(2)
MyGui.Add("Radio", "vMyRadio", "Sample radio1")
MyGui.Add("Radio",, "Sample radio2")
Tab.UseTab(3)
MyGui.Add("Edit", "vMyEdit r5")  ; r5 表示 5 行的高度.
Tab.UseTab()  ; 即后续添加的控件将不属于前面那个选项卡控件.
Btn := MyGui.Add("Button", "default xm", "OK")  ; xm 把它放置在左下角.
Btn.OnEvent("Click", ProcessUserInput)
MyGui.OnEvent("Close", ProcessUserInput)
MyGui.OnEvent("Escape", ProcessUserInput)
MyGui.Show()

ProcessUserInput(*)
{
    Saved := MyGui.Submit()  ; 将命名控件的内容保存到一个对象中.
    MsgBox("You entered:`n" Saved.MyCheckBox "`n" Saved.MyRadio "`n" Saved.MyEdit)
}

创建一个显示目录中的文件的列表框.

MyGui := Gui()
MyGui.Add("Text",, "Pick a file to launch from the list below.")
LB := MyGui.Add("ListBox", "w640 r10")
LB.OnEvent("DoubleClick", LaunchFile)
Loop Files, "C:\*.*"  ; 根据您的需要改变此文件夹和通配符模式.
    LB.Add([A_LoopFilePath])
MyGui.Add("Button", "Default", "OK").OnEvent("Click", LaunchFile)
MyGui.Show()

LaunchFile(*)
{
    if MsgBox("Would you like to launch the file or document below?`n`n" LB.Text,, 4) = "No"
        return
    ; 否则, 尝试运行此文件:
    try Run(LB.Text)
    if A_LastError
        MsgBox("Could not launch the specified file. Perhaps it is not associated with anything.")
}

当鼠标移动到特定的控件上时显示相关帮助(使用工具提示).

MyGui := Gui()
MyEdit := MyGui.Add("Edit")
; 在自定义属性中存储工具提示文本:
MyEdit.ToolTip := "This is a tooltip for the control whose name is MyEdit."
MyDDL := MyGui.Add("DropDownList",, ["Red","Green","Blue"])
MyDDL.ToolTip := "Choose a color from the drop-down list."
MyGui.Add("CheckBox",, "This control has no tooltip.")
MyGui.Show()
OnMessage(0x200, On_WM_MOUSEMOVE)

On_WM_MOUSEMOVE(wParam, lParam, msg, Hwnd)
{
    static PrevHwnd := 0
    if (Hwnd != PrevHwnd)
    {
        Text := "", ToolTip() ; 关闭之前的工具提示.
        CurrControl := GuiCtrlFromHwnd(Hwnd)
        if CurrControl
        {
            if !CurrControl.HasProp("ToolTip")
                return ; 此控件没有工具提示.
            Text := CurrControl.ToolTip
            SetTimer () => ToolTip(Text), -1000
            SetTimer () => ToolTip(), -4000 ; 移除工具提示.
        }
        PrevHwnd := Hwnd
    }
}

使用透明窗口进行屏幕显示(OSD).

MyGui := Gui()
MyGui.Opt("+AlwaysOnTop -Caption +ToolWindow")  ; +ToolWindow 避免显示任务栏按钮和 alt-tab 菜单项.
MyGui.BackColor := "EEAA99"  ; 可以是任何 RGB 颜色(下面会变成透明的).
MyGui.SetFont("s32")  ; 设置大字体(32 磅).
CoordText := MyGui.Add("Text", "cLime", "XXXXX YYYYY")  ; XX & YY 用来自动调整窗口大小.
; 让此颜色的所有像素透明且让文本显示为半透明(150):
WinSetTransColor(MyGui.BackColor " 150", MyGui)
SetTimer(UpdateOSD, 200)
UpdateOSD()  ; 立即进行第一次更新而不等待计时器.
MyGui.Show("x0 y400 NoActivate")  ; NoActivate 让当前活动窗口继续保持活动状态.

UpdateOSD(*)
{
    MouseGetPos &MouseX, &MouseY
    CoordText.Value := "X" MouseX ", Y" MouseY
}

在背景图像上移动的进度条.

MyGui := Gui()
MyGui.BackColor := "White"
MyGui.Add("Picture", "x0 y0 h350 w450", A_WinDir "\Web\Wallpaper\Windows\img0.jpg")
MyBtn := MyGui.Add("Button", "Default xp+20 yp+250", "Start the Bar Moving")
MyBtn.OnEvent("Click", MoveBar)
MyProgress := MyGui.Add("Progress", "w416")
MyText := MyGui.Add("Text", "wp")  ; wp 表示 "使用之前的宽度".
MyGui.Show()

MoveBar(*)
{
    Loop Files, A_WinDir "\*.*", "R"
    {
        if (A_Index > 100)
            break
        MyProgress.Value := A_Index
        MyText.Value := A_LoopFileName
        Sleep 50
    }
    MyText.Value := "Bar finished."
}

创建简单的图像查看器.

MyGui := Gui("+Resize")
MyBtn := MyGui.Add("Button", "default", "&Load New Image")
MyBtn.OnEvent("Click", LoadNewImage)
MyRadio := MyGui.Add("Radio", "ym+5 x+10 checked", "Load &actual size")
MyGui.Add("Radio", "ym+5 x+10", "Load to &fit screen")
MyPic := MyGui.Add("Pic", "xm")
MyGui.Show()

LoadNewImage(*)
{
    Image := FileSelect(,, "Select an image:", "Images (*.gif; *.jpg; *.bmp; *.png; *.tif; *.ico; *.cur; *.ani; *.exe; *.dll)")
    if Image = ""
        return
    if (MyRadio.Value)  ; 按实际大小显示图像.
    {
        Width := 0
        Height := 0
    }
    else ; 选择了第二个单选按钮: 按照屏幕的大小显示图像.
    {
        Width := A_ScreenWidth - 28  ; 减去的 28 是用来显示边框和内边缘的空间.
        Height := -1  ; "保持高宽比" 应该是最好的.
    }
    MyPic.Value := Format("*w{1} *h{2} {3}", Width, Height, Image)  ; 载入图像.
    MyGui.Title := Image
    MyGui.Show("xCenter y0 AutoSize")  ; 调整窗口以适应图片尺寸.
}

创建带有菜单栏的简单文本编辑器.


; 创建 MyGui 窗口:
MyGui := Gui("+Resize", "Untitled")  ; 使窗口可以调整大小.

; 为菜单栏创建子菜单:
FileMenu := Menu()
FileMenu.Add("&New", MenuFileNew)
FileMenu.Add("&Open", MenuFileOpen)
FileMenu.Add("&Save", MenuFileSave)
FileMenu.Add("Save &As", MenuFileSaveAs)
FileMenu.Add() ; 分隔线.
FileMenu.Add("E&xit", MenuFileExit)
HelpMenu := Menu()
HelpMenu.Add("&About", MenuHelpAbout)

; 通过附加子菜单来创建菜单栏:
MyMenuBar := MenuBar()
MyMenuBar.Add("&File", FileMenu)
MyMenuBar.Add("&Help", HelpMenu)

; 添加菜单栏到窗口:
MyGui.MenuBar := MyMenuBar

; 创建主编辑控件:
MainEdit := MyGui.Add("Edit", "WantTab W600 R20")

; 应用事件:
MyGui.OnEvent("DropFiles", Gui_DropFiles)
MyGui.OnEvent("Size", Gui_Size)

MenuFileNew()  ; 应用默认设置.
MyGui.Show()  ; 显示窗口.

MenuFileNew(*)
{
    MainEdit.Value := ""  ; 清空编辑控件.
    FileMenu.Disable("3&")  ; 使 &Save 灰色禁用.
    MyGui.Title := "Untitled"
}

MenuFileOpen(*)
{
    MyGui.Opt("+OwnDialogs")  ; 强制用户响应 FileSelectFile 对话框后才能返回到主窗口.
    SelectedFileName := FileSelect(3,, "Open File", "Text Documents (*.txt)")
    if SelectedFileName = "" ; 没有选择文件.
        return
    global CurrentFileName := readContent(SelectedFileName)
}

MenuFileSave(*)
{
    saveContent(CurrentFileName)
}

MenuFileSaveAs(*)
{
    MyGui.Opt("+OwnDialogs")  ; 强制用户响应 FileSelectFile 对话框后才能返回到主窗口.
    SelectedFileName := FileSelect("S16",, "Save File", "Text Documents (*.txt)")
    if SelectedFileName = "" ; 没有选择文件.
        return
    global CurrentFileName := saveContent(SelectedFileName)
}

MenuFileExit(*)  ; 用户从 File 菜单中选择 "Exit".
{
    WinClose()
}

MenuHelpAbout(*)
{
    About := Gui("+owner" MyGui.Hwnd)  ; 让主窗口成为 "about box" 的父窗口.
    MyGui.Opt("+Disabled")  ; 禁用主窗口.
    About.Add("Text",, "Text for about box.")
    About.Add("Button", "Default", "OK").OnEvent("Click", About_Close)
    About.OnEvent("Close", About_Close)
    About.OnEvent("Escape", About_Close)
    About.Show()

    About_Close(*)
    {
        MyGui.Opt("-Disabled")  ; 重新启用主窗口(必须在下一步之前进行).
        About.Destroy()  ; 销毁关于对话框.
    }
}

readContent(FileName)
{
    try
        FileContent := FileRead(FileName)  ; 读取文件的内容到变量中.
    catch
    {
        MsgBox("Could not open '" FileName "'.")
        return
    }
    MainEdit.Value := FileContent  ; 在控件中显示文本.
    FileMenu.Enable("3&")  ; Re-enable &Save.
    MyGui.Title := FileName  ; 在标题栏显示文件名.
    return FileName
}

saveContent(FileName)
{
    try
    {
        if FileExist(FileName)
            FileDelete(FileName)
        FileAppend(MainEdit.Value, FileName)  ; 保存内容到文件.
    }
    catch
    {
        MsgBox("The attempt to overwrite '" FileName "' failed.")
        return
    }
    ; 成功时在标题栏显示文件名(以防 MenuFileSaveAs 被调用的情况):
    MyGui.Title := FileName
    return FileName
}

Gui_DropFiles(thisGui, Ctrl, FileArray, *)  ; 支持拖拽.
{
    CurrentFileName := readContent(FileArray[1])  ; 仅获取首个文件(如果有多个文件的时候).
}

Gui_Size(thisGui, MinMax, Width, Height)
{
    if MinMax = -1  ; 窗口被最小化了. 无需进行操作.
        return
    ; 否则, 窗口的大小被调整过或被最大化了. 调整编辑控件的大小以匹配窗口.
    MainEdit.Move(,, Width-20, Height-20)
}

Demonstrates problems caused by reference cycles.

; Click Open or double-click tray icon to show another GUI.
; Use the menu items, Escape or Close button to see how it responds.
A_TrayMenu.Add("&Open", ShowRefCycleGui)
Persistent

ShowRefCycleGui(*) {
    static n := 0
    g := Gui(, "GUI #" (++n)), g.n := n
    g.MenuBar := mb := MenuBar()   ; g -> mb
    mb.Add("Gui", m := Menu())     ; mb -> m
    m.Add("Hide", (*) => g.Hide()) ; (*) -> g
    m.Add("Destroy", (*) => g.Destroy())
    ; For a GUI event, the callback parameter can be used to avoid a
    ; reference cycle (using the same name prevents accidental capture).
    ; However, Hide() doesn't break the *other* reference cycles.
    g.OnEvent("Escape", (g, *) => g.Hide())
    ; Capturing the variable can work out in our favour.
    g.OnEvent("Close", (*) => g := unset)
    g.Show("w300 h200")
    ; __Delete is not called due to the reference cycle:
    ;   g -> mb -> m -> (*) -> g
    ; unless g is unset by triggering the Close event,
    ; or MenuBar and event handlers are released by Destroy.
    g.__Delete := this => MsgBox("GUI #" this.n " deleted")
}