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.
