設想
我正在嘗試復制從根目錄開始使用檔案夾結構中的目錄/檔案夾填充 Treeview 的標準方法,但使用 IdFTP 從遠程服務器而不是本地硬碟驅動器獲取結構。我希望結果看起來類似于 Filezilla 等客戶端。
我使用了來自瑞士德爾福中心的
我在 Delphi 中看到的使用 Ttreeview
我的代碼
procedure TForm2.Button1Click(Sender: TObject);
var StartingDir : string;
begin
TreeView1.Items.BeginUpdate;
try
StartingDir := '/';
Screen.Cursor := crHourGlass;
TreeView1.Items.Clear;
FTPconnect; //procedure to connect to remote server
GetDirectories(TreeView1, StartingDir, nil, True);
FTPDisconnect; //procedure to disconnect from remote server
finally
TreeView1.Items.EndUpdate;
Screen.Cursor := crDefault;
end;
end;
procedure TForm2.GetDirectories(Tree: TTreeView; Directory: string; Item: TTreeNode; IncludeFiles: Boolean);
var
ItemTemp: TTreeNode;
DirItemType : TIdDirItemType ;
Filename , NewStartingDirectory: string;
i : Integer;
begin
Tree.Items.BeginUpdate;
IdFTP.ChangeDir(Directory);
IdFTP.List; //get directory of remote folder
i:=0;
repeat
DirItemType := IdFTP.DirectoryListing[I].ItemType;
Filename := IdFTP.DirectoryListing[I].FileName;
If (DirItemType = ditDirectory) and (Filename <> '.') and (Filename <> '..')then
begin
if DirItemType = ditDirectory then
Item := Tree.Items.AddChild(Item, Filename);
ItemTemp := Item.Parent;
if Directory = '/' then
NewStartingDirectory := Directory Filename
else
NewStartingDirectory := Directory '/' Filename;
GetDirectories(Tree, NewStartingDirectory, Item, IncludeFiles);
Item := ItemTemp;
end
else
if IncludeFiles then
begin //this bit commented out as we only want to see directories
// if (Filename <> '.') and (Filename <> '..') then
// Tree.Items.AddChild(Item, Filename);
end;
inc(i);
until i = IdFTP.DirectoryListing.Count;
Tree.Items.EndUpdate;
end;
瑞士德爾皮中心的代碼(用于比較)
procedure TForm1.Button1Click(Sender: TObject);
var
Node: TTreeNode;
Path: string;
Dir: string;
begin
Dir := 'c:\temp';
Screen.Cursor := crHourGlass;
TreeView1.Items.BeginUpdate;
try
TreeView1.Items.Clear;
GetDirectories(TreeView1, Dir, nil, True);
finally
Screen.Cursor := crDefault;
TreeView1.Items.EndUpdate;
end;
end;
procedure TForm1.GetDirectories(Tree: TTreeView; Directory: string; Item: TTreeNode; IncludeFiles: Boolean);
var
SearchRec: TSearchRec;
ItemTemp: TTreeNode;
begin
Tree.Items.BeginUpdate;
if Directory[Length(Directory)] <> '\' then Directory := Directory '\';
if FindFirst(Directory '*.*', faDirectory, SearchRec) = 0 then
begin
repeat
if (SearchRec.Attr and faDirectory = faDirectory) and (SearchRec.Name[1] <> '.') then
begin
if (SearchRec.Attr and faDirectory > 0) then
Item := Tree.Items.AddChild(Item, SearchRec.Name);
ItemTemp := Item.Parent;
GetDirectories(Tree, Directory SearchRec.Name, Item, IncludeFiles);
Item := ItemTemp;
end
else if IncludeFiles then
if SearchRec.Name[1] <> '.' then
Tree.Items.AddChild(Item, SearchRec.Name);
until FindNext(SearchRec) <> 0;
FindClose(SearchRec);
end;
Tree.Items.EndUpdate;
end;
我在這里看過 SO - 太復雜和錯誤的語言和這里- 類似于瑞士德爾福中心和這里 - 錯誤的語言,不確定它在做什么。
如果使用 TlistView 更好,你能告訴我使用它的等效代碼嗎?
uj5u.com熱心網友回復:
未經測驗:
- 我將
TIdFTP
變數設為引數,因為TTreeView
它也是一個引數,并且應該始終如一地完成,而不是過時的。 - 使用
for
回圈而不是repeat until
. - 反正
IncludeFiles
不用的時候就去掉。 - 消除奇怪的邏輯以始終獲取新 TreeNode 的父級。
- 不再鎖定 TreeView - 在呼叫此方法之前執行一次并在呼叫后解鎖它 - 否則您徒勞地執行了數十次。
- 基本邏輯正如我在評論中所寫:
- 將所有檔案夾字串存盤到您自己的串列中,此時避免遞回。
- 修復要連接一次的路徑,而不是每次回圈迭代。
- 通過該串列進行遞回 - 此時狀態
FTP
無關緊要,您不會弄亂不同級別的串列。 - 當然,釋放 StringList 的創建實體。
procedure TForm2.GetFolders
( Ftp: TIdFTP // The source, from which we read the content
; Tree: TTreeView // The destination, which we want to fill
; ParentNode: TTreeNode // Node under which all new child nodes should be created
; Path: String // Starting directory
);
var
NewNode: TTreeNode; // New child in the tree
Filename: String; // Check against unwanted folder entries
i: Integer; // Looping over both lists
sl: TStringList; // Collect folders only
begin
FTP.ChangeDir( Path );
FTP.List; // Entire remote listing
sl:= TStringList.Create; // Collect all entries we're interested in
try
for i:= 0 to FTP.DirectoryListing.Count- 1 do begin // For each entry
Filename:= FTP.DirectoryListing[i].FileName;
if (FTP.DirectoryListing[i].ItemType= ditDirectory) // Only folders
and (Filename<> '.')
and (Filename<> '..') then begin
sl.Add( Filename ); // Only the name, not the full path
end;
end;
// Do this only once
if Path<> '/' then Path:= '/' Path '/';
for i:= 0 to sl.Count- 1 do begin // All collected folders
NewNode:= Tree.Items.AddChild( ParentNode, sl[i] ); // Populate tree
GetFolders( Ftp, Tree, NewNode, Path sl[i] ); // Recursion of folder name current path
end;
finally
sl.Free;
end;
end;
未經測驗,但應該編譯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/522362.html
標籤:德尔福ftp树视图印地
上一篇:使用擴展型別實作泛型方法
下一篇:任務':app:generateDebugApolloIR'(type'ApolloIRGenTask')的配置發現了一些問題