Jump to content

Recommended Posts

Posted (edited)

Posted Image

Hi everyone! I don't know, maybe similar script already exists, but anyway, i hope maybe this code be useful whomever. This UDF will help you to embed your drives and directorys in your TreeView control ;)

ShellTreeView.au3

#include-once
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>

Global $hImage, $hWndTreeView, $objFSO, $hCommonDocs, $hMyDocs

$objFSO = ObjCreate("Scripting.FileSystemObject")

$hImage = _GUIImageList_Create(16, 16, 5, 3)
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 15)
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 6)
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 8)
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 3)
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 7)
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 4)
_GUIImageList_AddIcon($hImage, @SystemDir & "\shell32.dll", 11)

; #FUNCTION# ==================================================================================================
; Name............: _ShellTreeView_Create
; Description.....: Add TreeView items with drives structures
; Syntax..........: _ShellTreeView_Create($hTreeView)
; Parameter(s)....: $hTreeView - Handle to the TreeView control
; Return value(s).: None
; Note(s).........: Tested on AutoIt 3.2.12.1 and Windows XP SP2
; Author(s).......: R.Gilman (a.k.a. rasim)
; ==============================================================================================================
Func _ShellTreeView_Create($hTreeView)
    Local $RootItem, $aDrives, $hChild, $i
    
    $hWndTreeView = $hTreeView
    
    GUIRegisterMsg($WM_NOTIFY, "_TVN_ITEMEXPANDING")
    
    _GUICtrlTreeView_SetNormalImageList($hWndTreeView, $hImage)
    
    $RootItem = _GUICtrlTreeView_Add($hWndTreeView, 0, "My computer", 0, 0)
    
    $aDrives = DriveGetDrive("ALL")
    
    For $i = 1 To $aDrives[0]
        $aDrives[$i] = StringUpper($aDrives[$i])
    Next
    
    For $i = 1 To $aDrives[0]
        Switch DriveGetType($aDrives[$i])
            Case "Removable"
                If ($aDrives[$i] = "a:") Or ($aDrives[$i] = "b:") Then
                    $hChild = _GUICtrlTreeView_AddChild($hWndTreeView, $RootItem, $aDrives[$i], 1, 1)
                    ;_ShellTreeView_GetSelected($aDrives[$i], $hChild)
                Else
                    _GUICtrlTreeView_AddChild($hWndTreeView, $RootItem, $aDrives[$i], 4, 4)
                EndIf
            Case "Fixed"
                $hChild = _GUICtrlTreeView_AddChild($hWndTreeView, $RootItem, $aDrives[$i], 2, 2)
                _ShellTreeView_GetSelected($hWndTreeView, $aDrives[$i], $hChild)
            Case "CDROM"
                $hChild = _GUICtrlTreeView_AddChild($hWndTreeView, $RootItem, $aDrives[$i], 6, 6)
                _ShellTreeView_GetSelected($hWndTreeView, $aDrives[$i], $hChild)
        EndSwitch
    Next
    
    $hCommonDocs = _GUICtrlTreeView_AddChild($hWndTreeView, $RootItem, StringRegExpReplace(@DocumentsCommonDir, "^.*\\", ""), 3, 5)
    _ShellTreeView_GetSelected($hWndTreeView, @DocumentsCommonDir, $hCommonDocs)
    
    $hMyDocs = _GUICtrlTreeView_AddChild($hWndTreeView, $RootItem, StringRegExpReplace(@MyDocumentsDir, "^.*\\", ""), 3, 5)
    _ShellTreeView_GetSelected($hWndTreeView, @MyDocumentsDir, $hMyDocs)
EndFunc   ;==>_ShellTreeView_Create

