Jump to content

Fill a treeview with a drive folder structure


 Share

Recommended Posts

Figured that someone would have code for this already but didn't find it in my searches.

I'm trying to build a Windows Explorer-esk treeview control that would allow the user to define what folders they want my app to monitor.

I don't neseccarily need the whole tree structure of a drive, I'd like to have the user be able to add and remove items from the list.

If however someone has code to do the whole folder sturct of a drvie, that would work as well as I can define the checkbox option.

TIA

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Link to comment
Share on other sites

Here is "five minutes code" (about 20 actually :( ), it's works but I'm not like it, because it SLOW (not try to give it big folder!). Probably I will try to make this better tomorrow, if time allow... Anyway it can give you point.

$rootdir = "C:\your_root_dir\"
$a = _FileSearch($rootdir & "*.*",1)

GUICreate("GUI")
$root = GUICtrlCreateTreeView(5, 5, 200, 300)
Dim $ctrl[$a[0]][3]
For $i = 0 to $a[0] - 1
    $temp = StringSplit(StringTrimLeft($a[$i+1], StringLen($rootdir)), "\")
    If $temp[0] = 1 Then 
        $ctrl[$i][0] = GUICtrlCreateTreeViewItem($temp[1], $root)
        $ctrl[$i][1] = $temp[1]
        $ctrl[$i][2] = 1
    Else
        $parent = $root
        For $j = 1 To $temp[0]
            For $k = $i-1 To 0 Step -1
                If ($temp[$j] = $ctrl[$k][1]) and ($j = $ctrl[$k][2]) Then 
                    $parent = $ctrl[$k][0]
                    ExitLoop
                Endif
            Next
        Next
        $j = $j - 1
        $ctrl[$i][0] = GUICtrlCreateTreeViewItem($temp[$j], $parent)
        $ctrl[$i][1] = $temp[$j]
        $ctrl[$i][2] = $j
    Endif
Next
GUISetState()
While 1
$nMsg = GUIGetMsg()
If $nMsg = -3 Then Exit
Wend

;;;;;;;;;;; Larry's _FileSearch;;;;;;;;;;;;

Func _FileSearch($szMask,$nOption)
    $szRoot = ""
    $hFile = 0
    $szBuffer = ""
    $szReturn = ""
    $szPathList = "*"
    Dim $aNULL[1]

    If Not StringInStr($szMask,"\") Then
         $szRoot = @SCRIPTDIR & "\"
    Else
         While StringInStr($szMask,"\")
              $szRoot = $szRoot & StringLeft($szMask,StringInStr($szMask,"\"))
              $szMask = StringTrimLeft($szMask,StringInStr($szMask,"\"))
         Wend
    EndIf
    If $nOption = 0 Then
         _FileSearchUtil($szRoot, $szMask, $szReturn)
    Else
         While 1
              $hFile = FileFindFirstFile($szRoot & "*.*")
              If $hFile >= 0 Then
                   $szBuffer = FileFindNextFile($hFile)
                   While Not @ERROR
                        If $szBuffer <> "." And $szBuffer <> ".." And _
                             StringInStr(FileGetAttrib($szRoot & $szBuffer),"D") Then _
                             $szPathList = $szPathList & $szRoot & $szBuffer & "*"
                        $szBuffer = FileFindNextFile($hFile)
                   Wend
                   FileClose($hFile)
              EndIf
              _FileSearchUtil($szRoot, $szMask, $szReturn)
              If $szPathList == "*" Then ExitLoop
              $szPathList = StringTrimLeft($szPathList,1)
              $szRoot = StringLeft($szPathList,StringInStr($szPathList,"*")-1) & "\"
              $szPathList = StringTrimLeft($szPathList,StringInStr($szPathList,"*")-1)
         Wend
    EndIf
    If $szReturn = "" Then
         $aNULL[0] = 0
         Return $aNULL
    Else
         Return StringSplit(StringTrimRight($szReturn,1),"*")
    EndIf
EndFunc

Func _FileSearchUtil(ByRef $ROOT, ByRef $MASK, ByRef $RETURN)
    $hFile = FileFindFirstFile($ROOT & $MASK)
    If $hFile >= 0 Then
         $szBuffer = FileFindNextFile($hFile)
         While Not @ERROR
              If $szBuffer <> "." And $szBuffer <> ".." Then _
                   $RETURN = $RETURN & $ROOT & $szBuffer & "*"
              $szBuffer = FileFindNextFile($hFile)
         Wend
         FileClose($hFile)
    EndIf
EndFunc

BTW, if I recall right, Holger works now on explorer tree control. So when done it will be much better anyway :(

Edited by Lazycat
Link to comment
Share on other sites

It gives me an error at line 6.. Array variable subscript badly formatted.:

You just not changed $rootdir to something real.

Might be nice if _FileSearch supported type filtering...would make folder only searches faster (I assume).

Yes, it's support filters, but this is not give many gain in speed, because slow algoritm for parsing lines. Following code is much faster:

#include <GUIConstants.au3>
$rootdir = "C:\Program Files\Internet Explorer\"
GUICreate("GUI")
$hTree = GUICtrlCreateTreeView(5, 5, 300, 200)
_LoadTree($rootdir, "*.*", $hTree)

GUISetState()

While 1
    $nMsg = GUIGetMsg()
    If $nMsg = -3 Then Exit
Wend

Func _LoadTree($sRoot, $sMask, $hParent)
    Local $aFile[1], $nCnt = 1, $newParent
    Local $hSearch = FileFindFirstFile($sRoot & $sMask)
    If $hSearch >= 0 Then
       $sFile = FileFindNextFile($hSearch)
       While not @error
            ReDim $aFile[$nCnt]
            $aFile[$nCnt-1] = $sFile
            $nCnt = $nCnt + 1
            $sFile = FileFindNextFile($hSearch)
       Wend
       FileClose($hSearch)
    EndIf
    For $i = 0 To UBound($aFile) - 1
        If $aFile[$i] == "." or $aFile[$i] == ".." Then ContinueLoop
        If StringInStr(FileGetAttrib($sRoot & "\" & $aFile[$i]), "D") Then
            $newParent = GUICtrlCreateTreeViewItem($aFile[$i], $hParent)
           _LoadTree($sRoot & $aFile[$i] & "\", $sMask, $newParent)
           ContinueLoop
        Endif
        GUICtrlCreateTreeViewItem($aFile[$i], $hParent)
    Next
EndFunc

But it use simple recursion, so if your folders are 384 levels deep :( (Autoit recursion limit) you will have troubles :( Also with many files you can easily reach GUI controls limit. So this is only temporary and limited solution.

Link to comment
Share on other sites

This works nicely...but if you just want folders, move GUICtrlCreateTreeViewItem into the for...next loop like this:

For $i = 0 To UBound($aFile) - 1
        If $aFile[$i] == "." or $aFile[$i] == ".." Then ContinueLoop
        If StringInStr(FileGetAttrib($sRoot & "\" & $aFile[$i]), "D") Then
            $newParent = GUICtrlCreateTreeViewItem($aFile[$i], $hParent)
           _LoadTree($sRoot & $aFile[$i] & "\", $sMask, $newParent)
           ContinueLoop
           GUICtrlCreateTreeViewItem($aFile[$i], $hParent)
        Endif
    Next

All I know is now I get all the folders listed...before (when files were included) I got up to 'C's in my folder list. I'm hitting the recursion limit like you specified or the control limit.

Thanks for the code.

Sean Shrum :: http://www.shrum.net

All my published AU3-based apps and utilities

'Make it idiot-proof, and someone will make a better idiot'

 

Link to comment
Share on other sites

First or second sample? If first - forget this code, it's stupid and full of bugs. I'm always curse out myself - not code nothing at late evening :(

<{POST_SNAPBACK}>

second version works, my fault - AGAIN! :(

EDIT: Tried on a whole harddrive, it only create items for the first 5 out of 15 folders, including subfolders : looked trough the tree, and it haven't created them under something else.. simply not there..!

Edited by Wb-FreeKill
Link to comment
Share on other sites

EDIT: Tried on a whole harddrive, it only create items for the first 5 out of 15 folders, including subfolders  looked trough the tree, and it haven't created them under something else.. simply not there..!

"Maximum number of GUI controls per window: 4096". Because each tree item is actually control, you just reached it limit...

Link to comment
Share on other sites

  • 1 month later...

Why not use a FileSelectFolder dialog, retireve the desired folder name and then stuff that into your list box? You'd still end up with a list of folders.

Figured that someone would have code for this already but didn't find it in my searches.

I'm trying to build a Windows Explorer-esk treeview control that would allow the user to define what folders they want my app to monitor.

I don't neseccarily need the whole tree structure of a drive, I'd like to have the user be able to add and remove items from the list.

If however someone has code to do the whole folder sturct of a drvie, that would work as well as I can define the checkbox option.

TIA

<{POST_SNAPBACK}>

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...