TreeView [v1.0.44+]

目录

入门和简单示例

Tree-View 通过缩进父项目下的子项目来显示出层级关系. 最常见的例子是资源管理器的驱动器和文件夹树.

TreeView 通常看起来像这样:

TreeView

创建 TreeView 的语法为:

Gui, Add, TreeView, Options

这是一个创建和显示简单项目层次结构的可运行脚本:

Gui, Add, TreeView
P1 := TV_Add("First parent")
P1C1 := TV_Add("Parent 1's first child", P1)  ; 指定 P1 为此项目的父项目.
P2 := TV_Add("Second parent")
P2C1 := TV_Add("Parent 2's first child", P2)
P2C2 := TV_Add("Parent 2's second child", P2)
P2C2C1 := TV_Add("Child 2's first child", P2C2)

Gui, Show  ; 显示窗口及其 TreeView.
return

GuiClose:  ; 当用户关闭 TreeView 所在的 GUI 窗口时退出脚本.
ExitApp

参数

Options

除了常规选项和样式之外, 以下内容也是被支持或值得关注的:

BackgroundColor: 背景颜色. 指定 Color 为颜色名称(请参阅颜色图表) 或 RGB 值(0x 前缀是均可选的). 例如: BackgroundSilver, BackgroundFFDD99. 如果此选项不存在, 则 TreeView 初始默认的背景颜色由 Gui ColorControlColor 参数设置(如果没有, 则使用系统默认的背景颜色). 指定 BackgroundDefault 来应用系统的默认背景颜色(通常为白色). 例如, 使用 GuiControl, +BackgroundDefault, MyTreeView 可以把 TreeView 恢复为默认的颜色.

Buttons: 指定 -Buttons(负 Buttons) 来避免在每个含有子项目的项目左边显示加号或减号按钮.

CColor: 文本颜色. 指定 Color 为颜色名称(请参阅颜色图表) 或 RGB 值(0x 前缀是均可选的). 例如: cRed, cFF2211, c0xFF2211, cDefault.

Checked: 在每项的左边提供一个复选框. 当添加项目时, 在其选项中指定单词 Check 来让复选框初始为选中而不是未选中状态. 用户可以点击复选框或按下空格键来选中或取消选中项目. 要找出 TreeView 中当前选中了哪些项目, 请调用 TV_GetNext()TV_Get().

HScroll: 指定 -HScroll(负 HScroll) 来禁用控件中的水平滚动(而且控件将不显示水平滚动条).

ImageListID: 这是把图标添加到 TreeView 的方法. 指定 ID 为上次调用 IL_Create() 返回的 ImageList 的 ID. 此选项仅在创建 TreeView 时才有效果. [v1.1.02+]: 此外, 可以使用 TV_SetImageList() , 而不受前面提到的限制. 有关详情, 请参阅 ImageLists.

Lines: 指定 -Lines(负 Lines) 来避免显示连接父项目和它们的子项目之间的网状线. 但是, 移除这些线也阻止了顶级项目坐标加号/减号按钮的显示.

ReadOnly: 指定 -ReadOnly(负 ReadOnly) 来允许编辑每项的文本/名称. 要编辑某项, 请选择它接着按下 F2(请参阅下面的 WantF2 选项). 或者, 您可以对某个项目点击一次来选择它, 至少等半秒, 然后再次点击同一项目进行编辑. 编辑后, 可以对一个项目在其同级项目之间按字母顺序进行重新定位, 如示例 #1 所示.

WantF2: 指定 -WantF2(负 WantF2) 来禁止使用 F2编辑当前选择的项目. 仅当 -ReadOnly 也有效时此设置才不会被忽略. 不论此设置如何, g-标签仍会接收到 F2 通知.

GLabel: 当用户在控件中执行动作时, g-标签会自动运行. 如果控件含有 AltSubmit 选项, 则 g-标签会更频繁地启动. 有关详情, 请参阅 TreeView 通知.

Wn: 设置控件的宽度. 例如, 指定 w400 将使该控件的宽度为 400 像素. 如果忽略, 则默认为当前字体大小的 30 倍.

RnHn: 设置控件的高度. 例如, 指定 r7 将在控件内预留 7 行空间, 而 h400 将设置其高度为 400 像素. 如果同时省略 R 和 H, 默认为 5 行.