Func _TVN_ITEMEXPANDING($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $hWndFrom, $iCode
    
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    
    Switch $hWndFrom
        Case $hWndTreeView
            Switch $iCode
                Case $TVN_ITEMEXPANDING
                    Local $tINFO = DllStructCreate($tagNMTREEVIEW, $lParam)
                    Local $hControl = DllStructGetData($tINFO, "NewhItem")
                    
                    If _GUICtrlTreeView_GetExpanded($hWndTreeView, $hControl) = False Then
                        _ShellTreeView_GetSelected($hWndFrom, _GUICtrlTreeView_GetText($hWndFrom, $hControl), $hControl)
                    EndIf
            EndSwitch
    EndSwitch
    
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>_TVN_ITEMEXPANDING

; #FUNCTION# ==================================================================================================
; Name............: _ShellTreeView_GetSelected
; Description.....: Add TreeView items with directorys structures
; Syntax..........: _ShellTreeView_GetSelected($hWndTreeView, $sDrive, $hControl)
; Parameter(s)....: $hTreeView - Handle to the TreeView control
;                   $sDrive    - String contains drive letter or text of selected TreeView item
;                   $hControl  - Child handle
; Return value(s).: A full path to a selected directory
; Note(s).........: Tested on AutoIt 3.2.12.1 and Windows XP SP2
; Author(s).......: R.Gilman (a.k.a. rasim)
; ==============================================================================================================
Func _ShellTreeView_GetSelected($hWndTreeView, $sDrive, $hControl)
    Switch _IsDocDir($sDrive, $hControl)
        Case 1
            $sDrive = @DocumentsCommonDir
        Case 2
            $sDrive = @MyDocumentsDir
    EndSwitch
    
    If Not FileExists($sDrive) Then
        Local $hParent = _GUICtrlTreeView_GetParentHandle($hWndTreeView, $hControl), $iFullPath
        
        If _GUICtrlTreeView_GetText($hWndTreeView, $hParent) = StringRegExpReplace(@DocumentsCommonDir, "^.*\\", "") Then
            $iFullPath = @DocumentsCommonDir & "\" & $sDrive
        ElseIf _GUICtrlTreeView_GetText($hWndTreeView, $hParent) = StringRegExpReplace(@MyDocumentsDir, "^.*\\", "") Then
            $iFullPath = @MyDocumentsDir & "\" & $sDrive
        Else
            $iFullPath = _GUICtrlTreeView_GetText($hWndTreeView, $hParent) & "\" & $sDrive
        EndIf
        
        While 1
            If $hParent = 0 Then Return
            
            If FileExists($iFullPath) Then ExitLoop
            
            $hParent = _GUICtrlTreeView_GetParentHandle($hWndTreeView, $hParent)
            
            If _GUICtrlTreeView_GetText($hWndTreeView, $hParent) = StringRegExpReplace(@DocumentsCommonDir, "^.*\\", "") Then
                $iFullPath = @DocumentsCommonDir & "\" & $iFullPath
            ElseIf _GUICtrlTreeView_GetText($hWndTreeView, $hParent) = StringRegExpReplace(@MyDocumentsDir, "^.*\\", "") Then
                $iFullPath = @DocumentsCommonDir & "\" & $iFullPath
            Else
                $iFullPath = _GUICtrlTreeView_GetText($hWndTreeView, $hParent) & "\" & $iFullPath
            EndIf
        WEnd
        $sDrive = $iFullPath
    EndIf
    
    _GUICtrlTreeView_DeleteChildren($hWndTreeView, $hControl)
    
    Local $objFolder, $colSubFolder, $objSubFolder, $iSubChild, $iSub
    
    $objFolder = $objFSO.GetFolder($sDrive & "\")
    $colSubFolder = $objFolder.SubFolders
    
    For $objSubFolder In $colSubFolder
        $iSubChild = _GUICtrlTreeView_AddChild($hWndTreeView, $hControl, $objSubFolder.Name, 3, 5)
        $iSub = _GetSub($objSubFolder.Path)
        If $iSub Then _GUICtrlTreeView_AddChild($hWndTreeView, $iSubChild, $iSub, 3, 3)
    Next
    Return $sDrive
EndFunc   ;==>_ShellTreeView_GetSelected

Func _IsDocDir($sPath, $hControl)
    If ($sPath = StringRegExpReplace(@DocumentsCommonDir, "^.*\\", "")) And ($hControl = $hCommonDocs) Then
        Return 1
    ElseIf ($sPath = StringRegExpReplace(@MyDocumentsDir, "^.*\\", "")) And ($hControl = $hMyDocs) Then
        Return 2
    Else
        Return False
    EndIf
EndFunc   ;==>_IsDocDir

Func _GetSub($sPath)
    Local $objFolder, $colSubFolder, $objSubFolder
    
    $objFolder = $objFSO.GetFolder($sPath & "\")

    $colSubFolder = $objFolder.SubFolders

    For $objSubFolder In $colSubFolder
        If $objSubFolder.Name Then Return $objSubFolder.Name
    Next
EndFunc   ;==>_GetSub
Edited by rasim
Posted

  mrRevoked said:

I find it preferable to have the drive letters in uppercase though.

Replace

$aDrives = DriveGetDrive("ALL")oÝ÷ Û­«­¢+ØÀÌØíÉ¥ÙÌôÉ¥ÙÑÉ¥Ù ÅÕ½Ðí10ÅÕ½Ðì¤)½ÈÀÌØí¤ôÄѼÀÌØíÉ¥ÙÍlÁt($ÀÌØíÉ¥ÙÍlÀÌØí¥tôMÑÉ¥¹UÁÁÈ ÀÌØíÉ¥ÙÍlÀÌØí¥t¤)9áÐ

in ShellTreeView.au3...

Hmmm, really excellent script... I guessed it will be a real challenge to merge it with Holgers " Tristate GUI TreeView" (http://www.autoitscript.com/forum/index.php?showtopic=28464)...hmmm, maybe when I've finished my current projects ;)...

Thanks for your efforts and Cheers

Poly

This post will be edited again by Polyphem: Tomorrow, 11:55 AM
Posted

Hey guys! Thanks for feedback and advices.

  Quote

I find it preferable to have the drive letters in uppercase though.

Fixed, also added two system directories Common Documents and My Documents. Updated first post ;)
Posted

Nice UDF! But there's little problem with the Documents folders under Vista. I have 2 Documents folders listed, C:\Users\Public\Documents, and C:\Users\<username>\Documents. The Public folders work fine, but my documents all return 0 when I press Select. Oh, and both folders are named "Documents". I suppose it should be something like "Documents" and "Shared Documents" for the public folder.

I know, Vista breaks everything these days....

Posted (edited)

  Polyphem said:

I guessed it will be a real challenge to merge it with Holgers " Tristate GUI TreeView" (http://www.autoitscript.com/forum/index.php?showtopic=28464)...

Hmmmm, no... Not really :), just copy&paste and some adjustments to the variables... but I guess now theres some junk in the functions... This is what I got so far, currently trying to pass the checked boxes fullpath to an array. So don't wonder bout the results when clicking "Checked Items", work-in-progress.

Merged TristateTreeViewLib.au3 into ShellTreeView.au3 and changed the ShellTreeView_Example.au3 a little. Added TristateTreeViewLib.au3 to zip file for reference only.

Will continue to try in the evening >_<...

Have fun and Cheers

Poly

Edited by Polyphem
This post will be edited again by Polyphem: Tomorrow, 11:55 AM
Posted

  wraithdu said:

Nice UDF! But there's little problem with the Documents folders under Vista. I have 2 Documents folders listed, C:\Users\Public\Documents, and C:\Users\<username>\Documents. The Public folders work fine, but my documents all return 0 when I press Select. Oh, and both folders are named "Documents". I suppose it should be something like "Documents" and "Shared Documents" for the public folder.

I know, Vista breaks everything these days....

Hi. I can't check how this UDF works under Vista, because i not have a Vista. :) But you can make this UDF to properly works under Vista, just need little path correction, you may check the Windows version on UDF starting, e.g.

If @OSVersion = "WIN_VISTA" Then...

>_<

Posted

Hi rasim,

I've extended your UDF.

Most substantial of changes is the ability to add paths dynamically.

There's still some bugs that need to be worked out, and there could be possible speed improvements, but it might give you some ideas.

Example

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiTreeView.au3>
#include <ShellTreeView.au3>

$hGUI = GUICreate("Shell TreeView Demo", 300, 340)

$SelectButton = GUICtrlCreateButton("Select", 20, 300, 75, 23)

$CloseButton = GUICtrlCreateButton("Close", 207, 300, 75, 23)

$hTreeView = _GUICtrlTreeView_Create($hGUI, 20, 20, 260, 260, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT), _
                                     $WS_EX_CLIENTEDGE)

_ShellTreeView_Init()
_ShellTreeView_Create($hTreeView)
_ShellTreeView_AddPath($hTreeView, @DesktopDir, "It's ALL Mine!")
_ShellTreeView_AddPath($hTreeView, @DocumentsCommonDir)
_ShellTreeView_AddPath($hTreeView, @MyDocumentsDir)

GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE, $CloseButton
            _ShellTreeView_End()
            Exit
        Case $SelectButton
            $hSelect = _GUICtrlTreeView_GetSelection($hTreeView)
            If $hSelect Then
                $sText = _GUICtrlTreeView_GetText($hTreeView, $hSelect)
                MsgBox(64, "Info", _ShellTreeView_GetSelected($hTreeView, $sText, $hSelect), 0, $hGUI)
            EndIf
    EndSwitch
WEndoÝ÷ Ù@Å
^jëh×6#include-once
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>

; #INDEX# =======================================================================================================================
; Title .........: ShellTreeView
; AutoIt Version: 3.2.3++
; Language:       English
; Description ...: Shell Tree view
; ===============================================================================================================================

; #VARIABLES# ===================================================================================================================
Global $STV_FSOBJ, $STV_IMAGE, $STV_TREEVIEW
Global $STVH_ROOT
Global $STVH_AV_ITEMS[1][3]

; #FUNCTION# ==================================================================================================
; Name............: _ShellTreeView_Init
; Description.....: Iniates treeview shell
; Syntax..........: _ShellTreeView_Init()
; Parameter(s)....: None
; Return value(s).: None
; Note(s).........: Tested on AutoIt 3.2.12.1 and Windows XP SP2
; Author(s).......: mrRevoked
; ==============================================================================================================
Func _ShellTreeView_Init()
    If $STV_FSOBJ Then Return ; already created
    Dim $STV_FSOBJ = ObjCreate("Scripting.FileSystemObject")
    If @error Then Return SetError(1, 0, 0)
    
    Dim $STV_IMAGE = _GUIImageList_Create(16, 16, 5, 3)
    _GUIImageList_AddIcon($STV_IMAGE, @SystemDir & "\shell32.dll", 15)
    _GUIImageList_AddIcon($STV_IMAGE, @SystemDir & "\shell32.dll", 6)
    _GUIImageList_AddIcon($STV_IMAGE, @SystemDir & "\shell32.dll", 8)
    _GUIImageList_AddIcon($STV_IMAGE, @SystemDir & "\shell32.dll", 3)
    _GUIImageList_AddIcon($STV_IMAGE, @SystemDir & "\shell32.dll", 7)
    _GUIImageList_AddIcon($STV_IMAGE, @SystemDir & "\shell32.dll", 4)
    _GUIImageList_AddIcon($STV_IMAGE, @SystemDir & "\shell32.dll", 11)
EndFunc

; #FUNCTION# ==================================================================================================
; Name............: _ShellTreeView_End
; Description.....: Removes object from memory
; Syntax..........: _ShellTreeView_End()
; Parameter(s)....: None
; Return value(s).: None
; Note(s).........: Tested on AutoIt 3.2.12.1 and Windows XP SP2
; Author(s).......: mrRevoked
; ==============================================================================================================
Func _ShellTreeView_End()
    If Not $STV_FSOBJ Then Return ; already created
    Dim $STV_FSOBJ = 0
EndFunc

; #FUNCTION# ==================================================================================================
; Name............: _ShellTreeView_Create
; Description.....: Add TreeView items with drives structures
; Syntax..........: _ShellTreeView_Create($hTreeView)
; Parameter(s)....: $hTreeView - Handle to the TreeView control
; Return value(s).: None
; Note(s).........: Tested on AutoIt 3.2.12.1 and Windows XP SP2
; Author(s).......: R.Gilman (a.k.a. rasim)
; Modified........: mrRevoked
; ==============================================================================================================
Func _ShellTreeView_Create($hTreeView, $sName = "My Computer")
    If Not IsObj($STV_FSOBJ) Then _ShellTreeView_Init()
    If @error Then Return SetError(1, 0, 0)
    
    Local $STVH_ROOT, $aDrives, $hChild, $i
   
    $STV_TREEVIEW = $hTreeView
   
    GUIRegisterMsg($WM_NOTIFY, "_TVN_ITEMEXPANDING")
   
    _GUICtrlTreeView_SetNormalImageList($STV_TREEVIEW, $STV_IMAGE)
   
    $STVH_ROOT = _GUICtrlTreeView_Add($STV_TREEVIEW, 0, $sName, 0, 0)
   
    $aDrives = DriveGetDrive("ALL")
   
    For $i = 1 To $aDrives[0]
        $aDrives[$i] = StringUpper($aDrives[$i])
        
        Switch DriveGetType($aDrives[$i])
            Case "Removable"
                If ($aDrives[$i] = "A:") Or ($aDrives[$i] = "B:") Then
                    $hChild = _GUICtrlTreeView_AddChild($STV_TREEVIEW, $STVH_ROOT, $aDrives[$i], 1, 1)
                Else
                    $hChild = _GUICtrlTreeView_AddChild($STV_TREEVIEW, $STVH_ROOT, $aDrives[$i], 4, 4)
                EndIf
            Case "Fixed"
                $hChild = _GUICtrlTreeView_AddChild($STV_TREEVIEW, $STVH_ROOT, $aDrives[$i], 2, 2)
            Case "CDROM"
                $hChild = _GUICtrlTreeView_AddChild($STV_TREEVIEW, $STVH_ROOT, $aDrives[$i], 6, 6)
        EndSwitch
        _ShellTreeView_GetSelected($STV_TREEVIEW, $aDrives[$i], $hChild)
    Next
    
    Return $STVH_ROOT
EndFunc   ;==>_ShellTreeView_Create


; #FUNCTION# ==================================================================================================
; Name............: _ShellTreeView_AddPath
; Description.....: Add a TreeView item
; Syntax..........: _ShellTreeView_AddPath($hTreeView, $szFilePath)
; Parameter(s)....: $hTreeView - Handle to the TreeView control
; Return value(s).: None
; Note(s).........: Tested on AutoIt 3.2.12.1 and Windows XP SP2
; Author(s).......: mrRevoked
; ==============================================================================================================
Func _ShellTreeView_AddPath($hTreeView, $szFilePath, $szItemPath = "")
    If Not IsArray($STVH_AV_ITEMS) Then Return SetError(1, 0, 0)
        
    If $szItemPath = "" Then $szItemPath = StringRegExpReplace($szFilePath, "^.*\\", "")
    Local $iItemID = _GUICtrlTreeView_AddChild($hTreeView, $STVH_ROOT, $szItemPath, 3, 5)
    
    $STVH_AV_ITEMS[0][0] += 1
    ReDim $STVH_AV_ITEMS[$STVH_AV_ITEMS[0][0] + 1][3]
    $STVH_AV_ITEMS[$STVH_AV_ITEMS[0][0]][0] = $iItemID
    $STVH_AV_ITEMS[$STVH_AV_ITEMS[0][0]][1] = $szItemPath
    $STVH_AV_ITEMS[$STVH_AV_ITEMS[0][0]][2] = $szFilePath
    
    _ShellTreeView_GetSelected($STV_TREEVIEW, $szFilePath, $iItemID)
    
    Return 1
EndFunc

; proposed function <TODO
Func _ShellTreeView_DeleteItem()
    Return 0
EndFunc

; proposed function <TODO
Func _ShellTreeView_SetSelected()
    Return 0
EndFunc

; #FUNCTION# ==================================================================================================
; Name............: _ShellTreeView_GetSelected
; Description.....: Add TreeView items with directorys structures
; Syntax..........: _ShellTreeView_GetSelected($STV_TREEVIEW, $sDrive, $hControl)
; Parameter(s)....: $hTreeView - Handle to the TreeView control
;               $sDrive    - String contains drive letter or text of selected TreeView item
;               $hControl  - Child handle
; Return value(s).: A full path to a selected directory
; Note(s).........: Tested on AutoIt 3.2.12.1 and Windows XP SP2
; Author(s).......: R.Gilman (a.k.a. rasim)
; Modified........: mrRevoked
; ==============================================================================================================
Func _ShellTreeView_GetSelected($STV_TREEVIEW, $sDrive, $hControl)
    If Not IsObj($STV_FSOBJ) Then _ShellTreeView_Init()
    If @error Then Return SetError(1, 0, 0)
    
    If Not IsArray($STVH_AV_ITEMS) Then Return SetError(2, 0, 0)
    
    Local $sPath = _IsRootPath($sDrive, $hControl)
    
    ConsoleWrite("Origi:" & $sDrive & "Root: "& $sPath &@lf)
    
    If $sPath Then $sDrive = $sPath
    
    If Not FileExists($sDrive) Then
        Local $hParent = _GUICtrlTreeView_GetParentHandle($STV_TREEVIEW, $hControl)
        Local $iFullPath = 0

        $sItemtext = _GUICtrlTreeView_GetText($STV_TREEVIEW, $hParent)
        For $i = 0 To $STVH_AV_ITEMS[0][0] Step 1
            If $sItemtext = $STVH_AV_ITEMS[$i][1] Then
                $iFullPath = $STVH_AV_ITEMS[$i][2] & "\" & $sDrive
                ExitLoop
            EndIf
        Next
        If $iFullPath = 0 Then $iFullPath = _GUICtrlTreeView_GetText($STV_TREEVIEW, $hParent) & "\" & $sDrive

        ConsoleWrite("parent" & $hParent &@LF)
        
        While 1
            If $hParent = 0 Then Return
           
            If FileExists($iFullPath) Then ExitLoop
            
            $hParent = _GUICtrlTreeView_GetParentHandle($STV_TREEVIEW, $hParent)
            
            $sItemtext =  _GUICtrlTreeView_GetText($STV_TREEVIEW, $hParent)
            
            For $i = 0 To $STVH_AV_ITEMS[0][0] Step 1
                If $sItemtext = $STVH_AV_ITEMS[$i][1] Then
                    $iFullPath = $STVH_AV_ITEMS[$i][2] & "\" & $iFullPath
                    ExitLoop
                EndIf
            Next
        WEnd
        If $iFullPath = "" Then $iFullPath = _GUICtrlTreeView_GetText($STV_TREEVIEW, $hParent) & "\" & $iFullPath
        
        $sDrive = $iFullPath
    EndIf

    ConsoleWrite("pATH" & $sDrive &@LF)
    
    _GUICtrlTreeView_DeleteChildren($STV_TREEVIEW, $hControl)
   
    Local $objFolder, $colSubFolder, $objSubFolder, $iSubChild, $iSub
   
    $objFolder = $STV_FSOBJ.GetFolder($sDrive & "\")
    $colSubFolder = $objFolder.SubFolders
   
    For $objSubFolder In $colSubFolder
        $iSubChild = _GUICtrlTreeView_AddChild($STV_TREEVIEW, $hControl, $objSubFolder.Name, 3, 5)
        $iSub = _GetSub($objSubFolder.Path)
        If $iSub Then _GUICtrlTreeView_AddChild($STV_TREEVIEW, $iSubChild, $iSub, 3, 3)
    Next
    Return $sDrive
EndFunc   ;==>_ShellTreeView_GetSelected



; #INTERNAL_USE_ONLY#============================================================================================================
Func _IsRootPath($sPath, $hControl)
    If Not IsArray($STVH_AV_ITEMS) Then Return SetError(1, 0, 0)
    
    Local $szItemPath = $sPath
    For $i = 0 To $STVH_AV_ITEMS[0][0] Step 1
        If $hControl = $STVH_AV_ITEMS[$i][0] Then
            If $szItemPath Then Return $STVH_AV_ITEMS[$i][2]
        EndIf
    Next
    
    Return False
EndFunc

Func _GetSub($sPath)
    If Not $STV_FSOBJ Then _ShellTreeView_Init()
    If @error Then Return SetError(1, 0, 0)
    
    Local $objFolder, $colSubFolder, $objSubFolder
   
    $objFolder = $STV_FSOBJ.GetFolder($sPath & "\")

    $colSubFolder = $objFolder.SubFolders

    For $objSubFolder In $colSubFolder
        If $objSubFolder.Name Then Return $objSubFolder.Name
    Next
EndFunc   ;==>_GetSub


Func _TVN_ITEMEXPANDING($hWnd, $Msg, $wParam, $lParam)
    Local $tNMHDR, $hWndFrom, $iCode
   
    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
   
    Switch $hWndFrom
        Case $STV_TREEVIEW
            Switch $iCode
                Case $TVN_ITEMEXPANDING
                    Local $tINFO = DllStructCreate($tagNMTREEVIEW, $lParam)
                    Local $hControl = DllStructGetData($tINFO, "NewhItem")
                   
                    If _GUICtrlTreeView_GetExpanded($STV_TREEVIEW, $hControl) = False Then
                        _ShellTreeView_GetSelected($hWndFrom, _GUICtrlTreeView_GetText($hWndFrom, $hControl), $hControl)
                    EndIf
            EndSwitch
    EndSwitch
   
    Return "GUI_RUNDEFMSG"
EndFunc   ;==>_TVN_ITEMEXPANDING
Don't bother, It's inside your monitor!------GUISetOnEvent should behave more like HotKeySet()
Posted

mrRevoked

Hi! I glad that you interest my code :)

Results of the quick testing:

1. Works slowly than original code.

2. Why need to declare a $STV_FSOBJ as global and then as dim?

3. For some directories don't returns a full path, for some returns a 0.

4. Folder Common Documents on my computer contains many folders with subfolders, but i see only first subfolders.

Need more works. Good luck >_<

Posted (edited)

Nice idea overall, thanks for the start Rasim (for the Shell Part) and Poly (for the Tristate Part).

I ported it to AU native file search and enhanced the script to my needs. At this stage it's beta-beta and contains a number of useless debugging routines, mis-declared variables and needs to be thoroughly cleaned, but on XP it works fine. Maybe some Vista user volunteers for testing >_<.

Best Regards

P.S.: Rasim, I hope you don't mind that I was inspired by your signature style :).

Edit: Deleted obsolete code, see below for newer version...

Edited by KaFu
Posted

Hmmmm, found one problem. If items are checked and the parent is collapsed after selection, the check-state is lost. After expanding again (or acquiring the check-state via button), the state is not set correctly. Will look into this tomorrow...

Best Regards

Posted

KaFu

Nice work! But i have found a one(?) bug. In the parent item which contain a C: drive folders i can't expand items.

Posted (edited)

  rasim said:

Nice work! But i have found a one(?) bug. In the parent item which contain a C: drive folders i can't expand items.

Thanks :). Here's a cleaned and updated version correcting the bug I mentioned above and many minor things. Works fine on my XP-SP2 machines, maybe you'll give this one a try.

Edit: Updated attachment, now "My Computer" is always expanded on start-up.

Edit: Deleted obsolete code, see below for newer version...

Best Regards

Edited by KaFu
Posted

Very nice UDF rasim, thanks :)

