# TreeView [v1.0.44+]

## Table of Contents

- Introduction and Simple Example
- Options and Styles
- Built-in Functions:
  - Adding, Modifying, and Deleting Items
  - Getting Data Out of a TreeView
  - Setting Icons
- G-Label Notifications
- Remarks
- Examples

## Introduction and Simple Example

A Tree-View displays a hierarchy of items by indenting child items beneath their parents. The most common example is Explorer's tree of drives and folders.

A tree view usually looks like this:

The syntax for creating a TreeView is:

    Gui, Add, TreeView, Options

Here is a working script that creates and displays a simple hierarchy of items:

    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

## Options and Styles for "Gui, Add, TreeView, Options"

AltSubmit: Notifies the script for more types of TreeView events than normal. In other words, the g-label is launched more often. See TreeView Notifications for details.

Background: Specify the word Background followed immediately by a color name (see color chart) or RGB value (the 0x prefix is optional). Examples: `BackgroundSilver`, `BackgroundFFDD99`. If this option is not present, the TreeView initially defaults to the background color set by the last parameter of Gui Color (or if none, the system's default background color). Specifying `BackgroundDefault` applies the system's default background color (usually white). For example, a TreeView can be restored to the default color via `GuiControl, +BackgroundDefault, MyTreeView`.

Buttons: Specify `-Buttons` (minus Buttons) to avoid displaying a plus or minus button to the left of each item that has children.

C: Text color. Specify the letter C followed immediately by a color name (see color chart) or RGB value (the 0x prefix is optional). Examples: `cRed`, `cFF2211`, `c0xFF2211`, `cDefault`.

Checked: Provides a checkbox at the left side of each item. When adding an item, specify the word Check in its options to have the box to start off checked instead of unchecked. The user may either click the checkbox or press the spacebar to check or uncheck an item. To discover which items in a TreeView are currently checked, call TV_GetNext() or TV_Get().

HScroll: Specify `-HScroll` (minus HScroll) to disable horizontal scrolling in the control (in addition, the control will not display any horizontal scroll bar).

ImageList: This is the means by which icons are added to a TreeView. Specify the word ImageList followed immediately by the ImageListID returned from a previous call to IL_Create(). This option has an effect only when creating a TreeView (however, TV_SetImageList() does not have this limitation). Here is a working example:

    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

Lines: Specify `-Lines` (minus Lines) to avoid displaying a network of lines connecting parent items to their children. However, removing these lines also prevents the plus/minus buttons from being shown for top-level items.

ReadOnly: Specify `-ReadOnly` (minus ReadOnly) to allow editing of the text/name of each item. To edit an item, select it then press the `F2` key (see the WantF2 option below). Alternatively, you can click an item once to select it, wait at least half a second, then click the same item again to edit it. After being edited, an item can be alphabetically repositioned among its siblings via the following example:

    Gui, Add, TreeView, -ReadOnly gMyTree  ; For gMyTree, see TreeView's g-label.
    ; ...
    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: Rows of height (upon creation). Specify the letter R followed immediately by the number of rows for which to make room inside the control. For example, `R10` would make the control 10 items tall.

WantF2: Specify `-WantF2` (minus WantF2) to prevent an `F2` keystroke from editing the currently selected item. This setting is ignored unless -ReadOnly is also in effect. Regardless of this setting, the g-label still receives `F2` notifications.

(Unnamed numeric styles): Since styles other than the above are rarely used, they do not have names. See the TreeView styles table for a list.

## Built-in Functions for TreeViews

All of the TreeView functions operate upon the current thread's default GUI window (which can be changed via `Gui, 2:Default`). If the default window does not exist or has no TreeView controls, all functions return zero to indicate the problem.

If the window has more than one TreeView control, by default the functions operate upon the one most recently added. To change this, specify `Gui, TreeView, TreeViewName`, where TreeViewName is the name of the TreeView's associated variable, its ClassNN as shown by Window Spy or [in v1.1.04+] its HWND. Once changed, all existing and future threads will use the indicated TreeView. [v1.1.23+]: A_DefaultTreeView contains the current setting.

Adding, Modifying, and Deleting Items

- TV_Add: Adds a new item to the TreeView.
- TV_Modify: Modifies the attributes and/or name of an item.
- TV_Delete: Deletes the specified item or all items.

Getting Data Out of a TreeView

- TV_GetSelection: Returns the selected item's ID number.
- TV_GetCount: Returns the total number of items in the control.
- TV_GetParent: Returns the specified item's parent as an item ID.
- TV_GetChild: Returns the ID number of the specified item's first/top child.
- TV_GetPrev: Returns the ID number of the sibling above the specified item.
- TV_GetNext: Returns the ID number of the next item below the specified item.
- TV_GetText: Retrieves the text/name of the specified item.
- TV_Get: Returns the ID number of the specified item if it has the specified attribute.

Setting Icons

- TV_SetImageList [v1.1.02+]: Sets an ImageList created beforehand which is used to display icons.

### TV_Add

Adds a new item to the TreeView and returns its unique Item ID number (or 0 upon failure).

    TV_Add(Name, ParentItemID, Options)

Name is the displayed text of the item, which can be text or numeric (including numeric expression results). ParentItemID is the ID number of the new item's parent (omit it or specify 0 to add the item at the top level). When adding a large number of items, performance can be improved by using `GuiControl, -Redraw, MyTreeView` before adding the items, and `GuiControl, +Redraw, MyTreeView` afterward.

#### Options for TV_Add() and TV_Modify()

The Options parameter is a string containing zero or more words from the list below (not case sensitive). Separate each word from the next with a space or tab. To remove an option, precede it with a minus sign. To add an option, a plus sign is permitted but not required.

Bold: Displays the item's name in a bold font. To later un-bold the item, use `TV_Modify(ItemID, "-Bold")`. [v1.1.30.01+]: The word Bold may optionally be followed immediately by a 0 or 1 to indicate the starting state.

Check: Shows a checkmark to the left of the item (if the TreeView has checkboxes). To later uncheck it, use `TV_Modify(ItemID, "-Check")`. The word Check may optionally be followed immediately by a 0 or 1 to indicate the starting state. In other words, both `"Check"` and `"Check" . VarContainingOne` are the same (the period used here is the concatenation operator).

Expand: Expands the item to reveal its children (if any). To later collapse the item, use `TV_Modify(ItemID, "-Expand")`. If there are no children, TV_Modify() returns 0 instead of the item's ID. By contrast, TV_Add() marks the item as expanded in case children are added to it later. Unlike "Select" (below), expanding an item does not automatically expand its parent. Finally, the word Expand may optionally be followed immediately by a 0 or 1 to indicate the starting state. In other words, both `"Expand"` and `"Expand" . VarContainingOne` are the same.

First | Sort | N: These options apply only to TV_Add(). They specify the new item's position relative to its siblings (a sibling is any other item on the same level). If none of these options is present, the new item is added as the last/bottom sibling. Otherwise, specify First to add the item as the first/top sibling, or specify Sort to insert it among its siblings in alphabetical order. If a plain integer (N) is specified, it is assumed to be ID number of the sibling after which to insert the new item (if integer N is the only option present, it does not have to be enclosed in quotes).

Icon: Specify the word Icon followed immediately by the number of this item's icon, which is displayed to the left of the item's name. If this option is absent, the first icon in the ImageList is used. To display a blank icon, specify a number that is larger than the number of icons in the ImageList. If the control lacks an ImageList, no icon is displayed nor is any space reserved for one.

Select: Selects the item. Since only one item at a time can be selected, any previously selected item is automatically de-selected. In addition, this option reveals the newly selected item by expanding its parent(s), if necessary. To find out the current selection, call TV_GetSelection().

Sort: For TV_Modify(), this option alphabetically sorts the children of the specified item. To instead sort all top-level items, use `TV_Modify(0, "Sort")`. If there are no children, 0 is returned instead of the ID of the modified item.

Vis: Ensures that the item is completely visible by scrolling the TreeView and/or expanding its parent, if necessary.

VisFirst: Same as above except that the TreeView is also scrolled so that the item appears at the top, if possible. This option is typically more effective when used with TV_Modify() than with TV_Add().

### TV_Modify

Modifies the attributes and/or name of an item.

    TV_Modify(ItemID , Options, NewName)

It returns the item's own ID upon success or 0 upon failure (or partial failure). When only the first parameter is present, the specified item is selected. When NewName is omitted, the current name is left unchanged. For Options, see the list above.

### TV_Delete

Deletes the specified item or all items.

    TV_Delete(ItemID)

If ItemID is omitted, all items in the TreeView are deleted. Otherwise, only the specified ItemID is deleted. It returns 1 upon success and 0 upon failure.

### TV_GetSelection

Returns the selected item's ID number.

    TV_GetSelection()

### TV_GetCount

Returns the total number of items in the control.

    TV_GetCount()

This function is always instantaneous because the control keeps track of the count.

### TV_GetParent

Returns the specified item's parent as an item ID.

    TV_GetParent(ItemID)

Items at the top level have no parent and thus return 0.

### TV_GetChild

Returns the ID number of the specified item's first/top child (or 0 if none).

    TV_GetChild(ParentItemID)

### TV_GetPrev

Returns the ID number of the sibling above the specified item (or 0 if none).

    TV_GetPrev(ItemID)

### TV_GetNext

Returns the ID number of the next item below the specified item (or 0 if none).

    TV_GetNext(ItemID, ItemType)

This has the following modes:

1. When all parameters are omitted, it returns the ID number of the first/top item in the TreeView (or 0 if none).
2. When only ItemID is present, it returns the ID number of the sibling below the specified item (or 0 if none). If ItemID is 0, it returns the ID number of the first/top item in the TreeView (or 0 if none).
3. When ItemType is "Full" or "F", the next item is retrieved regardless of its relationship to the specified item. This allows the script to easily traverse the entire tree, item by item. For example:

       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%".
       }