(未命名的数字样式): 由于上述样式之外的其他样式很少使用, 所以它们没有名称. 有关列表, 请参阅 TreeView 样式列表.

内置函数

以下函数操作于当前线程的默认 GUI 窗口(这可以使用 Gui Default 进行改变). 如果默认窗口不存在或不含有 TreeView 控件, 则函数返回零来表明此问题.

如果窗口中含有多个 TreeView 控件, 则默认情况下函数操作于最近添加的那个. 要改变这种情况, 请指定 Gui, TreeView, TreeViewName, 其中 TreeViewName 为 TreeView 的关联变量的名称或 Window Spy 中显示的其 ClassNN 或在 [v1.1.04+] 中它的 HWND. 一旦改变后, 所有现有和将来的线程都会使用指定的 TreeView. [v1.1.23+]: A_DefaultTreeView 包含当前设置.

项目函数:

检索函数:

其他函数:

TV_Add

添加新的项目到 TreeView.

ItemID := TV_Add(Name, ParentItemID, Options)

参数

Name

项目显示的文本, 它可以为文本或数值(包括数值的表达式结果).

ParentItemID

如果为空或省略, 默认为 0, 这意味着项目将被添加到顶级. 否则, 请指定新项目的父项的 ID.

Options

如果为空或省略, 则默认为无选项. 否则, 从下面的列表中指定一个或多个选项(不区分大小写). 选项间使用空格或 tab 分隔. 要移除选项, 请在选项前加上负号. 要添加选项, 允许使用加号, 但不是必需的.

Bold: 用粗体显示项目的名称. 以后要取消项目名称的粗体显示, 请使用 TV_Modify(ItemID, "-Bold"). [v1.1.30.01+]: 单词 Bold 后可以可选地紧跟着 0 或 1 以指示起始状态.

Check: 在项目的坐标显示一个复选标记(需要 TreeView 具有复选框). 以后要取消复选它, 请使用 TV_Modify(ItemID, "-Check"). 在单词 Check 后可以紧跟着 0 或 1 来表示初始状态. 换句话说, "Check""Check" . VarContainingOne 是相同的(这里中间使用的是连接运算符).

Expand: 展开此项以让其子项目显示出来(如果有). 以后要折叠项目, 请使用 TV_Modify(ItemID, "-Expand"). 如果没有子项目, 那么 TV_Modify() 返回 0 而不是它的项目 ID. 与之相比, TV_Add() 标记此项目为展开的以防以后要添加子项目. 与下面的 Select 选项不同, 展开一个项目不会自动展开其父项目. 最后, 在单词 Expand 后可以紧跟着 0 或 1 来表示初始状态. 换句话说, "Expand""Expand" . VarContainingOne 是相同的.

First | Sort | N: 这些选项仅适用于 TV_Add(). 它们指定新项目相对于其同级项目的位置(此处 同级项目 是同一级别的其他任何项目). 如果这些选项都不存在, 则新项目被添加到同级项目的最后一个/底部. 否则, 请指定单词 First 来添加项目到同级项目的第一个/顶部, 或指定单词 Sort 来按字母顺序插入新项目到同级项目中间. 如果指定一个纯整数 N, 则假定它为同级项目的 ID 号, 新项目会被插入到它的后面(如果 N是唯一使用的选项, 则它不需要括在引号中).

Icon: 指定单词 Icon 后紧跟着此项目图标的编号, 项目图标显示在项目名称的左边. 如果此选项不存在, 则使用图像列表中的首个图标. 要显示空白图标, 请指定一个大于图像列表中图标数目的数字. 如果控件没有图像列表, 则既不显示图标也不为图标保留空间.

Select: 选择项目. 因为一次只能选择一个项目, 此时任何原来选择的项目会自动取消选择. 此外, 如果有必要此选项会展开其父项目以显示新选择的项目. 要找出当前选择的项目, 请使用 TV_GetSelection().

Sort: 对于 TV_Modify(), 此选项按字母顺序排列指定项目的子项目. 要对所有顶级项目进行排序, 请使用 TV_Modify(0, "Sort"). 如果不含子项目, 则返回 0 而不是所修改项目的 ID.

Vis: 通过滚动 TreeView 和/或展开其父项目(必要时) 来确保此项完全可见.

VisFirst: 和上面一样, 不过在可行时它还会滚动 TreeView 使得此项显示在最上面. 此选项与 TV_Modify() 一起使用比与 TV_Add() 通常更有效.