@KaFu

  Quote

I hope you don't mind that I was inspired by your signature style

I don't think he is, because he was inspired by mine >_< (and i certainly don't mind :idiot:).

 

  Reveal hidden contents

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Posted

  MrCreatoR said:

I don't think he is, because he was inspired by mine :idiot: (and i certainly don't mind :P).

Then I just say thanks to MrCreatoR for inspiring rasim for inspiring me, too :)...

Damn, this code is a bugger, too much traps to evade and corners to think around. Here's my latest (and sadly I'm sure not my last) version of the code. Any feedback's welcome >_<...

Best Regards

  • 2 months later...
Posted

  KaFu said:

Here's my latest (and sadly I'm sure not my last) version of the code. Any feedback's welcome :)...

Hi all,

my goal is to write a simple backup utility with pre-selection of some folders, like this:

Posted Image

My sample, based on the excellent KaFu code , works only if I manually open the specific four folders "Documents And Settings", "Proprietario", "Impostazioni locali" and "Dati applicazioni". A lot of days to build a recursive function with _GUICtrlTreeView_SetState and _ShellTreeView_GetSelected before my Select Case have been useless. :)

Can someone help me ?

Best Regards,

xavier66

#include<GuiConstantsEx.au3>
#include<WindowsConstants.au3>
#include<GuiTreeView.au3>
#include<ShellTristateTreeView.au3>
#include<Array.au3>
#include<WinAPI.au3>