4. When ItemType is either "Check", "Checked", or "C", the same behavior as above is used except that any item without a checkmark is skipped over. This allows all checkmarked items in the TreeView to be retrieved, one by one.

### TV_GetText

Retrieves the text/name of the specified ItemID and stores it in OutputVar.

    TV_GetText(OutputVar, ItemID)

If the text is longer than 8191, only the first 8191 characters are retrieved. Upon success, the function returns the item's own ID. Upon failure, it returns 0 (and OutputVar is also made blank).

### TV_Get

Returns the ID number of the specified item if it has the specified attribute.

    TV_Get(ItemID, Attribute)

If the specified item has the specified attribute, its own ItemID is returned. Otherwise, 0 is returned. For Attribute, specify "E", "Expand", or "Expanded" to determine if the item is currently expanded (that is, its children are being displayed); specify "C", "Check", or "Checked" to determine if the item has a checkmark; or specify "B" or "Bold" to determine if the item is currently bold in font.

Note: Since an IF-statement sees any non-zero value as "true", the following two lines are functionally identical: `if TV_Get(ItemID, "Checked") = ItemID` and `if TV_Get(ItemID, "Checked")`.

### TV_SetImageList [v1.1.02+]

Sets or replaces the TreeView's ImageList.

    TV_SetImageList(ImageListID , IconType)

