後一頁
前一頁
回目錄
回首頁
第六章 文件管理(三)

2.畫出每個自畫項目 

  這在TabSet的OnDrawTab事件處理過程中完成。這一事件處理過程的參數中包含了待畫項目索引、畫板、待畫區欄位、是否被選中等。這�塈畯怚u利用了前三個參數。事實上利用最後一個參數,我們可以對被選中的標籤進行一些特殊的視覺效果處理。這一工作就留給讀者自己去完成。 

procedure TFMForm.DriveTabSetDrawTab(Sender: TObject; TabCanvas: TCanvas;

R: TRect; Index: Integer; Selected: Boolean);

var

Bitmap: TBitmap;

begin

Bitmap := TBitmap(DriveTabSet.Tabs.Objects[Index]);

with TabCanvas do

begin

Draw(R.Left, R.Top + 4, Bitmap);

TextOut(R.Left + 2 + Bitmap.Width, R.Top + 2, DriveTabSet.Tabs[Index]);

end;

end; 

6.4.5 文件管理基本功能的實現 

  在子視窗的File選擇表中,定義了文件管理的基本功能,它們是:

  ● Open :打開或執行一個文件(從文件列示方塊連續按兩下該文件可實現同樣效果)

● Move :文件在不同目錄間的移動

  ● Copy :文件拷貝

  ● Delete :文件解除

  ● Rename :文件更名

  ● Properties :顯示文件屬性 

6.4.5.1 文件打開 

  文件打開功能可以執行一個可執行文件,或把文件在與之相關聯的應用程式中打開。文件總是與建立它的應用程式相關聯,這種關聯可以在Windows的文件管理器中修改。要注意的是:文件的關聯是以後綴名為標誌的,因而對一個文件關聯方式的修改將影響所有相同後綴名的文件。

  文件打開功能實現的關鍵是利用了Windows API函數ShellExecute 。由於Windows API函數的參數要求字元串型式是PChar,而Delphi中一般用的是有結束標誌的String型式,因此為呼叫方便我們把這一函數進行了重新定義如下。 

function ExecuteFile(const FileName, Params, DefaultDir: String;

ShowCmd: Integer): THandle;

var

zFileName, zParams, zDir: array[0..79] of Char;

begin

Result := ShellExecute(Application.MainForm.Handle, nil,

StrPCopy(zFileName, FileName), StrPCopy(zParams, Params),

StrPCopy(zDir, DefaultDir), ShowCmd);

end;

  以上函數在fmxutils單元中定義。fmxutils是一個自定義代碼單元。

  有關ShellExecute中各參數的具體含義讀者可查閱連線Help文件。

  StrPCopy把一個Pascal型式的字元串拷貝到一個無結束符的PChar型式字元串中。

  在子視窗的Open1Click事件處理過程中: 

procedure TFMForm.Open1Click(Sender: TObject);

begin

with FileList do

ExecuteFile(FileName, '', Directory, SW_SHOW) ;

end;

  如果FileList允許顯示目錄的話(即FileType屬性再增加一項ftDirectory),那麼對於一個目錄而言,打開的含義應該是顯示它下邊的子目錄和文件。程式修改如下。 

  procefure TFMForm.Open1Click(Sender: Tobject);

begin

With FileList do

begin

if HasAttr(FileName,faDirectory) then

DirectoryOutline.Directory := FileName

else

ExecuteFile(FileName,' ' ,Directory,SW_SHOW);

end;

end; 

其中HasAttr是一個fmxutils單元中的自定義函數,用於偵測指定文件是否具有某種屬性。 

function HasAttr(const FileName: String; Attr: Word): Boolean;

begin

Result := (FileGetAttr(FileName) and Attr) = Attr;

end; 