;===============================================================================
;
; Program Name:     ShellTristateTreeViewDemo.au3
;                   Userfunction My-WM_Notify() is registered in ShellTristateTreeView.au3.
;
;                   AutoIt Version: 3.2.12.1
;
; Author(s):        Rasim (ShellTreeView.au3)
;                   Holger Kotsch (TristateTreeViewLib.au3)
;                   Merged & Modified by Polyphem
;                   Ported to Au native filesearch and further enhancements by KaFu
;                   
; Note(s):
;   2008-Sep-15     Modified by KaFu from original functions
;===============================================================================

Global $sStateIconFile = @ScriptDir & "\modern.bmp"
Global $aTreeViewItemState[1][1],$aTreeViewItemStateChecked[1][1]

$hGUI = GUICreate("ShellTristateTreeView Demo", 300, 340)
$Buttonselected = GUICtrlCreateButton("Selected Item", 10, 300, 80, 23)
$ButtonCheckedStats = GUICtrlCreateButton("Checked Status", 110, 300, 80, 23)
$ButtonCheckedFull = GUICtrlCreateButton("Checked Full", 210, 300, 80, 23)
$hTreeView = _GUICtrlTreeView_Create($hGUI, 20, 20, 260, 260, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT,$TVS_DISABLEDRAGDROP, $TVS_CHECKBOXES),$WS_EX_CLIENTEDGE)
_GUICtrlTreeView_BeginUpdate($hTreeView)
_ShellTreeView_Create($hTreeView)
_GUICtrlTreeView_SetState($hTreeView, _GUICtrlTreeView_GetFirstItem($hTreeView),$TVIS_EXPANDED,true)
_ShellTreeView_GetSelected($hTreeView, _GUICtrlTreeView_GetText($hTreeView, _GUICtrlTreeView_GetFirstItem($hTreeView)),  _GUICtrlTreeView_GetFirstItem($hTreeView))
_GUICtrlTreeView_EndUpdate($hTreeView)

