iT邦幫忙

0

Delphi 列舉(篩選)子目錄下符合檔案【附例】

  • 分享至 

  • xImage
  •  

Purpose:運用’回呼函數Callback’,列舉(篩選)子目錄下符合檔案
Enviro:Delphi RAD 10.4 Win 64x
//---實作下列這段話
Start by defining a type for your function/procedure
type
TMyProc = procedure(Param1: Integer);

Then you can use your procedure type anywhere, as long as your procedure's signature matches your type. To call your callback from within, you can use something like this:

procedure DoAndCallBack(MyProc: TMyProc)
begin
MyProc(1);
end;
步驟:上段話分兩步驟

  1. 定義一個類別Type,當它被呼叫時,執行某事
  2. 在Procedure內呼叫它 MyProc

Step 1-1. 定義一個Type EnumProc 參數:檔名、檔案屬性
type
TEnumProc = procedure(fNa: string; vAttr:integer; var bCont:Boolean) of object;

Step 1-2. 創建一個該類別的實體AddRec(),寫碼,寫入要執行的事

//--- AddRec 實作TEnumProc類別, 把檔案加入 List
//--- 接受參數 fNa檔名  vAttr檔案屬性
procedure TfrmSeek.AddRec(fNa: string; vAttr:integer; var bCont:Boolean);
begin
  memo1.Lines.Add(fNa);
  if vAttr = faDirectory then dirList.Add(fNa);
  if (vAttr and faArchive)  <>0 then fList.Add(fNa);
  bCont := True;
end;

Step 2. 如何呼叫它
寫一個Procedure,參數:subYes 是否包含子目錄
procedure TfrmSeek.EnumFiles(subYes:Boolean; sDir, SMASK: string; Attr: Integer; AddFile: TEnumProc);
完整代碼請詳見 Source Code

只找一層
//--- 找現在這一層

 //--- 找現在這一層
  Status := FindFirst(sDir+SMASK, faAnyFile, SRec);
  try
    while Status = 0 do
    begin
      //--- 下一行的意思是: ( 只要檔案啦 )
      //--- SRec.Attr 和Attr 做AND運算,如果<>0,表示有此屬性
      //--- 而且不是Folder ,也不是 '.' 或者'..'
      if (SRec.Attr and Attr <> 0) and (FileExists(sDir + SRec.name)) and
        not ((SRec.Attr and faDirectory <> 0) and ((SRec.name = '.') or (SRec.name = '..'))) then
      begin
        bContinue := True;
        //--- 加入 List
        AddRec( sDir+SRec.name, SRec.Attr ,bContinue );
        if not bContinue then Break;
        if flagStop then Break;

      end;
      //--- 繼續找
      Status := FindNext(SRec);
      Application.ProcessMessages;
    end;
  finally
    FindClose(SRec);
  end;

再找子目錄層

//--- 找子目錄層
  if subYes then begin
     Status := FindFirst(sDir + '*.*', faDirectory, SRec);
     try
       while Status = 0 do
       begin
         //--- add to directory list
         if (SRec.Attr = faDirectory) and ((SRec.Name<>'.') and (SRec.Name<>'..')) then
         begin
            dirList.Add(SRec.Name);
            memo2.Lines.Add(sRec.Name);
         end;

         if (SRec.Name<>'.') and (SRec.Name<>'..') then begin
            EnumFiles(subYes, sDir + SRec.name, SMASK, Attr, AddRec);
         end;
         //--- 繼續找
         Status := FindNext(SRec);
         if flagStop then Break;
         // 加這行才能即時中斷執行
         Application.ProcessMessages;
       end;
     finally
       FindClose(SRec);
     end;
  end;

Step 3. 在btnGo 呼叫它
EnumFiles(subAlso,path, filter,faAnyFile, AddRec);

註:Global Variables 宣告
DirCount : integer;
dirList : TStringList;
fList : TStringList;
flagStop : Boolean; //--- 中斷執行

成果: 範例 Source + Exec
https://ithelp.ithome.com.tw/upload/images/20210824/20111373NLaXOKSr76.jpg
2021/8/24


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言