返回值

成功时, 函数返回新添加项目的唯一 ID. 失败时, 返回 0.

备注

当添加大量项目时, 在添加项目前使用 GuiControl, -Redraw, MyTreeView 并且在添加项目后使用 GuiControl, +Redraw, MyTreeView 可以提升性能.

TV_Modify

修改项目的属性和/或名称.

ItemID := TV_Modify(ItemID , Options, NewName)

参数

ItemID

要修改的项目的 ID 号.

Options

如果和 NewName 参数一起省略, 则选择项目. 否则, 请指定上表中的一个或多个选项.

NewName

如果省略, 则保持当前名称不变. 否则, 请指定项目的新名称.

返回值

成功时, 函数返回项目自己的 ID. 失败时(或部分失败), 返回 0.

TV_Delete

删除指定项目或所有项目.

IsDeleted := TV_Delete(ItemID)

参数

ItemID

如果为空或省略, 则删除 TreeView 中的 所有 项目. 否则, 请指定要删除项目的 ID 号.

返回值

成功时, 函数返回 1(true). 失败时, 返回 0(false).

TV_GetSelection

返回选择项目的 ID 号.

ItemID := TV_GetSelection()

返回值

函数返回选择项目的 ID 号.

TV_GetCount

返回控件中项目的总数.

Count := TV_GetCount()

返回值

函数返回控件中项目的总数. 该值总是即时返回的, 因为控件会跟踪此计数.

TV_GetParent

返回指定项目的父项目的 ID 号.

ParentItemID := TV_GetParent(ItemID)

参数

ItemID

要检查的项目的 ID 号.

返回值

函数返回指定项目的父项目的 ID 号. 如果项目没有父项目, 返回 0, 这适用于所有顶级项目.

TV_GetChild

返回指定项目的第一个/最上面的子项目的 ID 号.

ChildItemID := TV_GetChild(ItemID)

参数

ItemID

要检查的项目的 ID 号. 如果为 0, 返回 TreeView 中第一个/顶层项目的 ID 号.

返回值

函数返回指定项目的第一个/最上面的子项目的 ID 号. 如果没有子项目, 返回 0.

TV_GetPrev

返回指定项目上一个的同级项目的 ID 号.

PrevItemID := TV_GetPrev(ItemID)

参数

ItemID

要检查的项目的 ID 号.

返回值

函数返回指定项目上一个的同级项目的 ID 号. 如果没有同级项目, 返回 0.

TV_GetNext

返回指定项目下一个项目的 ID 号.

NextItemID := TV_GetNext(ItemID, ItemType)

参数

ItemID

如果为空或省略, 默认为 0, 这意味着将返回 TreeView 中第一个/最上面的项目的 ID 号. 否则, 请指定要检查的项目的 ID 号.

ItemType

如果省略, 将检索指定项目下面一个同级项目的 ID 号. 否则, 请指定以下字符串之一:

FullF: 检索下一个项目, 不论它是否为指定项目的同级项目. 这使得脚本可以容易地逐项遍历整个树. 请参阅下面的示例.

Check, CheckedC: 仅获取下一个带复选标记的项目.

返回值

函数返回指定项目下一个项目的 ID 号. 如果没有下一个项目, 返回 0.

备注

下面的示例逐项遍历整个树:

ItemID := 0  ; 这样使得首次循环从树的顶部开始搜索.
Loop
{
    ItemID := TV_GetNext(ItemID, "Full")  ; 把 "Full" 替换为 "Checked" 来找出所有含复选标记的项目.
    if not ItemID  ; 没有更多项目了.
        break
    TV_GetText(ItemText, ItemID)
    MsgBox The next Item is %ItemID%, whose text is "%ItemText%".
}

TV_GetText

检索指定项目的文本/名称.

ItemID := TV_GetText(OutputVar, ItemID)

参数

OutputVar

输出变量的名称, 该变量储存了检索到的文本. 最多只能检索 8191 个字符. 失败时, 变量被置空.

ItemID

要检索其文本的项目的 ID 号.

返回值

成功时, 函数返回项目自己的 ID. 失败时, 返回 0.

TV_Get

如果指定项目含有指定的属性, 则返回它的 ID.

ItemID := TV_Get(ItemID, Attribute)

参数

ItemID

要检查的项目的 ID 号.

Attribute

