Help with TreeView

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Help with TreeView

16 Mar 2014, 03:25

Hi there, I've just discovered the Explorer-like example in the Help file. I have a problem with this section:

Code: Select all

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"))
}
In particular this: "adds to the TreeView all subfolders in the specified folder."

How do I add the "specified folder" as well? The way the script works at the moment, it shows only subfolders and their files so if the specified folder has files in it, they aren't displayed in the listview. I know I could use the parent of the specified folder instead but I only want one folder from the parent.
User avatar
dmg
Posts: 287
Joined: 02 Oct 2013, 01:43
Location: "Twelve days north of Hopeless and a few degrees south of Freezing to Death"
Contact:

Re: Help with TreeView

16 Mar 2014, 04:13

Well, gosh darn it, you finally found something I can't help with! I have never had occasion to work with a TreeView so I have no idea what to do. I will look into it, and if I find anything of note I will post back. Good luck. :geek:
"My dear Mr Gyrth, I am never more serious than when I am joking."
~Albert Campion
------------------------------------------------------------------------
Website | Demo scripts | Blog | External contact
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

16 Mar 2014, 04:22

Oooooooh a puzzler!!!

Well if you're stumped I certainly don't feel bad at not being able to figure it out :-)
hd0202
Posts: 183
Joined: 04 Oct 2013, 03:07
Location: Germany near Cologne

Re: Help with TreeView

17 Mar 2014, 00:54

My suggestion: start with the parent folder of the folder you want to show and ignore the sibling folders :!:

First add some lines after setting TreeRoot:

Code: Select all

TreeRoot = %A_StartMenuCommon%
splitpath, treeroot, rootname
stringgetpos, pos, treeroot, \, R
treeroot := substr(treeroot, 1, pos)
TreeViewWidth := 280
Then change the function AddSubFoldersToTree:

Code: Select all

AddSubFoldersToTree(Folder, ParentItemID = 0)
{
    global rootname
    ; 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.
    {
        if (parentitemid = 0 and a_loopfilename <> rootname)
            continue
        AddSubFoldersToTree(A_LoopFileFullPath, TV_Add(A_LoopFileName, ParentItemID, "Icon4"))
    }
}
Hubert
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Help with TreeView

17 Mar 2014, 04:11

... or maybe:

Code: Select all

...
...
...
; 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...
TreeRootID := TV_Add(TreeRoot, 0, "Expand Icon4")   ; <<<<<<<<<< added!
AddSubFoldersToTree(TreeRoot, TreeRootID)           ; <<<<<<<<<< changed!
SplashTextOff
...
...
...
hd0202
Posts: 183
Joined: 04 Oct 2013, 03:07
Location: Germany near Cologne

Re: Help with TreeView

17 Mar 2014, 04:35

@just me
Your solution was my first thought too :lol:
If it where so simple I had not needed more than one hour for my suggestion - please test both versions :!:

Hubert
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Help with TreeView

17 Mar 2014, 04:52

@hd0202:

Code: Select all

MyTreeView:  ; This subroutine handles user actions (such as clicking).
...
...
...
; SelectedFullPath = %TreeRoot%\%SelectedItemText% ; <<<<<<<<<< commented out!
SelectedFullPath = %SelectedItemText%              ; <<<<<<<<<< added!
...
...
...
;)
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

17 Mar 2014, 05:39

Thanks guys!!!

The code from both of you works great although:

1. just me's expands the treeroot folder in treeview which is what I want, but it adds the FULLPATH of the treeroot folder (not the subfolders) to the treeview which looks horrible with a long path.

2. hd0202's adds only the NAME of the treeroot folder to the treeview which is what I want, but the treeroot folder isn't expanded in the treeview.

A solution to either of those would be fabulous!!! Cheers.
just me
Posts: 9576
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Help with TreeView

17 Mar 2014, 07:03

Merged changes:

Code: Select all