GUISetState()
LoadStateImage($hTreeView, $sStateIconFile)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
            
        Case $Buttonselected
            $hSelect = _GUICtrlTreeView_GetSelection($hTreeView)
            If $hSelect Then
                $sText = _GUICtrlTreeView_GetText($hTreeView, $hSelect)
                MsgBox(64, "ShellTristateTreeViewDemo - Info", _ShellTreeView_GetSelected($hTreeView, $sText, $hSelect, true))
            EndIf
            
        Case $ButtonCheckedStats
            GUISetState(@SW_LOCK)
            $iCountState = 0
            redim $aTreeViewItemState[_GUICtrlTreeView_GetCount($hTreeView)][2]
            $hItem = _GUICtrlTreeView_GetFirstItem($hTreeView)
            while $hItem
                if $iCountState = 0 Then
                    $aTreeViewItemState[$iCountState][0] = "My Computer"
                Else
                    $sText = _GUICtrlTreeView_GetText($hTreeView, $hItem)
                    $aTreeViewItemState[$iCountState][0] = _ShellTreeView_GetSelected($hTreeView, $sText, $hItem, true)
                    ; === my modification ===
                    Select
                        Case $sText = "Desktop"
                            MyCtrlSetItemState($hTreeView, $hItem, $GUI_CHECKED)

                        Case $sText = "Documenti"
                            MyCtrlSetItemState($hTreeView, $hItem, $GUI_CHECKED)

                        Case $sText = "Preferiti"
                            MyCtrlSetItemState($hTreeView, $hItem, $GUI_CHECKED)

                        Case $sText = "Identities"
                            MyCtrlSetItemState($hTreeView, $hItem, $GUI_CHECKED)
                    EndSelect
                    ; =======================
                EndIf
                $aTreeViewItemState[$iCountState][1] = MyCtrlGetItemState($hTreeView,$hItem)
                $iCountState += 1
                $hItem = _GUICtrlTreeView_GetNext($hTreeView, $hItem)
            WEnd
            GUISetState(@SW_UNLOCK)
            _ArrayDisplay($aTreeViewItemState)
            
            
        Case $ButtonCheckedFull
            GUISetState(@SW_LOCK)
            $aTreeViewItemState = ""
            dim $aTreeViewItemState[_GUICtrlTreeView_GetCount($hTreeView)][2]
            $hItemRoot = _GUICtrlTreeView_GetFirstItem($hTreeView)
            $aTreeViewItemState[0][0] = "My Computer"
            $aTreeViewItemState[0][1] = MyCtrlGetItemState($hTreeView,$hItemRoot)
            $iCountStateChecked = 1
            if MyCtrlGetItemState($hTreeView, $hItemRoot) = 1 Then ; if "My Computer" is activated
                $hItemSub = _GUICtrlTreeView_GetFirstChild($hTreeView, $hItemRoot)
                While $hItemSub
                    $iCountStateChecked += 1
                    $sText = _GUICtrlTreeView_GetText($hTreeView, $hItemSub)
                    $aTreeViewItemState[$iCountStateChecked][0] = _ShellTreeView_GetSelected($hTreeView, $sText, $hItemSub, true)
                    $aTreeViewItemState[$iCountStateChecked][1] = MyCtrlGetItemState($hTreeView,$hItemSub)
                    $hItemSub = _GUICtrlTreeView_GetNextChild($hTreeView, $hItemSub)
                WEnd
            ElseIf MyCtrlGetItemState($hTreeView, $hItemRoot) = 2 Then  ; if anything else is activated
                _TreeviewGetChildState($hTreeView, $hItemRoot, $iCountStateChecked)
            EndIf

            ; Parse and clean the results, just keep top-most parent directories activated and skip childs
            _ArrayDelete($aTreeViewItemState,0)
            _ArraySort($aTreeViewItemState,1)
            for $iCountStateChecked = ubound($aTreeViewItemState)-1 to 1 step -1
                if stringlen($aTreeViewItemState[$iCountStateChecked][0]) = 0 then _ArrayDelete($aTreeViewItemState,$iCountStateChecked)
            Next
            _ArraySort($aTreeViewItemState)
            for $i = 0 to UBound($aTreeViewItemState)-2
                if $i = UBound($aTreeViewItemState) - 1 then ExitLoop
                if StringInStr($aTreeViewItemState[$i+1][0],$aTreeViewItemState[$i][0]) then 
                    _ArrayDelete($aTreeViewItemState,$i+1)
                    $i = $i -1
                endif
            Next
            GUISetState(@SW_UNLOCK)
            if stringlen($aTreeViewItemState[0][0]) = 0 then
                MsgBox(64,"ShellTristateTreeView Demo","Nothing selected...")
            Else
                _ArrayDisplay($aTreeViewItemState)
            endif
    EndSwitch
