Jump to content
Sign in to follow this  
rasim

ShellTreeView

Recommended Posts

rasim

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

Share this post


Link to post
Share on other sites
Andreik

Very useful rasim. Thanks. ;)


When the words fail... music speaks

Share this post


Link to post
Share on other sites
Polyphem

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

Share this post


Link to post
Share on other sites
rasim

Hey guys! Thanks for feedback and advices.

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

Share this post


Link to post
Share on other sites
wraithdu

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....

Share this post


Link to post
Share on other sites
Polyphem

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

Share this post


Link to post
Share on other sites
rasim

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...

>_<

Share this post


Link to post
Share on other sites
spudw2k
WeMartiansAreFriendly

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()

Share this post


Link to post
Share on other sites
rasim

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 >_<

Share this post


Link to post
Share on other sites
KaFu

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

Share this post


Link to post
Share on other sites
KaFu

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

Share this post


Link to post
Share on other sites
rasim

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.

Share this post


Link to post
Share on other sites
ptrex
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.

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

Share this post


Link to post
Share on other sites
MrCreatoR

Very nice UDF rasim, thanks :)

@KaFu

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:).

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites
KaFu

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

Share this post


Link to post
Share on other sites
xavier66

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

Share this post


Link to post
Share on other sites
KaFu

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

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.