這里所顯示的刪除操作簡單明了。但在程序開始設(shè)計(jì)時我卻走了一條彎路,后來發(fā)現(xiàn)雖然這種方法用于記錄的刪除操作顯得笨拙、可笑,但卻恰恰是記錄插入、排序的思想。
這種思想的核心是創(chuàng)建一個新文件保存更新后的內(nèi)容。若新文件順利創(chuàng)建,則刪除原文件,否則恢復(fù)原來的文件。程序清單如下:
procedure TRecFileForm.DeleteButtonClick(Sender: TObject);
var
NewFile: MethodFileType;
MethodRec: TMethod;
NewFileName: String;
i: Integer;
begin
if FileOpened = False then Exit;
CurrentRec := StringGrid1.Row-1;
if CurrentRec < 0 then Exit;
if MessageDlg('Delete Current Record ?', mtConfirmation,
[mbYes, mbNo], 0) = idYes then
begin
HazAttr.text := '';
NewFileName := ChangeFileExt(FileName,'.sav');
try
AssignFile(NewFile,FileName);
ReWrite(NewFile);
Except
On EInOutError do
begin
Rename(MethodFile,FileName);
Exit;
end;
end;
for i := 1 to Count do
if I <> CurrentRec+1 then
begin
MethodRec := GridToRec(i);
Write(NewFile,MethodRec);
end;
closeFile(MethodFile);
try
AssignFile(MethodFile,Filename);
Reset(MethodFile);
except
on EInOutError do
begin
DeleteFile(FileName);
AssignFile(MethodFile,NewFileName);
Reset(MethodFile);
Rename(MethodFile,FileName);
Exit;
end;
DeleteFile(NewFileName);
Count:=Count-1;
ChangeGrid;
end;
end;
對于記錄插入,方法基本同上。對于排序,可先將關(guān)鍵域讀入排序,而后再按排序結(jié)果對應(yīng)的記錄號順序重寫文件。
6.2.8 結(jié)果綜合
對不同方法的評估結(jié)果,可按一定的公式進(jìn)行綜合。當(dāng)用戶按下“計(jì)算”按鈕時,系統(tǒng)進(jìn)行計(jì)算并把綜合結(jié)果寫入HazAttr只讀編輯框中。
為保證結(jié)果顯示的正確性,每次增加、修改、刪除操作確認(rèn)后HazAttr編輯框清空。
6.2.9 編輯對話框的輸入檢查
當(dāng)用戶單擊“增加”或“修改”按鈕時系統(tǒng)將彈出一個編輯對話框,讓用戶輸入或修改記錄內(nèi)容。其中的三個編輯框,一個組合列表框分別對應(yīng)TMethod 的四個域。由于TMethod的Result域必須是[0,1]間的小數(shù),因此當(dāng)用戶按OK鍵關(guān)閉對話框時應(yīng)進(jìn)行類型和范圍檢查。
在VB中我做過同樣的工作,那時需要對用戶輸入的鍵碼逐個進(jìn)行判斷。但這種方法很繁瑣、很難做圓滿(如不能很好地支持編輯鍵)。而Object Pascal提供了更好的方法。這種方法的關(guān)鍵就在于它的類型轉(zhuǎn)換函數(shù)Val:
procedure Val(Str: String;var V; var Code: Integer);
V是由Str轉(zhuǎn)換成的整型或?qū)嵭蛿?shù)。若字符串非法,則出錯位置返至Code;否則置Code為0。字符串非法并不會引發(fā)一個轉(zhuǎn)換異常。
如果轉(zhuǎn)換后的數(shù)超出了我們的范圍,則顯式把Code置為-1。最后統(tǒng)一通過檢測Code是否為0來判斷輸入是否合法。
我們把輸入檢查放在對話框的OnCloseQuery事件處理過程中。如輸入非法,則禁止對話框關(guān)閉,并將輸入焦點(diǎn)置于Result編輯框中。但假如用戶按了Cancel按鈕,則這種檢查是多余的。為此定義一個布爾變量IsCancel,對話框生成時置為False。假如用戶按下Cancel,則置為True,此時OnCloseQuery事件不進(jìn)行輸入檢查。
對話框的OnCloseQuery事件處理過程的程序清單如下:
procedure TEditForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
Res: Real;
k: Integer;
begin
if IsCancel = False then
begin
val(Result.text,Res,k);
if (Res > 1) or (Res < 0) then k := -1;
if k <> 0 then
begin
MessageDlg('非法輸入 !',mtWarning,[mbOK],0);
Result.text := '';
CanClose := False;
Result.SetFocus;
end;
end;
end;
6.2.10 文件和系統(tǒng)的關(guān)閉
文件關(guān)閉須調(diào)用CloseFile過程:
CloseFile(MethodFile);
并對系統(tǒng)的狀態(tài)重新進(jìn)行設(shè)置。
系統(tǒng)關(guān)閉時首先檢測當(dāng)前是否有打開的文件。若有則先關(guān)閉文件。這在主窗口的OnCloseQuery事件中實(shí)現(xiàn)。
實(shí)現(xiàn)文件關(guān)閉的程序清單如下:
procedure TRecFileForm.CloseButtonClick(Sender: TObject);
begin
if FileOpened then
begin
CloseFile(MethodFile);
FileOpened := False;
ClearGrid;
OpenButton.Enabled := True;
NewButton.Enabled := True;
CloseButton.Enabled := False;
RecFileForm.Caption := FormCaption;
end;
end;
實(shí)現(xiàn)系統(tǒng)關(guān)閉前檢查的程序清單如下:
procedure TRecFileForm.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
if FileOpened then
closeFile(MethodFile);
end;
6.2.11 記錄文件小結(jié)
我們所舉的例子雖然簡單,但基本覆蓋了記錄文件操作的主要方面。這里關(guān)鍵問題在于靈活應(yīng)用Delphi提供的文件管理函數(shù)。同時,為了保證程序的健壯性應(yīng)對異常進(jìn)行捕獲并處理。在數(shù)據(jù)庫應(yīng)用技術(shù)發(fā)展的今天,記錄文件的重要性也許有所下降,但對象我們這里所處理的簡單問題它仍有用武之地。
這里所舉的例子一次只能處理一個文件。但讀者可以很容易把它改為一個MDI程序。雖然對于這里的實(shí)際情況來說,似乎并無必要。
6.3 文件控件的應(yīng)用
Delphi文件管理的最大特色是提供了一組文件操作控件。利用這些控件我們可以快速開發(fā)一個文件名瀏覽系統(tǒng)。其功能強(qiáng)大與其所需書寫代碼之少所形成的強(qiáng)烈反差,正是Dephi生命力的體現(xiàn)。
6.3.1 文件控件及其相互關(guān)系
Delphi提供的專用文件控件如下表所示。
表6.4 Delphi專用文件控件
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
控件名 功能
─────────────────────────────────────
DriveComboBox 驅(qū)動器組合列表框。用于選擇當(dāng)前驅(qū)動器
FileListBox 文件列表框。用于顯示當(dāng)前目錄中的文件和選中當(dāng)前文件
FilterComboBox 文件類型組合列表框。用于選擇顯示文件的類型
DirectoryOutline 目錄樹(6.4節(jié)專門介紹)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
以上控件前四個在Component Palette(部件選擇板)的System頁中,DirectoryOutline在Component Palette的Samples頁中。
以上文件控件再加上文件編輯框、目錄標(biāo)簽框(事實(shí)上是一般的編輯框、標(biāo)簽框)就可以構(gòu)成一個完整的文件操作系統(tǒng)。它們之間的聯(lián)系幾乎不用代碼支持,只要設(shè)置好相應(yīng)的屬性就可以了。
FileEdit、DirLabel、FileListBox、FileFilterComloList、 DirectoryListBox、DriveComboList六個控件間的屬性聯(lián)系如下:
DriveComboList .DirList := DirectoryListBox;
DirectoryListBox.DirLabel := DirLabel;
DirectoryListBox.FileList := FileListBox;
FileFilterComboList.FileList := FileListBox;
FileListBox.FileEdit := FileEdit;
以上聯(lián)系可以在設(shè)計(jì)時完成。只要打開相應(yīng)屬性的選擇列表框進(jìn)行選擇即可。也可以在運(yùn)行時利用如上的賦值語句建立聯(lián)系。
文件控件的關(guān)鍵屬性基本上都在以上聯(lián)系中反映出來了。除此之外,F(xiàn)ileFilterComboList有一個Filter屬性,用來設(shè)置組合列表框的選擇項(xiàng);FileListBox 有一個Mask屬性,用于設(shè)置顯示文件的類型,這就允許FileListBox在脫離FileFilterComboList單獨(dú)應(yīng)用時仍能根據(jù)需要顯示特定的文件。在6.4節(jié)中我們將應(yīng)用這一功能。
文件控件的方法、事件基本是從ListBox和ComboBox中繼承的。但FileListBox 中有一個ApplyFilePath方法很有用,我們將在后邊給出其用法。
6.3.2 文件名瀏覽查找系統(tǒng)的設(shè)計(jì)思路
作為文件控件的應(yīng)用實(shí)例,我們開發(fā)了一個簡單的文件名瀏覽查找系統(tǒng)。這個系統(tǒng)可用于文件名的顯示,把選中的文件寫入列表框,并能按文件編輯框中輸入的通配符對文件進(jìn)行查找。
表6.5 部件的設(shè)計(jì)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
部件 屬性 功能
─────────────────────────────────────
FileCtrForm Position=poDefault 主窗口
DirLabel 顯示當(dāng)前目錄
FileEdit TabOrder=0 顯示當(dāng)前文件/輸入文件顯示匹配符
FileListBox1 FileEdit=FileEdit 顯示當(dāng)前目錄文件
DirectoryListBox1 DirLabel=DirLabel 顯示當(dāng)前驅(qū)動器目錄
FileList= FileListBox1
DriveComboBox1 DirList= DirectoryListBox1 選擇當(dāng)前驅(qū)動器
FilterComboBox1 FileList=FileListBox1 選擇文件顯示類型
Filter='All Files(*.*)|*.*|
Source Files(*.pas)|*.pas|
Form Files(*.dfm)|*.dfm|
Project Files(*.dpr)|*.dpr'
ListBox1 顯示選中或查找的文件
Button1 Caption='查找' 按 FileEdit 中的內(nèi)容進(jìn)行查找
Button2 Caption='退出' 退出系統(tǒng)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
相關(guān)推薦:2010年9月計(jì)算機(jī)等級考試試題及答案解析專題北京 | 天津 | 上海 | 江蘇 | 山東 |
安徽 | 浙江 | 江西 | 福建 | 深圳 |
廣東 | 河北 | 湖南 | 廣西 | 河南 |
海南 | 湖北 | 四川 | 重慶 | 云南 |
貴州 | 西藏 | 新疆 | 陜西 | 山西 |
寧夏 | 甘肅 | 青海 | 遼寧 | 吉林 |
黑龍江 | 內(nèi)蒙古 |