...
; 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...
TreeRoot := RTrim(TreeRoot, "\")                         ; Remove trailing backslashes, if any.
Title := TreeRoot                                        ; Set GUI title to TreeRoot.
SplitPath, TreeRoot, TreeRootName, TreeRootDir           ; Split TreeRoot into TreeRootName and TreeRootDir.
If (TreeRootName)                                        ; If TreeRootName is not empty
   TreeRootID := TV_Add(TreeRootName, 0, "Expand Icon4") ;    add it to the TreeView
Else                                                     ; Else
   TreeRootID := 0                                       ;    set TreeRootId to zero.
AddSubFoldersToTree(TreeRoot, TreeRootID)                ; Call AddSubFolders() passing TreeRoot and TreeRootID
TreeRoot := TreeRootDir                                  ; Set TreeRoot to TreeRootDir.
SplashTextOff

; Display the window and return. The OS will notify the script whenever the user performs an eligible action:
Gui, Show,, %Title%  ; Display the source directory (TreeRoot) in the title bar. <<<<<<<<<< changed!
...
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

17 Mar 2014, 19:30

Thanks just me, I hope I'm right in replacing that code with the previous code between the splashtext commands and making no further changes. Now I have the folder name :-) but no files show in the listview :-( Should I have made a change (or reverted) the other code you supplied (the SelectedFullPath)? Cheers.
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

17 Mar 2014, 20:30

Got it!!! I had to remove this line:

SelectedFullPath = %SelectedItemText%

and replace it with your previously commented out line:

SelectedFullPath = %TreeRoot%\%SelectedItemText% ; <<<<<<<<<< commented out!

Working like a charm now :-) And I've add code so I can launch the files by double-click. Very happy I am. Thanks so much for the help.
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

22 Mar 2014, 17:30

OK I have another small issue. I name a lot of my "important" files and folders by prepending the name with an underscore (eg: _MyFolder, _myfile.ahk) so they "sort" (in usual Explorer-style) to the top. My script (with no defined sort command) puts underscored items at the bottom. I thought this a bit strange given that the default Sort, VarName examples in the help file sort with underscores at the top eg:[The following _example sorts the contents of a file] would sort correctly with _example at the top). So I'm thinking I need to add some kind of sort command to my script and force it to sort the way I want but I have no idea where to place it. This is my script:

Code: Select all

;Opens a file explorer containing files in a_scriptdir

;Using just me's code:
;http://ahkscript.org/boards/viewtopic.php?f=5&t=2777

#SingleInstance force

; Set the root folder for the TreeView. Loading may take a long time if an entire drive such as C:\ is specified:
TreeRoot = %A_ScriptDir%
TreeViewWidth := 280
ListViewWidth := A_ScreenWidth - TreeViewWidth - 450

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 :
Gui, Add, TreeView, vMyTreeView r20 w%TreeViewWidth% gMyTreeView ImageList%ImageListID%
Gui, Add, ListView, vMyListView r20 w%ListViewWidth% x+10 gMyListView AltSubmit, Name|Modified

; Set the ListView's column widths:
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:
Gui, Add, StatusBar
SB_SetParts(60, 85)  ; Create three parts in the bar (the third part fills the remaining width).