6.4.5.2 文件拷貝、移動、解除、更名 

  文件拷貝的關鍵是使用了以文件句柄為操作物件的文件管理函數,因而提供了一種底層的I/O通道。在Object Pascal中這一點是利用無型式文件實現的。

  在文件拷貝中首先檢查目標檔案標簽是否是一個目錄。如是則把原文件的檔案標簽加入到目標路徑後,產生目標文件全路徑名。而後提取源文件的時間戳,以備拷貝完成後設定目標文件。拷貝過程中使用了返回文件句柄或以文件句柄為參數的文件管理函數FileOpen、FileCreate、FileRead、FileWrite、FileClose。為保證文件的正常關閉和記憶體的釋放,在拷貝過程中進行異常保護。

過程CopyFile實現上述功能,它定義在fmxutils單元中。 

procedure CopyFile(const FileName, DestName: TFileName);

var

CopyBuffer: Pointer;

TimeStamp, BytesCopied: Longint;

Source, Dest: Integer;

Destination: TFileName;

const

ChunkSize: Longint = 8192;

begin

Destination := ExpandFileName(DestName);

if HasAttr(Destination, faDirectory) then

Destination := Destination + '\' + ExtractFileName(FileName);

TimeStamp := FileAge(FileName);

GetMem(CopyBuffer, ChunkSize);

try

Source := FileOpen(FileName, fmShareDenyWrite);

if Source < 0 then

raise EFOpenError.Create(FmtLoadStr(SFOpenError, [FileName]));

try

Dest := FileCreate(Destination);

if Dest < 0 then

raise EFCreateError.Create(FmtLoadStr(SFCreateError,[Destination]));

try

repeat

BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize);

if BytesCopied > 0 then

FileWrite(Dest, CopyBuffer^, BytesCopied);

until BytesCopied < ChunkSize;

finally

FileSetDate(Dest,TimeStamp);

FileClose(Dest);

end;

finally

FileClose(Source);

end;

finally

FreeMem(CopyBuffer, ChunkSize);

end;

end;

  如果我們不使用FileSetDate過程,Windows自動把目前時間作為時間戳寫入文件。

  文件移動事實上是文件拷貝與文件解除的結合。fmxutils單元中的MoveFile過程實現了這一功能。 

procedure MoveFile(const FileName, DestName: TFileName);

var

Destination: TFileName;

begin

Destination := ExpandFileName(DestName);

if not RenameFile(FileName, Destination) then

begin

if HasAttr(FileName, faReadOnly) then

raise EFCantMove.Create(Format(SFCantMove, [FileName]));

CopyFile(FileName, Destination);

DeleteFile(FileName);

end;

end; 

EFCanMove是一個自定義異常類: 

  type

EFCanMove := Class(EStreamError);

  有關自定義異常類請參閱第十二章。

  文件解除、文件更名直接呼叫Delphi文件管理過程DeleteFile、RenameFile。它們都以檔案標簽為參數。操作執行前應彈出一個對話方塊進行確認,執行完畢後應呼叫Update方法更新FileList的顯示。 

6.4.5.3 一致的介面 

  文件拷貝、文件移動、 文件更名以及後邊的改變目前工作目錄在形式上都表現為從一個源文件到一個目標文件。因而可以採用統一的用戶介面,即ChangeForm對話方塊

這四個選擇表項共用一個Click事件處理過程,通過對Sender參數的偵測,決定將要打開對話方塊的標題和顯示內容。當用戶按OK鍵關閉且目標文件(目錄)非空時,程式彈出一個訊息對話方塊要求用戶進一步確認,而後執行相應的動作。

  共用的事件處理過程FileChange的程式清單如下: 

procedure TFMForm.FileChange(Sender: TObject);

var

ChangeForm: TChangeForm;

IsFile: Boolean;

begin

ChangeForm := TchangeForm.Create(Self);

IsFile := True;

with ChangeForm do

begin

if Sender = Move1 then Caption := 'Move'

else if Sender = Copy1 then Caption := 'Copy'

else if Sender = Rename1 then Caption := 'Rename'

else if Sender = ChangeDirectory1 then

begin

Caption:='Change Directory';