指定以下字符串之一:

E, ExpandExpanded: 当前展开的项目(即它的子项目是显示的).

C, CheckChecked: 项目具有复选标记.

BBold: 当前字体为粗体的项目.

返回值

如果指定的项目具有指定的属性, 则返回它自己的 ID. 否则, 返回 0.

备注

因为在 IF 语句中把任何非零值视为 "true", 所以下面两行功能相同: if TV_Get(ItemID, "Checked") = ItemIDif TV_Get(ItemID, "Checked").

TV_SetImageList [v1.1.02+]

设置或替换用于显示图标的 ImageList.

PrevImageListID := TV_SetImageList(ImageListID , IconType)

参数

ImageListID

之前调用 IL_Create() 返回的 ID 号.

IconType

如果省略, 默认为 0. 否则, 请指定 2 表示状态图标(目前还不直接支持, 但可以通过 SendMessage 来使用).

返回值

成功时, 函数返回先前与 TreeView 关联的 ImageList ID. 失败时, 返回 0. 任何这样分离的 ImageList 通常应该通过 IL_Destroy() 来销毁.

G-标签通知(主要)

g-标签例如 gMySubroutine 可以使用在 Options 中. 这使得当用户在控件中执行动作时 MySubroutine 标签会自动运行. 此子程序中可引用内置变量 A_GuiA_GuiControl 来找出产生事件的是哪个窗口和 TreeView. 更重要的是, 它可以参考 A_GuiEvent, 其包含下列字符串或字母的其中一个(考虑到和未来版本的兼容性, 脚本不应假定这些字符串或字母是唯一可能的值):

DoubleClick: 用户双击了一项. 变量 A_EventInfo 包含目标项目 ID.

D: 用户尝试开始拖动一个项目(目前还没有内置对拖动项目的支持). 变量 A_EventInfo 包含目标项目 ID.

d(小写的 D): 和上面相同, 除了指右键拖动而不是左键.

e(小写的 E): 用户完成编辑一个项目(只有当 TreeView 选项中含有 -ReadOnly 时用户才可以编辑项目). 变量 A_EventInfo 包含目标项目 ID.

S: 选择了一个新项目, 可以是用户或脚本自己选择的. 变量 A_EventInfo 包含新选择项目的 ID.

G-标签通知(次要)

如果 TreeView 含有 AltSubmit 选项, 则其 g-标签会运行的更频繁并且 A_GuiEvent 还可能包含下列值:

Normal: 用户左键单击了一个项目. 变量 A_EventInfo 包含目标项目 ID.

RightClick: 用户右键单击了一个项目. 变量 A_EventInfo 包含目标项目 ID. 在大多数情况下, 最好不要通过显示菜单来响应此通过. 而应使用 GuiContextMenu 标签, 因为它还能识别 Appskey. 例如:

GuiContextMenu:  ; 运行此标签来响应右键点击或按下 Appskey.
if (A_GuiControl != "MyTreeView")  ; 这个检查是可选的. 让它只为 TreeView 中的点击显示菜单.
    return
; 在提供的坐标处显示菜单, A_GuiX 和 A_GuiY. 应该使用这些
; 因为即使用户按下 Appskey 它们也会提供正确的坐标:
Menu, MyContextMenu, Show, %A_GuiX%, %A_GuiY%
return

E: 用户开始编辑一个项目(只有当 TreeView 含有 -ReadOnly 选项时用户才可以编辑项目). 变量 A_EventInfo 包含目标项目 ID.

F: TreeView 接收到键盘焦点.

f(小写的 F): TreeView 失去了键盘焦点.

K: 当 TreeView 拥有焦点时用户按下了一个键. A_EventInfo 包含此键的虚拟按键代码, 这是介于 1 和 255 之间的数字. 如果此键是字母键, 则在大多数键盘布局中可以使用 Chr(A_EventInfo) 把它转换成相应的字符. 不论 WantF2 选项如何都可以接收到 F2. 然而, 不会接收到 Enter; 要接收它, 请像下面描述的那样使用一个默认按钮.

+(加号): 展开了一个项目来显示它的子项目. 变量 A_EventInfo 包含目标项目 ID.

-(减号): 折叠一个项目来隐藏它的子项目. 变量 A_EventInfo 包含目标项目 ID.

ImageLists