; Add folders and their subfolders to the tree. Display the status in case loading takes a long time:
SplashTextOn, 200, 25, Please wait, Loading the tree...
TreeRoot := RTrim(TreeRoot, "\")                         ; Remove trailing backslashes, if any.
SplitPath, TreeRoot, TreeRootName, TreeRootDir           ; Split TreeRoot into TreeRootName and TreeRootDir.
If (TreeRootName)                                        ; If TreeRootName is not empty
   TreeRootID := TV_Add(TreeRootName, 0, "Expand Icon4") ;    add it to the TreeView
Else                                                     ; Else
   TreeRootID := 0                                       ;    set TreeRootId to zero.
AddSubFoldersToTree(TreeRoot, TreeRootID)                ; Call AddSubFolders() passing TreeRoot and TreeRootID
TreeRoot := TreeRootDir                                  ; Set TreeRoot to TreeRootDir.
SplashTextOff

Gui, Show, h550, %TreeRoot%
return

; This function adds to the TreeView all subfolders in the specified folder.
AddSubFoldersToTree(Folder, ParentItemID = 0)
{
    ; 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"))
}

;--------------------------------------------------------------------------------------------------
; What to do when a folder is clicked in treeview
MyTreeView: 
if A_GuiEvent <> S  ; if 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
TotalSize = 0
Loop %SelectedFullPath%\*.*  ; For simplicity, this omits folders so that only files are shown in the ListView.
{
    ;LV_Add("", A_LoopFileName, A_LoopFileTimeModified)
    LV_Add("", A_LoopFileName, A_LoopFileSize . " KB")
    FileCount += 1
    TotalSize += A_LoopFileSize
}
GuiControl, +Redraw, MyListView

; Populate 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

;--------------------------------------------------------------------------------------------------
; What to do when a file is double/right-clicked in listview
MyListView:
if (A_GuiEvent = "DoubleClick")
{
    LV_GetText(RowText, A_EventInfo)  ; Get the text from the row's first field and store it in the var RowText.
    run %SelectedFullPath%\%RowText%
	;exitapp   ;exit the script after selection is made
}
else if (A_GuiEvent = "RightClick")
{
    LV_GetText(RowText, A_EventInfo)  ; Get the text from the row's first field and store it in the var RowText.
    run C:\PortableApps\Notepad++\notepad++.exe "%SelectedFullPath%\%RowText%"
	;exitapp   ;exit the script after selection is made
}
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
Cheers :-)

EDIT: Just discovered the Sort, VarName still doesn't sort underscores to the top if there is a string that starts with a number. The numbers are sorted first then the underscore then alphabetical characters after that.
garry
Posts: 3795
Joined: 22 Dec 2013, 12:50

Re: Help with TreeView

23 Mar 2014, 11:20

EDIT: Just discovered the Sort, VarName still doesn't sort underscores to the top if there is a string that starts with a number. The numbers are sorted first then the underscore then alphabetical characters after that.
add after Guicontrol, +Redraw, MyListView

Code: Select all

;... GuiControl, +Redraw, MyListView
LV_ModifyCol(1, "Logical SortAsc")
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

23 Mar 2014, 18:55

garry wrote:add after Guicontrol, +Redraw, MyListView

Code: Select all

;... GuiControl, +Redraw, MyListView
LV_ModifyCol(1, "Logical SortAsc")
Thanks garry!! You've got me half way there :-) Items in the listview now sort correctly (underscored, numerical, alphabetical) but not in the treeview (hardly surprising since your code was only added to the listview section). Do I add the same code somewhere else for the treeview or is it different code altogether? Cheers :-)
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

23 Mar 2014, 19:04

Got it!! Just added Sort to the options on this line:

AddSubFoldersToTree(A_LoopFileFullPath, TV_Add(A_LoopFileName, ParentItemID, "Icon4 Sort"))

Working all good now, yay!!! Thanks heaps everyone for being so helpful :-)
Guest

Re: Help with TreeView

24 Mar 2014, 03:00

thank you all for the good treeview example
kiwichick , sorry , your solution now sort treeview ( not only listview)
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

24 Mar 2014, 16:52

Thought I may as well post the completed script with the sort commands in case anyone else is interested. It is currently set to show files/folders from A_ScriptDir. Double-clicking a file runs it. Right-clicking a file opens it in Notepad++.

Code: Select all

;Opens a file explorer containing files in a_scriptdir

;Using just me's code:
;http://ahkscript.org/boards/viewtopic.php?f=5&t=2777
;with help from garry for sorting

#SingleInstance force

; Set the root folder for the TreeView. Loading may take a long time if an entire drive such as C:\ is specified:
TreeRoot = %A_ScriptDir%
TreeViewWidth := 280
ListViewWidth := A_ScreenWidth - TreeViewWidth - 450

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 :
Gui, Add, TreeView, vMyTreeView r20 w%TreeViewWidth% gMyTreeView ImageList%ImageListID%
Gui, Add, ListView, vMyListView r20 w%ListViewWidth% x+10 gMyListView AltSubmit, Name|Modified