ImageListID is the number returned from a previous call to IL_Create(). IconType is normally omitted, in which case it defaults to 0. Otherwise, specify 2 for state icons (which are not yet directly supported, but could be used via SendMessage). If successful, TV_SetImageList() returns the ImageListID that was previously associated with the TreeView (or 0 if none). Any such detached ImageList should normally be destroyed via IL_Destroy(ImageListID).

## G-Label Notifications (Primary)

A g-label such as `gMySubroutine` may be listed in the control's options. This would cause the MySubroutine label to be launched automatically whenever the user performs an action in the control. This subroutine may consult the built-in variables A_Gui and A_GuiControl to find out which window and TreeView generated the event. More importantly, it may consult A_GuiEvent, which contains one of the following strings or letters (for compatibility with future versions, a script should not assume these are the only possible values):

DoubleClick: The user has double-clicked an item. The variable A_EventInfo contains the item ID.

D: The user has attempted to start dragging an item (there is currently no built-in support for this). The variable A_EventInfo contains the item ID.

d (lowercase D): Same as above except a right-click-drag rather than a left-drag.

e (lowercase E): The user has finished editing an item (the user may edit items only when the TreeView has `-ReadOnly` in its options). The variable A_EventInfo contains the item ID.

S: A new item has been selected, either by the user or the script itself. The variable A_EventInfo contains the newly selected item ID.

