Tree-View 通过在父项目下缩进它们的子项目来显示出项目的层级关系. 最常见的例子是资源管理器的驱动器和文件夹树.
创建 TreeView 的语法为:
这里是一个创建和显示一个简单项目层次结构的有效脚本:
Gui, Add, TreeView P1 := TV_Add("First parent") P1C1 := TV_Add("Parent 1's first child", P1) ; Specify P1 to be this item's parent. 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 ; Show the window and its TreeView. return GuiClose: ; Exit the script when the user closes the TreeView's GUI window. ExitApp
AltSubmit: 通知脚本有比正常更多的 TreeView 事件类型. 换言之, g-label 运行的更频繁.参见 TreeView 通告 获取详情.
Background: 指定单词 Background 接着一个颜色名称 (参见 颜色图表) 或 RGB 值 (0x 前缀是可选的).例如: BackgroundSilver, BackgroundFFDD99. 如果此选项不存在, TreeView 最初默认的背景颜色由 Gui Color (或者如果没有, 则使用系统默认的背景颜色) 的最后一个参数设置. 指定 BackgroundDefault 应用系统的默认背景颜色 (通常为白色).例如, 通过 GuiControl, +BackgroundDefault, MyTreeView 可以把 TreeView 恢复为默认的颜色.
Buttons: 指定 -Buttons (负 Buttons) 以避免在每个含有子项目的项目左边显示一个加号或减号按钮.
C: 文本颜色. 指定字母 C 接着一个颜色名称 (参见 颜色图表) 或 RGB 值 (0x 前缀是可选的).例如: cRed, cFF2211, c0xFF2211, cDefault
Checked: 在每项的左边提供一个复选框. 当 添加 一项时, 在其选项中指定单词 Check 使复选框初始为选中而不是未选中状态. 用户可以点击复选框或按下空格键来选中或取消选中一项. 要找出 TreeView 中当前选中了哪些项目, 请调用 TV_GetNext() 或 TV_Get().
HScroll: 指定 -HScroll (负 HScroll) 来禁用控件中的水平滚动 (此外, 控件将不显示水平滚动条). 在比 Windows 2000/Me 老的操作系统中, 此选项没有效果除非系统中有 Comctl32.dll 5.8 或更高版本 (随应用程序例如 Internet Explorer 5 或更高版本一起发布).
ImageList: 这是通过它把图标添加到 TreeView 的方法. 指定单词 ImageList 接着之前调用 IL_Create() 返回的 ImageListID. 此选项仅当创建 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) ; Omits the DLL's path so that it works on Windows 9x too. 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
Lines: 指定 -Lines (负 Lines) 来避免显示连接父项目和它们的子项目的网状线. 但是, 移除这些线也阻止了顶级项目左边加号/减号按钮的显示.
ReadOnly: 指定 -ReadOnly (负 ReadOnly) 来允许编辑每项的文本/名称. 要编辑某项, 选择它接着按下 F2 键. 或者, 你可以对一个项目点击一次来选择它, 至少等待半秒钟, 然后再次点击同一项目进行编辑. 编辑后, 一个项目可以在其同级项目之间按字母顺序重新定位, 请参考下面的例子:
Gui, Add, TreeView, -ReadOnly gMyTree ; ... 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
R: 行高 (创建时).指定字母 R 接着为在控件中留出空间的行数. 例如, R10 将使控件为 10 个项目的高度.
WantF2: 指定 -WantF2 (负 WantF2) 来禁止使用 F2 键击 编辑 当前选择的项目. 仅当 -ReadOnly 也有效时此设置才不会被忽略.不论此设置如何, g-label 仍会接收到 F2 通告.
(未命名的数字样式): 由于上述以外的其他样式很少使用, 它们没有名称.参见 TreeView 样式表 了解这些样式.
所有的 TreeView 函数操作于当前线程的 默认 GUI 窗口 (这可以通过 Gui, 2:Default 改变). 如果默认窗口不存在或不含有 TreeView 控件, 所有函数返回 0 来表明此问题.
如果窗口含有多个 TreeView 控件, 默认情况下函数操作于最近添加的那个. 要改变这种情况, 请指定 Gui, TreeView, TreeViewName, 此处 TreeViewName 为 TreeView 的 关联变量 的名称或 Window Spy 中显示的其 ClassNN. 一旦改变后, 所有现有和将来的 线程 将使用指定的 TreeView.
TV_Add(Name, [ParentItemID, Options]): 添加一个新项到 TreeView 并且返回其唯一的 项目 ID 号 (当失败时返回 0). Name 为被显示的项目文本, 其可以为文本或数字 (包括数值的 表达式 结果). ParentItemID 为新项目的父项的 ID 号 (忽略它或指定 0 来添加项目到顶级). 当添加大量项目时, 在添加项目前使用 GuiControl, -Redraw, MyTreeView 并且在添加项目后使用 GuiControl, +Redraw, MyTreeView 可以提升性能.
TV_Add() 和 TV_Modify() 的选项: 选项 参数是一个包含零个或多个下面列表中单词的字符串 (不区分大小写). 单词间使用空格或制表符分隔.要移除一个选项, 请在选项前加上一个负号.要添加一个选项, 可以在选项前加上一个正号但不是必需的.
Bold: 用粗体显示项目的名称. 要在以后取消项目名称的粗体显示, 请使用 TV_Modify(ItemID, "-Bold").
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 接着此项目图标的编号, 项目图标显示在项目名称的左边. 如果此选项不存在, 则使用 ImageList 中的首个图标.要显示一个空白图标, 指定一个大于 ImageList 中图标编号的数字.如果控件没有 ImageList, 则既不显示图标也不为图标保留空间.
Select: 选择项目. 因为一次只能选择一个项目, 此时任何原来选择的项目会自动取消选择. 此外, 如果有必要此选项会展开其父项目以显示新选择的项目. 要找出当前的选择, 请调用 TV_GetSelection().
Sort: 对于 TV_Modify(), 此选项按字母顺序排列指定项目的子项目. 要排序所有顶级项目, 请使用 TV_Modify(0, "Sort"). 如果不含子项目, 返回 0 而不是所修改的项目 ID.
Vis: 通过滚动 TreeView 和/或展开其父项目 (如果必要) 确保此项完全可见.
VisFirst: 和上面一样, 除了滚动 TreeView 使得此项显示在最上面, 如果可能的话. 此选项与 TV_Modify() 一起使用比与 TV_Add() 通常更有效.
TV_Modify(ItemID [, Options, NewName]): 修改一个项目的属性和/或名称. 成功时它返回项目自己的 ID 而失败 (或部分失败) 时返回 0. 如果仅存在首个参数, 则 选择 指定的项目. 如果省略 NewName, 则当前名称保持不变. 了解 选项, 参见上面的列表.
TV_Delete([ItemID]): 如果省略 ItemID, 则删除 TreeView 中 所有 项目. 否则, 仅删除指定 ItemID 所在的项目. 成功时返回 1 而失败返回 0.
TV_GetSelection(): 返回选择项目的 ID 号.
TV_GetCount(): 返回控件中项目的总数. 此函数总是即时的因为控件跟踪此计数.
TV_GetParent(ItemID): 返回指定项目的父项目的 ID. 顶级项目没有父项目因此返回 0.
TV_GetChild(ParentItemID): 返回指定项目的第一个/最上面的 子项目的 ID 号 (如果没有则为 0).
TV_GetPrev(ItemID): 返回指定项目上面一个的同级项目的 ID 号 (如果没有则为 0).
TV_GetNext([ItemID, "Checked | Full"]): 此函数含有以下模式:
ItemID = 0 ; Causes the loop's first iteration to start the search at the top of the tree. Loop { ItemID := TV_GetNext(ItemID, "Full") ; Replace "Full" with "Checked" to find all checkmarked items. if not ItemID ; No more items in tree. break TV_GetText(ItemText, ItemID) MsgBox The next Item is %ItemID%, whose text is "%ItemText%". }
TV_GetText(OutputVar, ItemID): 获取指定 ItemID 的文本/名称并保存到 OutputVar 中. 如果文本长于 8191, 则仅获取开始的 8191 个字符.成功时函数返回项目自己的 ID. 失败时返回 0 (并且 OutputVar 也被置空).
TV_Get(ItemID, "Expand | Check | Bold"): 如果指定的项目含有指定的属性, 则返回其自己的 ItemID. 否则返回 0. 在第二个参数中指定 "E", "Expand", 或 "Expanded" 以判断此项当前是 展开的 (即其子项目是显示的); 指定 "C", "Check", 或 "Checked" 以判断此项含有 复选标记; 或指定 "B" 或 "Bold" 以判断此项当前为 粗体 显示.
提示: 因为在 IF声明 中把任何非零值视为 "真", 下面两行功能相同:
一个 g-label 例如 gMySubroutine 可以使用在此控件选项中. 这使得当用户在控件中执行一个动作时 MySubroutine 标签会自动运行. 此子程序中可参考使用内置变量 A_Gui 和 A_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.
如果 TreeView 的 选项 中含有单词 AltSubmit, 其 g-label 会运行的更频繁并且 A_GuiEvent 可能包含下列附加的值:
Normal: 用户左键单击了一个项目.变量 A_EventInfo 包含目标项目 ID.
RightClick: 用户右键单击了一个项目. 变量 A_EventInfo 包含了目标项目 ID. 在大多数情况下, 最好不要显示一个菜单响应此通告. 而是使用 GuiContextMenu 标签 因为它还能识别 Appskey.例如:
GuiContextMenu: ; Launched in response to a right-click or press of the Apps key. if A_GuiControl <> MyTreeView ; This check is optional. It displays the menu only for clicks inside the TreeView. return ; Show the menu at the provided coordinates, A_GuiX and A_GuiY. These should be used ; because they provide correct coordinates even if the user pressed the Apps key: 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.
Gui Submit 命令对 TreeView 控件没有效果. 因此, 脚本可以使用 TreeView 的 关联变量 (如果有的话) 来保存其他数据而不用担心它会被覆盖.
当 TreeView 拥有焦点时如果要检测到用户按下的回车键, 请使用一个 默认按钮 (如果需要可以隐藏它). 例如:
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() 中描述的重绘提示可以稍微减轻这种情况.
与 ListViews 不同, 当 TreeView 销毁时其 ImageList 不会被自动销毁. 因此, 如果 TreeView 中使用的 ImageList 以后不再用于其他地方, 在销毁 TreeView 所在的窗口后脚本应该调用 IL_Destroy(ImageListID) 销毁此 ImageList. 然而, 如果脚本很快将退出这样做是没必要的因为那时所有的 ImageList 会被自动销毁. 相关提示, TreeView 最初的 ImageList 可以被替换为一个新的, 参照此例:
Gui +LastFound SendMessage, 0x1109, 0, NewImageListID, SysTreeView321 ; 0x1109 is TVM_SETIMAGELIST if ErrorLevel ; The TreeView had a previous ImageList. IL_Destroy(ErrorLevel) ; Destroying it is the most typical action.
一个脚本可以在每个窗口中创建多个 TreeView. 要对非默认的 TreeView 进行操作, 请参见 内置函数.
要执行一些操作例如调整大小, 隐藏或改变 TreeView 的字体, 请使用 GuiControl.
Tree View eXtension (TVX) 扩展了 TreeViews 的功能增加支持移动, 插入和删除. 演示的例子参见 www.autohotkey.com/forum/topic19021.html
Windows 95 和 NT4: 如果系统缺少后面这些文件的 4.70 或更高版本: Comctl32.dll, Shell32.dll, and Shlwapi.dll -- 它们随各种更新和应用程序例如 Internet Explorer 3.0 或更高版本一起发布 -- TreeView 的功能受到更多限制并且某些特性可能不会和预期一样.
ListView, 其他控件类型, Gui, GuiContextMenu, GuiControl, GuiControlGet, TreeView 样式表
; The following is a working script that is more elaborate than the one near the top of this page. ; It creates and displays a TreeView containing all folders in the all-users Start Menu. When the ; user selects a folder, its contents are shown in a ListView to the right (like Windows Explorer). ; In addition, a StatusBar control shows information about the currently selected folder. ; The following folder will be the root folder for the TreeView. Note that loading might take a long ; time if an entire drive such as C:\ is specified: TreeRoot = %A_StartMenuCommon% TreeViewWidth := 280 ListViewWidth := A_ScreenWidth - TreeViewWidth - 30 ; Allow the user to maximize or drag-resize the window: Gui +Resize ; Create an ImageList and put some standard system icons into it: ImageListID := IL_Create(5) Loop 5 ; Below omits the DLL's path so that it works on Windows 9x too: IL_Add(ImageListID, "shell32.dll", A_Index) ; Create a TreeView and a ListView side-by-side to behave like Windows Explorer: Gui, Add, TreeView, vMyTree r20 w%TreeViewWidth% gMyTree ImageList%ImageListID% Gui, Add, ListView, vMyList r20 w%ListViewWidth% x+10, Name|Modified ; Set the ListView's column widths (this is optional): Col2Width = 70 ; Narrow to reveal only the YYYYMMDD part. LV_ModifyCol(1, ListViewWidth - Col2Width - 30) ; Allows room for vertical scrollbar. LV_ModifyCol(2, Col2Width) ; Create a Status Bar to give info about the number of files and their total size: Gui, Add, StatusBar SB_SetParts(60, 85) ; Create three parts in the bar (the third part fills all the remaining width). ; Add folders and their subfolders to the tree. Display the status in case loading takes a long time: SplashTextOn, 200, 25, TreeView and StatusBar Example, Loading the tree... AddSubFoldersToTree(TreeRoot) SplashTextOff ; Display the window and return. The OS will notify the script whenever the user performs an eligible action: Gui, Show,, %TreeRoot% ; Display the source directory (TreeRoot) in the title bar. return AddSubFoldersToTree(Folder, ParentItemID = 0) { ; This function adds to the TreeView all subfolders in the specified folder. ; It also calls itself recursively to gather nested folders to any depth. Loop %Folder%\*.*, 2 ; Retrieve all of Folder's sub-folders. AddSubFoldersToTree(A_LoopFileFullPath, TV_Add(A_LoopFileName, ParentItemID, "Icon4")) } MyTree: ; This subroutine handles user actions (such as clicking). if A_GuiEvent <> S ; i.e. an event other than "select new tree item". return ; Do nothing. ; Otherwise, populate the ListView with the contents of the selected folder. ; First determine the full path of the selected folder: TV_GetText(SelectedItemText, A_EventInfo) ParentID := A_EventInfo Loop ; Build the full path to the selected folder. { ParentID := TV_GetParent(ParentID) if not ParentID ; No more ancestors. return TV_GetText(ParentText, ParentID) SelectedItemText = %ParentText%\%SelectedItemText% } SelectedFullPath = %TreeRoot%\%SelectedItemText% ; Put the files into the ListView: LV_Delete() ; Clear all rows. GuiControl, -Redraw, MyListView ; Improve performance by disabling redrawing during load. FileCount = 0 ; Init prior to loop below. TotalSize = 0 Loop %SelectedFullPath%\*.* ; For simplicity, this omits folders so that only files are shown in the ListView. { LV_Add("", A_LoopFileName, A_LoopFileTimeModified) FileCount += 1 TotalSize += A_LoopFileSize } GuiControl, +Redraw, MyListView ; Update the three parts of the status bar to show info about the currently selected folder: SB_SetText(FileCount . " files", 1) SB_SetText(Round(TotalSize / 1024, 1) . " KB", 2) SB_SetText(SelectedFullPath, 3) return GuiSize: ; Expand/shrink the ListView and TreeView in response to user's resizing of window. if A_EventInfo = 1 ; The window has been minimized. No action needed. return ; Otherwise, the window has been resized or maximized. Resize the controls to match. GuiControl, Move, MyTree, % "H" . (A_GuiHeight - 30) ; -30 for StatusBar and margins. GuiControl, Move, MyList, % "H" . (A_GuiHeight - 30) . " W" . (A_GuiWidth - TreeViewWidth - 30) return GuiClose: ; Exit the script when the user closes the TreeView's GUI window. ExitApp