IsFile:=False;

end

else Exit;

if IsFile then

begin

CurrentDir.Caption := FileList.Directory;

FromFileName.Text := FileList.FileName;

ToFileName.Text := '';

end

else

begin

CurrentDir.Caption := DriveTabSet.Tabs[DriveTabSet.TabIndex];

FromFileName.Text := DirectoryOutline.Directory;

ToFileName.Text := '';

end;

if (ShowModal <> idCancel) and (ToFileName.Text <> '') then

ConfirmChange(Caption, FromFileName.Text, ToFileName.Text);

end;

end; 

其中用到的自定義私有過程ConfirmChange用於執行相應的動作: 

procedure TFMForm.ConfirmChange(const ACaption, FromFile, ToFile: String);

begin

if MessageDlg(Format('%s %s to %s', [ACaption, FromFile, ToFile]),

mtConfirmation, [mbYes, mbNo], 0) = idYes then

begin

if ACaption = 'Move' then

MoveFile(FromFile, ToFile)

else if ACaption = 'Copy' then

CopyFile(FromFile, ToFile)

else if ACaption = 'Rename' then

RenameFile(FromFile, ToFile)

else if ACaption = 'Change Directory' then

changeDirectory(ToFile);

FileList.Update;

end;

end; 

6.4.5.4 顯示文件屬性 

  當程式執行Properties 選擇表項的Click 事件處理過程時,首先彈出一個TFileAttrForm型式的對話方塊,顯示文件的屬性

當用戶修改並確認後程式重新設定文件屬性。

  Properties選擇表項的Click事件處理過程如下: 

procedure TFMForm.Properties1Click(Sender: TObject);

var

Attributes, NewAttributes: Word;

FileAttrForm: TFileAttrForm;

begin

FileAttrForm := TFileAttrForm.Create(self);

ShowFileAttr(FileAttrForm,FileList.FileName,FileList.Directory);

end;

  其中過程ShowFileAttr的實現如下: 

procedure TFMForm.ShowFileAttr(FileAttrForm:TFileAttrForm;

AFileName,Directory:String);

var

Attributes,NewAttributes: Word;

begin

with FileAttrForm do

begin

FileName.Caption := AFileName;

FilePath.Caption := Directory;

ChangeDate.Caption := DateTimeToStr(FileDateTime(AFileName));

Attributes := FileGetAttr(AFileName);

ReadOnly.Checked := (Attributes and faReadOnly) = faReadOnly;

Archive.Checked := (Attributes and faArchive) = faArchive;

System.Checked := (Attributes and faSysFile) = faSysFile;

Hidden.Checked := (Attributes and faHidden) = faHidden;

if ShowModal <> idCancel then

begin

NewAttributes := Attributes;

if ReadOnly.Checked then NewAttributes := NewAttributes or faReadOnly

else NewAttributes := NewAttributes and not faReadOnly;

if Archive.Checked then NewAttributes := NewAttributes or faArchive

else NewAttributes := NewAttributes and not faArchive;

if System.Checked then NewAttributes := NewAttributes or faSysFile

else NewAttributes := NewAttributes and not faSysFile;

if Hidden.Checked then NewAttributes := NewAttributes or faHidden

else NewAttributes := NewAttributes and not faHidden;

if NewAttributes <> Attributes then

FileSetAttr(AFileName, NewAttributes);

end;

end;

end; 

以上過程中用到的函數FileDataTime在fmxutils單元中定義,返回一個TDatatime型式的變數。 

function FileDateTime(const FileName: String): System.TDateTime;

begin

Result := FileDateToDateTime(FileAge(FileName));

end; 

6.4.6 其它文件管理功能的實現 

  在子視窗的Function選擇表中,定義了一些其它的文件管理功能:

  ● Search :找到一個給定名字的文件,若存在則顯示該文件屬性

  ● Disk View :顯示目前磁碟機的大小和剩餘空間

  ● View type :確定顯示文件的型式 