图像列表是指一组大小相同并存储在内存中的图标. 创建时, 每个 ImageList 都是空的. 脚本会重复调用 IL_Add() 函数来向列表中添加图标, 并且每个图标都会被赋予一个从 1 开始的连续编号. 这个编号就是脚本用于在项目名称左侧显示特定图标所依据的数字. 以下是一个有效的示例, 展示了如何将图标放入 TreeView 中:

ImageListID := IL_Create(10)  ; Create an ImageList with initial capacity for 10 icons.
Loop 10  ; Load the ImageList with some standard system icons.
    IL_Add(ImageListID, "shell32.dll", A_Index)
Gui, Add, TreeView, ImageList%ImageListID%
TV_Add("Name of Item", 0, "Icon4")  ; Add an item to the TreeView and give it a folder icon.
Gui, Show

[v1.1.02+]: TV_SetImageList 函数可用作 ImageList 选项的替代方案.

如需了解所有 ImageList 函数的详细信息, 请查阅 ListView 页面.

ListView 不同, 当 TreeView 销毁时它的图像列表不会自动被销毁. 因此, 如果 TreeView 中使用的图像列表以后不再用于其他地方, 则在销毁 TreeView 所在的窗口后脚本应调用 IL_Destroy() 来销毁此图像列表. 然而, 如果脚本很快将退出, 这样做是没必要的, 因为那时所有的图像列表会自动被销毁.

备注

Gui Submit 命令对 TreeView 控件没有效果. 因此, 脚本可以使用 TreeView 的关联变量(如果有) 来保存其他数据而不用担心它会被覆盖.

当 TreeView 拥有焦点时如果要检测到用户按下的 Enter, 请使用默认按钮(如果需要可以隐藏它). 例如:

Gui, Add, Button, Hidden Default, OK
...
ButtonOK:
GuiControlGet, FocusedControl, FocusV
if (FocusedControl != "MyTreeView")
    return
MsgBox % "Enter was pressed. The selected item ID is " . TV_GetSelection()
return

使用键盘除了在项与项之间导航外, 用户还可以通过输入一个项目名称的前几个字符来进行增量搜索. 这使得选择对象跳转到最近匹配的项目.

尽管 TreeView 中的每个项目可以存储任意长度的文本, 但仅显示开始的 260 个字符.

尽管理论上 TreeView 中的项目数可以多达 65536, 然而接近此数目时添加项的性能将显著降低. 通过使用 TV_Add() 中描述的重绘提示可以稍微减轻这种情况.

脚本可以在每个窗口中创建多个 TreeView. 要对非默认的 TreeView 进行操作, 请参阅内置函数.

要执行一些操作, 例如调整大小, 隐藏或改变 TreeView 的字体, 请使用 GuiControl.

Tree View eXtension(TVX)(旧论坛) 扩展了 TreeView 的功能, 增加对插入, 移动和删除的支持.

ListView, 其他控件类型, Gui, GuiContextMenu, GuiControl, GuiControlGet, TreeView 样式表

示例

创建并显示一个包含三个项目的可编辑 TreeView. TreeView 使用 g-标签来处理用户输入. 在这种情况下, 每当用户完成对一个项目的编辑时, 该项目会按照字母顺序重新排列在其同级项目之间. 要测试此示例, 请使用 F2 或延迟双击来编辑一个项目.

Gui, Add, TreeView, -ReadOnly gMyTree
TV_Add("A")
TV_Add("B")
TV_Add("C")
Gui, Show
return

MyTree:
if (A_GuiEvent == "e")  ; The user has finished editing an item (use == for case-sensitive comparison).
    TV_Modify(TV_GetParent(A_EventInfo), "Sort")  ; This works even if the item has no parent.
return

下面是一个比页面顶部的脚本更复杂的可工作的脚本. 它创建并显示一个 TreeView, 其中包含所有用户开始菜单中的所有文件夹. 当用户选择一个文件夹时, 它的内容会显示在右边的 ListView 中(类似于 Windows 资源管理器). 此外, StatusBar 控件会显示当前选择文件夹的信息.

; 下面的文件夹为 TreeView 的根文件夹. 请注意, 如果指定整个驱动器例如 C:\
; 那么可能需要很长加载时间:
TreeRoot := A_StartMenuCommon
TreeViewWidth := 280
ListViewWidth := A_ScreenWidth - TreeViewWidth - 30

