Alle Verzeichnisse in ein TTreeView einlesen
Die folgende Prozedur liest eine gesamte Verzeichnis-Struktur ohne Dateien in ein TTreeView ein. Dabei werden auch die Unterverzeichnisse mit eingelesen und in dem TTreeView hierarchisch dargestellt.
procedure GetDirs(const ADirectory: string; ATree: TTreeView; AStart: TTreeNode); function SlashSep(const APath, AStr: string): string; begin if AnsiLastChar(APath)^ '' then Result := APath + '' + AStr else Result := APath + AStr; end; var SearchRec: TSearchRec; NewNode: TTreeNode; begin if FindFirst(SlashSep(ADirectory, '*.*'), faAnyFile, SearchRec) = 0 then begin try repeat if (((SearchRec.Attr and faDirectory) 0) and (SearchRec.Name '.') and (SearchRec.Name '..')) then begin NewNode := ATree.Items.AddChild(AStart, SearchRec.Name); GetDirs(SlashSep(ADirectory, SearchRec.Name), ATree, NewNode); end; until FindNext(SearchRec) 0; finally SysUtils.FindClose(SearchRec); end; end; end;
Diese Prozedur geht dabei rekursiv vor: Es wird zuerst das Verzeichnis der ersten Ebene durchsucht. Jedes weitere gefundene Verzeichnis wird ebenfalls durchsucht, solange bis in einem Verzeichnis keine Unterverzeichnisse mehr sind.
So kann die Funktion beispielsweise aufgerufen werden:
begin TreeView1.Items.BeginUpdate; GetDirs('f:\', TreeView1, nil); TreeView1.AlphaSort; TreeView1.Items.EndUpdate; end;
Ein Problem ist aber, dass die Funktion nicht sehr performant ist: Ist das Verzeichnis ein Stammverzeichnis (bspw. „C:\“), dauert die Einlesung der Verzeichnisse mit Unterverzeichnissen unter Umständen sehr lange. Diesem Problem kann Abhilfe geleistet werden, indem die Unterverzeichnisse erst dann eingelesen werden, wenn das übergeordnete TreeView-Element erweitert wird. So verlagert sich das Einlesen der Verzeichnisse gleichmäßig und der Benutzer bekommt nur wenig davon mit.
Soll ein Verzeichnis vom Anwender ausgewählt werden, kann ein bereits vorhandener Dialog benutzt werden.