- Offizieller Beitrag
Das rekursive einlesen des Inhaltsverzeichnisses einer ganzen Festplatte kann ja recht lange dauern. Wenn man dieses aber in einem Treeview haben will, dann gibt es nur diese Möglichkeit oder man liest das Verzeichnis ebenenweise (eine Verzeichnisebene nach der anderen) ein.
Aber immer nur eine Ebene sieht nicht so toll aus, weil dann die Verzeichnisse kein Plus-Button haben (als Kennzeichen dafür, dass der Ordner nicht leer ist). Also muss man mindestens zwei Ebenen rekursiv einlesen und das ist (bzw. war ) gar nicht so einfach.
Edit 18.12.2019:
Ich hatte dieses alte Script ganz vergessen. Zum einlesen eines Verzeichnisses habe ich bereits eine bessere Version geschrieben ("New_SelectFilesOrFolder.au3" im Anhang).
- Die zeigt die richtigen Icons zu den Dateien/Verzeichnissen an.
- Man kann ein Verzeichnis oder eine/mehrere Datei(en) markieren.
- Es gibt einen animierten Warte-Mauszeiger.
- Der ausgewählte Pfad wird oben angezeigt.
Edit 19.11.2010:
- Es gab noch einen Bug mit ansonsten leeren Verzeichnissen, in denen sich aber Reparse Points befinden (z.B. "c:\Users\Default\Documents\"). Die Überprüfung mit IsArray war da etwas suboptimal.
Edit 19.11.2010:
- Bei den symbolischen Links gab es noch einen Bug. Entfernt! (Danke, Kleiner!)
- Es werden nun die Einstellungen zu versteckten Dateien und geschützten Systemdateien aus dem Explorer übernommen.
Edit 18.11.2010: Geänderte Erkennung der Pluszeichen, womit jetzt auch die Tastatursteuerung möglich ist! (Danke, Großvater!)
Edit 07.11.2010: Symbolische Links (Reparse Points) werden nicht Angezeigt! (Danke, Kleiner!)
_GUICtrlTreeView_FileExplorer:
Spoiler anzeigen
#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_UseX64=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****
#include <GUIConstantsEx.au3>
#include <GuiImageList.au3>
#include <GuiTreeView.au3>
#include <StructureConstants.au3>
#include <TreeViewConstants.au3>
#include <WindowsConstants.au3>
Opt('MustDeclareVars', 1)
[/autoit] [autoit][/autoit] [autoit]Global $hGui = GUICreate('FileExplorer', 400, 400)
[/autoit] [autoit][/autoit] [autoit]Global Const $Delim = '\', $Delim1 = '|'
[/autoit] [autoit][/autoit] [autoit]Global $hTreeview = GUICtrlCreateTreeView(10, 10, 380, 360)
Global $hWndTreeview = GUICtrlGetHandle($hTreeview)
Global $hOk = GUICtrlCreateButton('Ok', 240, 375, 60, 22)
Global $hCancel = GUICtrlCreateButton('Cancel', 320, 375, 60, 22)
Global $hImage = _GUIImageList_Create(16, 16, 5, 1)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 3) ; Verzeichnis-Icon
_GUIImageList_AddIcon($hImage, 'shell32.dll', 110) ; Verzeichnis-Icon mit Haken
_GUIImageList_AddIcon($hImage, 'shell32.dll', 1) ; Datei-Icon
_GUIImageList_AddIcon($hImage, 'shell32.dll', 5) ; Diskette
_GUIImageList_AddIcon($hImage, 'shell32.dll', 7) ; Wechseldatenträger
_GUIImageList_AddIcon($hImage, 'shell32.dll', ; Festplatte
_GUIImageList_AddIcon($hImage, 'shell32.dll', 11) ; CDROM
_GUIImageList_AddIcon($hImage, 'shell32.dll', 12) ; Netzwerklaufwerk
_GUIImageList_AddIcon($hImage, 'shell32.dll', 53) ; Unbekannt
_GUICtrlTreeView_SetNormalImageList($hTreeview, $hImage)
GUISetState()
GUICtrlSetStyle($hTreeview, Default, BitOR($WS_EX_COMPOSITED, $WS_EX_CLIENTEDGE))
If ToolTip('Please wait...', Default, Default, 'Read Directory', 1) Then Local $aDrives = DriveGetDrive('ALL'), $iLWindex, $hRoot
For $i = 1 To $aDrives[0]
$iLWindex = 0
Switch DriveGetType($aDrives[$i])
Case 'Fixed'
$iLWindex = 5
Case 'CDROM'
$iLWindex = 6
Case 'RAMDisk'
$iLWindex = 7
Case 'Removable'
$iLWindex = 4
If StringLeft($aDrives[$i], 2) = 'a:' Or StringLeft($aDrives[$i], 2) = 'b:' Then $iLWindex = 3
Case Else
$iLWindex = 8
EndSwitch
$hRoot = _GUICtrlTreeView_Add($hTreeview, $hTreeview, StringUpper($aDrives[$i]), $iLWindex, $iLWindex)
If DriveStatus($aDrives[$i]) <> 'READY' Then ContinueLoop
If _GUICtrlTreeView_BeginUpdate($hTreeview) And _GUICtrlTreeView_FileExplorer($hTreeview, $hRoot, $aDrives[$i]) Then _GUICtrlTreeView_EndUpdate($hTreeview)
Next
ToolTip('')
GUIRegisterMsg($WM_NOTIFY, '_WM_NOTIFY')
While True
Switch GUIGetMsg()
Case $GUI_EVENT_CLOSE, $hCancel
Exit
Case $hOk
MsgBox(0, 'Selected Path/File', StringReplace(_GUICtrlTreeView_GetTree($hTreeview, _GUICtrlTreeView_GetSelection($hTreeview)), $Delim1, $Delim))
EndSwitch
WEnd
Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hChild, $hITEM, $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $ilParam)
If DllStructGetData($tNMTREEVIEW, 'hWndFrom') = $hWndTreeview Then
Switch DllStructGetData($tNMTREEVIEW, 'Code')
Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
Switch DllStructGetData($tNMTREEVIEW, 'Action')
Case $TVE_EXPAND
If ToolTip('Please wait...', Default, Default, 'Read Directory', 1) Then $hITEM = DllStructGetData($tNMTREEVIEW, 'NewhItem')
If _GUICtrlTreeView_GetExpanded($hTreeview, $hITEM) Then Return $GUI_RUNDEFMSG
$hChild = _GUICtrlTreeView_GetFirstChild($hTreeview, $hITEM)
If Not $hChild Then Return $GUI_RUNDEFMSG
If _GUICtrlTreeView_BeginUpdate($hTreeview) Then _GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
_GUICtrlTreeView_FileExplorer($hTreeview, $hChild, StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), $Delim1, $Delim))
Do
$hChild = _GUICtrlTreeView_GetNextChild($hTreeview, $hChild)
If Not $hChild Then ExitLoop
_GUICtrlTreeView_DeleteChildren($hTreeview, $hChild)
_GUICtrlTreeView_FileExplorer($hTreeview, $hChild, StringReplace(_GUICtrlTreeView_GetTree($hTreeview, $hChild), $Delim1, $Delim))
Until False
If _GUICtrlTreeView_EndUpdate($hTreeview) Then ToolTip('')
EndSwitch
EndSwitch
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>_WM_NOTIFY
Func _GUICtrlTreeView_FileExplorer($hTreeview, $hITEM, $sPath)
Local $sFileList, $sFolderList, $aDirList, $hSearch, $sFile
Local $iHidden = RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced', 'Hidden') - 1
Local $iSuperHidden = Not RegRead('HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced', 'ShowSuperHidden')
$hSearch = FileFindFirstFile($sPath & $Delim & '*')
If $hSearch = -1 Then Return True
Do
$sFile = FileFindNextFile($hSearch)
If @error Then ExitLoop
Switch @extended
Case False
If $iHidden And StringInStr(FileGetAttrib($sPath & $Delim & $sFile), 'H') Then ContinueLoop
If $iSuperHidden And StringInStr(FileGetAttrib($sPath & $Delim & $sFile), 'S') Then ContinueLoop
$sFileList &= $sFile & $Delim1
Case True
If _IsReparsePoint($sPath & $Delim & $sFile) Then ContinueLoop
$sFolderList &= $sFile & $Delim1
EndSwitch
Until False
FileClose($hSearch)
If $sFolderList & $sFileList = '' Then Return True
$aDirList = StringSplit(StringTrimRight($sFolderList & $sFileList, 1), $Delim1, 2)
For $sFile In $aDirList
If StringInStr(FileGetAttrib($sPath & $Delim & $sFile), 'D') Then
_GUICtrlTreeView_AddChild($hTreeview, $hITEM, $sFile, 0, 1)
Else
_GUICtrlTreeView_AddChild($hTreeview, $hITEM, $sFile, 2, 2)
EndIf
Next
Return True
EndFunc ;==>_GUICtrlTreeView_FileExplorer
Func _IsReparsePoint($FLS) ; progandy
Dim Static $K32 = DllOpen('kernel32.dll')
Dim $DA = DllCall($K32, 'dword', 'GetFileAttributesW', 'wstr', $FLS)
If @error Then Return SetError(1, @error, False)
Return BitAND($DA[0], 1024) = 1024
EndFunc ;==>_IsReparsePoint