WEnd



Func _TreeviewGetChildState($hTreeView, $hItem, $iCountStateChecked)
    Local $hItemSub
    
    $hItemSub = _GUICtrlTreeView_GetFirstChild($hTreeView, $hItem)
    While $hItemSub
        if MyCtrlGetItemState($hTreeView, $hItemSub) = 2 Then
            $iCountStateChecked = _TreeviewGetChildState($hTreeView, $hItemSub, $iCountStateChecked)
        ElseIf MyCtrlGetItemState($hTreeView, $hItemSub) = 1 Then
            $iCountStateChecked += 1
            $sText = _GUICtrlTreeView_GetText($hTreeView, $hItemSub)
            $aTreeViewItemState[$iCountStateChecked][0] = _ShellTreeView_GetSelected($hTreeView, $sText, $hItemSub, true)
            $aTreeViewItemState[$iCountStateChecked][1] = MyCtrlGetItemState($hTreeView,$hItemSub)
        endif
        $hItemSub = _GUICtrlTreeView_GetNextChild($hTreeView, $hItemSub)
    WEnd    
    Return $iCountStateChecked
    
EndFunc
Posted (edited)

The reason why it is not working is, that the function builds the tree only two recursions deep initially :), and when you open a dir it reads all folders on step deeper. Otherwise it would have to parse all directories of all drives attached at each start-up... from performance point of view a no-no.

What you CAN do is one of the following:

- The function returns an array of selected folders. Manually add the folders after the array is created (Quick, dirty, will only work for your language (have to admit that my Italian is rusty at most :) ))

- If I'm correct, the folders are all either accessible via AU macros or are sub-folders of those

@AppDataDir

@DesktopDir

@MyDocumentsDir

or the folders can be obtained from the registry via RegRead(), e.g.

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Local Settings\

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders\Local AppData\

Split those paths and add a check to the function to set the state of folders containing the respective roots to intermediate and if there is an exact match to checked to correctly reflect the settings in the tree. Finally add the relative macro paths at the end of the function to the array (prior check existence with FileExist() to prevent errors).

Regards

Edited by KaFu

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
  • Recently Browsing   0 members

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