6.4.6.1 文件找到 

  當用戶按一下Search選擇表項時,程式彈出一個對話方塊(如圖6.10),要求輸入待找到的檔案標簽和找到路徑。檔案標簽可以是萬用字元符號。當用戶確認後程式顯示第一個匹配文件的屬性(如圖6.9)。找到不到匹配文件則給出相應的資訊。

       在實現這一功能的最初設計中,我試圖使用FileSearch函數,這個函數允許在多個不同路徑中找到。但可惜的是:也許由於系統設計者的失誤,這個函數並沒有返回它應該返回的東西(第一個匹配文件的全路徑名),而是仍把輸入的匹配符返回。

  沒有辦法我只能再次使用FindFirst,這個函數的特性在6.3節中已進行了介紹。下面是這一功能的實現代碼。 

procedure TFMForm.search1Click(Sender: TObject);

var

SearchForm: TSearchForm;

FileAttrForm: TFileAttrForm;

FindIt,path: String;

SearchRec: TSearchRec;

Return: Integer;

begin

SearchForm := TSearchForm.Create(self);

with SearchForm do

begin

SearchFile.text := '';

SearchPath.text := DirectoryOutline.Directory;

if (ShowModal <> idCancel) and

(SearchFile.Text <> '') and (SearchPath.text <> '') then

begin

FindIt := SearchPath.text+'\'+SearchFile.text;

Return := FindFirst(FindIt,faAnyFile,SearchRec);

if Return <> 0 then

FindIt := ''

else

FindIt := ExpandFileName(SearchRec.Name);

end;

if FindIt = '' then

MessageDlg('Cannot find the file in current directory.',

mtWarning, [mbOk], 0)

else

begin

Path := ExtractFilePath(FindIt);

FindIt := ExtractFileName(FindIt);

FileAttrForm := TFileAttrForm.Create(self);

ShowFileAttr(FileAttrForm,FindIt,Path);

end;

end;

end; 

6.4.6.2 顯示磁碟資訊

  當用戶按一下Disk View選擇表項時,將彈出一個TDiskViewForm型式的對話方塊,用來顯示目前磁碟的資訊

         磁碟資訊的獲取是在DiskViewForm中DriveEdit編輯框的OnChange事件處理過程中實現的。 

procedure TDiskViewForm.driveEditChange(Sender: TObject);

var

dr: Byte;

Free,Total: LongInt;

begin

Free := DiskFree(0);

Total := DiskSize(0);

FreeSpace.text := IntToStr(Free)+ ' bytes.';

TotalSpace.text := IntToStr(Total) + ' bytes.';

end;

  DiskFree、DiskSize帶參數為0表示目前磁碟機。讀者可以很容易把它改成按用戶輸入顯示磁碟資訊的情況。

  DiskViewForm中的三個編輯框設計時都令ReadOnly為True。 

6.4.6.3 改變顯示文件的型式 

  改變顯示文件的型式事實上是設定FileList的Mask屬性。我們利用一個標準的InputBox輸入文件的匹配字元串。而後利用Update方法更新FileList。 

procedure TFMForm.Viewtype1Click(Sender: TObject);

var

FileMask: String;

begin

FileMask := InputBox('File type','Input File type For View :',FileList.Mask);

If FileMask = '' then FileMask := '*.*';

FileList.Mask := FileMask;

FileList.Update;

CreateCaption;

end;

  其中的CreateCaption私有過程將在(6.4.8)中進行介紹。 

6.4.7 目錄管理功能的實現 

  在子視窗的Directory選擇表中,提供了目錄管理功能:

  ● Create Directory :建立一個子目錄

  ● Delete Directory :解除一個空的子目錄

  ● Change Directory :改變目前工作目錄 

6.4.7.1 建立目錄 

  建立目錄時首先彈出一個TNewDir型式的對話方塊