## G-Label Notifications (Secondary)

If the TreeView has the word AltSubmit in its options, its g-label is launched more often and A_GuiEvent may contain the following additional values:

Normal: The user has left-clicked an item. The variable A_EventInfo contains the item ID.

RightClick: The user has right-clicked an item. The variable A_EventInfo contains the item ID. In most cases, it is best not to display a menu in response to this. Instead, use the GuiContextMenu label because it also recognizes the Apps key. For example:

    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: The user has begun editing an item (the user may edit items only when the TreeView has -ReadOnly in its options). The variable A_EventInfo contains the item ID.

F: The TreeView has received keyboard focus.

f (lowercase F): The TreeView has lost keyboard focus.

K: The user has pressed a key while the TreeView has focus. A_EventInfo contains the virtual key code of the key, which is a number between 1 and 255. If the key is alphabetic, on most keyboard layouts it can be translated to the corresponding character via `Chr(A_EventInfo)`. `F2` keystrokes are received regardless of WantF2. However, the `Enter` keystroke is not received; to receive it, use a default button as described below.

+ (plus sign): An item has been expanded to reveal its children. The variable A_EventInfo contains the item ID.

- (minus sign): An item has been collapsed to hide its children. The variable A_EventInfo contains the item ID.

## Remarks

The Gui Submit command has no effect on a TreeView control. Therefore, the script may use the TreeView's associated variable (if any) to store other data without concern that it will ever be overwritten.

To detect when the user has pressed `Enter` while a TreeView has focus, use a default button (which can be hidden if desired). For example:

    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

In addition to navigating from item to item with the keyboard, the user may also perform incremental search by typing the first few characters of an item's name. This causes the selection to jump to the nearest matching item.

Although any length of text can be stored in each item of a TreeView, only the first 260 characters are displayed.

Although the theoretical maximum number of items in a TreeView is 65536, item-adding performance will noticeably decrease long before then. This can be alleviated somewhat by using the redraw tip described in TV_Add().

Unlike ListViews, a TreeView's ImageList is not automatically destroyed when the TreeView is destroyed. Therefore, a script should call IL_Destroy(ImageListID) after destroying a TreeView's window if the ImageList will not be used for anything else. However, this is not necessary if the script will soon be exiting because all ImageLists are automatically destroyed at that time.

A script may create more than one TreeView per window. To operate upon a TreeView other than the default one, see built-in functions.

To perform actions such as resizing, hiding, or changing the font of a TreeView, use GuiControl.

Tree View eXtension (TVX) extends TreeViews to support moving, inserting and deleting. It is demonstrated at www.autohotkey.com/forum/topic19021.html

## Related

ListView, Other Control Types, Gui, GuiContextMenu, GuiControl, GuiControlGet, TreeView styles table

## Examples

#1: 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
        IL_Add(ImageListID, "shell32.dll", A_Index)
    ; Create a TreeView and a ListView side-by-side to behave like Windows Explorer:
    Gui, Add, TreeView, vMyTreeView r20 w%TreeViewWidth% gMyTreeView ImageList%ImageListID%
    Gui, Add, ListView, vMyListView 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"))
    }

    MyTreeView:  ; 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.
            break
        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, MyTreeView, % "H" . (A_GuiHeight - 30)  ; -30 for StatusBar and margins.
    GuiControl, Move, MyListView, % "H" . (A_GuiHeight - 30) . " W" . (A_GuiWidth - TreeViewWidth - 30)
    return

    GuiClose:  ; Exit the script when the user closes the TreeView's GUI window.
    ExitApp