; Set the ListView's column widths:
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:
Gui, Add, StatusBar
SB_SetParts(60, 85)  ; Create three parts in the bar (the third part fills the remaining width).

; Add folders and their subfolders to the tree. Display the status in case loading takes a long time:
SplashTextOn, 200, 25, Please wait, Loading the tree...
TreeRoot := RTrim(TreeRoot, "\")                         ; Remove trailing backslashes, if any.
SplitPath, TreeRoot, TreeRootName, TreeRootDir           ; Split TreeRoot into TreeRootName and TreeRootDir.
If (TreeRootName)                                        ; If TreeRootName is not empty
   TreeRootID := TV_Add(TreeRootName, 0, "Expand Icon4") ;    add it to the TreeView
Else                                                     ; Else
   TreeRootID := 0                                       ;    set TreeRootId to zero.
AddSubFoldersToTree(TreeRoot, TreeRootID)                ; Call AddSubFolders() passing TreeRoot and TreeRootID
TreeRoot := TreeRootDir                                  ; Set TreeRoot to TreeRootDir.
SplashTextOff

Gui, Show, h550, %TreeRoot%
return

; This function adds to the TreeView all subfolders in the specified folder.
AddSubFoldersToTree(Folder, ParentItemID = 0)
{
    ; 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 Sort"))   ; sort so that underscores and numbers are sorted to top of tree
}

;--------------------------------------------------------------------------------------------------
; What to do when a folder is clicked in treeview
MyTreeView: 
if A_GuiEvent <> S  ; if 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
TotalSize = 0
Loop %SelectedFullPath%\*.*  ; For simplicity, this omits folders so that only files are shown in the ListView.
{
    ;LV_Add("", A_LoopFileName, A_LoopFileTimeModified)
    LV_Add("", A_LoopFileName, A_LoopFileSize . " KB")
    FileCount += 1
    TotalSize += A_LoopFileSize
}
GuiControl, +Redraw, MyListView
LV_ModifyCol(1, "Logical SortAsc")   ; sort so that underscores and numbers are sorted to top of list

; Populate 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

;--------------------------------------------------------------------------------------------------
; What to do when a file is double/right-clicked in listview
MyListView:
if (A_GuiEvent = "DoubleClick")
{
    LV_GetText(RowText, A_EventInfo)  ; Get the text from the row's first field and store it in the var RowText.
    run %SelectedFullPath%\%RowText%
	;exitapp   ;exit the script after selection is made
}
else if (A_GuiEvent = "RightClick")
{
    LV_GetText(RowText, A_EventInfo)  ; Get the text from the row's first field and store it in the var RowText.
    run C:\PortableApps\Notepad++\notepad++.exe "%SelectedFullPath%\%RowText%"
	;exitapp   ;exit the script after selection is made
}
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
Last edited by kiwichick on 24 Mar 2014, 16:59, edited 1 time in total.
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

24 Mar 2014, 16:55

Guest wrote:kiwichick , sorry , your solution now sort treeview ( not only listview)
Hi Guest, I'm the one who's sorry now because I have no idea what you're getting at :-(
garry
Posts: 3795
Joined: 22 Dec 2013, 12:50

Re: Help with TreeView

25 Mar 2014, 06:21

.. aaargh sorry for confusing , Guest was me (garry) ( had problem with login ) , my answer above was not optimal , but you found the solution ....
kiwichick
Posts: 169
Joined: 21 Jan 2014, 22:03

Re: Help with TreeView

25 Mar 2014, 20:12

garry wrote:.. aaargh sorry for confusing , Guest was me (garry) ( had problem with login ) , my answer above was not optimal , but you found the solution ....
All good :-) Thanks for all your help!!!!

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: peter_ahk and 343 guests