對話方塊中要求用戶輸入目錄名。如果用戶不輸入路徑,則缺省認定為目前工作目錄的子目錄: 

  Dir := ExpandFileName(DirName.Text); 

  而後呼叫MkDir函數。在目錄建立過程中關閉了I/O錯誤偵測,出錯不產生異常而是把IOResult設定為非零值。通過檢查IOResult是否為0可以確定建立是否成功。

程式清單如下: 

procedure TFMForm.CreateDirectory1Click(Sender: TObject);

var

NewDir: TNewDir;

Dir: String;

begin

{$I-}

NewDir := TNewDir.Create(self);

with NewDir do

begin

CurrentDir.Caption := DirectoryOutline.Directory;

if (ShowModal <> idCancel) and (DirName.Text <> '') then

Dir := ExpandFileName(DirName.text);

end;

MkDir(Dir);

if IOResult <> 0 then

MessageDlg('Cannot Create directory', mtWarning, [mbOk], 0);

end;

  但不幸的是目錄建立後我們卻無法從目前工作目錄樹中看到。必須移到另一個磁碟機而後再返回,建立的目錄才是可見的。在後邊我們將提供一種解決方法。 

6.4.7.2 解除目錄 

  在實現目錄解除過程中,遠不如建立目錄那麼順利。碰到的問題是:

  1.RmDir不允許解除目前工作目錄。但為了操作方便,我們要求解除的恰恰是目前工作目錄;

  2.目錄解除後呼叫Refresh方法或Update方法並不能使該目錄從螢幕顯示中去除。因而當用戶試圖進入該目錄時會導致系統崩潰。

  對第一個問題,我們的解決辦法是把目前工作目錄轉換到其父目錄。假如讀者記得目錄也被作業系統作為一種特殊的文件對待的話,那麼就不會對下面的語句感到奇怪了: 

  path := DirectoryOutline.Directory;

  Directoryoutlin.Directory := ExpandFilePath(Path);

  而後呼叫RmDir過程: 

RmDir(Path);

 

  第二個問題的解決卻頗為費神。因為DirectoryOutline是Delphi提供的示例部件,沒有Help文件支援。通過試驗發現:只有當DirectoryOutline的Drive屬性改變時,才重新從相應磁碟機讀取目錄。而且它基本上是唯讀的,除非清除( Clear) 它,象Add、Delete這些方法對它都是無效的。

  我曾經考慮過一個笨拙的方法,那就是先改變目前磁碟機而後再改回來。但這種方法一方面速度無法忍受,另一方面當只存在一個磁碟機可用時會導致系統崩潰。

  正當我一籌莫展時,突然想到:DirectoryOutline是一個Sample部件,Delphi 提供了它的源代碼。而當我分析了它的源代碼後,我知道應該做什麼了,那就是為DirectoryOutline增添一個Reset方法! 

6.7.3 為部件增添一個方法 

  嚴格地說,我們所做的工作屬於建立一個新部件。但因為我們有源代碼,所以不必從DirectoryOutline繼承而是直接修改它。這樣我們可以省去與建立部件有關的許多繁瑣工作。對建立新部件感興趣的讀者可閱讀本書第三編的有關章節。

  在Delphi IDE中打開DirectoryOutline的源文件後:

1.把庫單元名改為DirPlus,類名改為TDirectoryOutlinePlus,表明這是DirectoryOutline的增強版。而後存入另一個目錄中;

  2.加入一個公有方法Reset。這一方法的作用是重新讀取目前磁碟機的目錄。程式清單如下。 

procedure TDirectoryOutlinePlus.Reset;

begin

ChDir(FDrive + ':');

GetDir(0, FDirectory);

FDirectory := ForceCase(FDirectory);

if not (csLoading in ComponentState) then BuildTree;

end;

  讀者也許被這段代碼弄糊塗了。由於篇幅所限,而且涉及到許多自定義部件開發的內容,我們也不準備去詳細解釋它。假如讀者想徹底搞懂它,我建議先看一下本書第三編有關自定義部件開發的內容,而後再對照原DirectoryOutline的源代碼進行分析。

  3.編譯成一個庫文件DirPlus.tpu;