; 让用户可以最大化或拖动调整窗口大小:
Gui +Resize

; 创建图像列表并在其中放入一些标准的系统图标:
ImageListID := IL_Create(5)
Loop 5 
    IL_Add(ImageListID, "shell32.dll", A_Index)
; 创建 TreeView 和 ListView, 让它们像在 Windows 资源管理器中那样靠在一起:
Gui, Add, TreeView, vMyTreeView r20 w%TreeViewWidth% gMyTreeView ImageList%ImageListID% ; ImageList
Gui, Add, ListView, vMyListView r20 w%ListViewWidth% x+10, Name|Modified

; 设置 ListView 的列宽(可选的):
Col2Width := 70  ; 缩小到只显示 YYYYMMDD 部分.
LV_ModifyCol(1, ListViewWidth - Col2Width - 30)  ; 允许垂直滚动条.
LV_ModifyCol(2, Col2Width)

; 创建状态栏, 显示文件夹数及其总大小的信息:
Gui, Add, StatusBar
SB_SetParts(60, 85)  ; 在状态栏中创建三个部分(第三部分占用所有剩余宽度).

; 添加文件夹及其子文件夹到树中. 如果加载需要很长时间, 则显示提示信息:
SplashTextOn, 200, 25, TreeView and StatusBar Example, Loading the tree...
AddSubFoldersToTree(TreeRoot)
SplashTextOff

; 显示窗口并返回. 每当用户执行符合条件的动作时, 操作系统会通知脚本:
Gui, Show,, %TreeRoot%  ; 在标题栏中显示源目录(TreeRoot).
return

AddSubFoldersToTree(Folder, ParentItemID = 0)
{
    ; 此函数添加指定文件夹中所有子文件夹到 TreeView.
    ; 它还可以调用自己来递归获取到任意深度的内嵌文件夹.
    Loop %Folder%\*.*, 2  ; 获取所有文件夹的子文件夹.
        AddSubFoldersToTree(A_LoopFileFullPath, TV_Add(A_LoopFileName, ParentItemID, "Icon4"))
}

MyTreeView:  ; 此子程序处理用户的操作(例如点击).
if (A_GuiEvent != "S")  ; 即除了 "选择树中的新项目" 以外的其他操作.
    return  ; 什么都不做.
; 否则, 把选择的文件夹中的内容放入 ListView.
; 首先确定选择的文件夹的完整路径:
TV_GetText(SelectedItemText, A_EventInfo)
ParentID := A_EventInfo
Loop  ; 建立到选择的文件夹的完整路径.
{
    ParentID := TV_GetParent(ParentID)
    if not ParentID  ; 没有更高层的项目了.
        break
    TV_GetText(ParentText, ParentID)
    SelectedItemText := ParentText "\" SelectedItemText
}
SelectedFullPath := TreeRoot "\" SelectedItemText

; 把文件放入 ListView:
LV_Delete()  ; 清除所有行.
GuiControl, -Redraw, MyListView  ; 加载过程中禁用重绘来提升性能.
FileCount := 0  ; 在下面循环之前初始化.
TotalSize := 0
Loop %SelectedFullPath%\*.*  ; 为了简化, 这里省略了文件夹, 所以只在 ListView 中显示文件.
{
    LV_Add("", A_LoopFileName, A_LoopFileTimeModified)
    FileCount += 1
    TotalSize += A_LoopFileSize
}
GuiControl, +Redraw, MyListView

; 更新状态栏的三个部分, 让它们显示当前选择的文件夹的信息:
SB_SetText(FileCount . " files", 1)
SB_SetText(Round(TotalSize / 1024, 1) . " KB", 2)
SB_SetText(SelectedFullPath, 3)
return

GuiSize:  ; 当用户改变窗口大小时扩展/收缩 ListView 和 TreeView.
if (A_EventInfo = 1)  ; 窗口被最小化了. 无需进行操作.
    return
; 否则, 窗口的大小被调整过或被最大化了. 调整控件大小以适应.
GuiControl, Move, MyTreeView, % "H" . (A_GuiHeight - 30)  ; -30 用于状态栏和边距.
GuiControl, Move, MyListView, % "H" . (A_GuiHeight - 30) . " W" . (A_GuiWidth - TreeViewWidth - 30)
return

GuiClose:  ; 当用户关闭 TreeView 所在的 GUI 窗口时退出脚本.
ExitApp