4.把DirPlus加入部件的Samples頁中。

  如何加入一個部件見第三編有關章節的介紹。

  當增強的目錄樹準備好以後,必須修改我們的子視窗設計,但卻不必親自修改源代碼。

  1.解除子視窗中的TDirectoryOutline類部件DirectoryOutline。此時FileList佔據了整個用戶區;

  2.把FileList的Align屬改為None,並留出左邊的空白供放部件用;

  3.在視窗左部加入TDirectoryOutlinPlus類的部件DirectoryOutline;

4.把DirectoryOutline的Align屬性改為Left,FileList的Align屬性還原為Client;

5.在DirectoryOutline的事件OnChange清單中選取DirectoryOutlineChange,即原DirectoryOutline的處理過程。

  以上工作的最終目標是實現目錄建立、解除後螢幕的正確顯示。這只需要呼叫DirectoryOutline的Reset方法即可。

目錄解除過程的實現代碼如下。 

procedure TFMForm.DeleteDirectory1Click(Sender: TObject);

var

path: String;

k: Integer;

begin

{$I-}

path := DirectoryOutline.Directory;

DirectoryOutline.Directory := ExtractFilePath(Path);

if MessageDlg('Delete ' + path + '?', mtConfirmation,[mbYes, mbNo], 0) = idYes then

RmDir(path);

if IOResult <> 0 then

MessageDlg(' Cannot remove directory! The path might not'+

'exist,non-empty or is the current logged directory.',mtWarning,[mbOk], 0)

else

DirectoryOutline.Reset;

end;

修改後的目錄建立過程如下。 

procedure TFMForm.CreateDirectory1Click(Sender: TObject);

var

NewDir: TNewDir;

Dir: String;

begin

{$I-}

NewDir := TNewDir.Create(self);

with NewDir do

begin

CurrentDir.Caption := DirectoryOutline.Directory;

if (ShowModal <> idCancel) and (DirName.Text <> '') then

Dir := ExpandFileName(DirName.text);

end;

MkDir(Dir);

if IOResult <> 0 then

MessageDlg('Cannot Create directory', mtWarning, [mbOk], 0)

else

DirectoryOutline.Reset;

end;

  當完成了這些工作,把程式重新編譯、執行後,可以發現我們所希望實現的功能完全實現了!同時,我們有了一個更好的目錄樹部件。 

6.4.7.4 改變目前工作目錄 

  改變目前工作目錄的實現非常簡單,只要修改DirectoryOutline的Directory屬性。但需注意的是:當改變後目錄所在磁碟機也發生變化時應相應修改DriveTabSet的目前值。由於磁碟機名與DriveTabSet的索引屬性TabIndex之間並沒有確定的對應關係,因而需要通過一個回圈進行找到匹配。

Change Directory的選擇表事件處理過程是FileChange,即與文件的移動、拷貝、更名共用一個事件處理過程。詳細情況請讀者參看(6.4.5.3)中的介紹。

改變目前工作目錄的實現如下。 

procedure TFMForm.ChangeDirectory(Todir: String);

var

i: Integer;

begin

{$I-}

ChDir(ToDir);

if IOResult <> 0 then

MessageDlg('Cannot find directory', mtWarning, [mbOk], 0)

else

begin

with DirectoryOutline do

begin

Directory := ToDir;

Refresh;

if DriveTabSet.Tabs[DriveTabSet.TabIndex][1]<>drive then

for I := 1 to 25 do

if DriveTabSet.Tabs[i][1] = drive then

begin

DriveTabSet.TabIndex := i;

Exit;

end;

end;

end;

end;

6.4.8 一些問題的處理 

6.4.8.1 子視窗的標題 

  Windows的文件管理器是我們設計的楷模,在子視窗顯示標題上也不例外。我們把目前工作目錄加上文件的型式作為子視窗的標題。

過程CreateCaption用於產生子視窗的標題。 

procedure TFMForm.CreateCaption;

var

Cap: String;

begin

Cap := DirectoryOutline.Directory;

Cap := cap+'\'+FileList.mask;

Caption := Cap;

end; 

         目前工作目錄或文件顯示型式發生變化時改變子視窗的標題。如DirectoryOutline的Change事件處理過程和ViewType選擇表項的Click事件處理過程就呼叫了該過程。 

6.4.8.2 狀態條的顯示 

  狀態條用於顯示目前工作目錄和目前選中文件。它們的值在DirectoryOutline 和FileList的Change事件處理過程中修改。

  DirectoryOutline和FileList最終的Change事件處理過程如下: 

procedure TFMForm.DirectoryOutlineChange(Sender: TObject);

begin

CreateCaption;

FileList.clear;

FileList.Directory := DirectoryOutline.Directory;

FileList.Update;

FileManager.DirectoryPanel.Caption := DirectoryOutline.Directory;

end;

procedure TFMForm.FileListChange(Sender: TObject);

begin

with FileList do

begin

if (ItemIndex >= 0) and (Not HasAttr(FileName,faDirectory)) then

begin

TheFileName := FileName;

FileManager.FilePanel.Caption :=

Format('%s, %d bytes', [TheFileName, GetFileSize(TheFileName)]);

end

else

FileManager.FilePanel.Caption := '';

end;

end; 

6.4.8.3 版本資訊 

  當用戶按一下主視窗的Help|About選擇表項時將彈出一個About對話方塊,用於顯示版本資訊(如圖6.13)。

  這一對話方塊是用Delphi提供的模板做的。

6.4.8.4 選擇表項的變灰與使能 

  File選擇表中定義的文件管理功能只有當活動焦點在FileList(即有目前選中文件)時才起作用。否則所有選擇表項應變灰,以免導致系統崩潰。

  這一功能在File選擇表的Click事件處理過程中實現。這一點並不很容易被人想到,希望讀者能從中受到啟發。 

procedure TFMForm.File1Click(Sender: TObject);

var

FileSelected: Boolean;

begin

FileSelected := FileList.ItemIndex >= 0;

Open1.Enabled := FileSelected;

Delete1.Enabled := FileSelected;

Copy1.Enabled := FileSelected;

Move1.Enabled := FileSelected;

Rename1.Enabled := FileSelected;

Properties1.Enabled := FileSelected;

end;

  判斷是否有文件被選中是通過偵測ItemIndex屬性是否大於等於0來實現的。

   FileSelected := FileList.ItemIndex >= 0; 

6.4.8.5 可重用的文件處理模群組 

  庫單元fmxutils是一個代碼庫,提供了若干文件處理模群組。這些模群組除在本程式中使用外,讀者可以在其它應用程式中直接呼叫,而且不必重新編譯,只要在Uses子句中包含即可。從中我們可以體會到,Delphi 以庫單元為中心的程式群群組織方式提供了一種較完善的代碼重用機制。 

6.4.9 小結 

  文件管理器是一個較為綜合的例程,使用到了絕大部分以檔案標簽、文件句柄以及其它參數(除文件變數)為操作物件的文件管理過程/函數,同時也提供了一些程式設計開發的思想。我們的介紹是以程式功能模群組來群群組織的,我建議讀者在學習並試圖自己建立這一程式時採用同樣的方法。(6.4.8)中的內容或許是一開始就應了解的,但其它完全可以按順序逐步地擴充,最後得到一個完整的程式。這一例程在後邊的拖放操作和異常處理等章節中還要用到。讀者可以以此為基礎進一步完善它,使它真正成為一個完全實用的程式。

  文件管理是在開發一個進階的Windows程式中不可避免的要涉及到的問題。本章介紹的思路和方法將為讀者成為一個熟練的程式員奠定基礎。



後一頁
前一頁
回目錄
回首頁