在Windows中的應用程式極大多數擁有自己的初始化文件,如PowerBuilder、Office及Cstar等。因此初始化檔案的讀寫是每個高階程式設計師必須掌握的技術。雖然初始化檔案的讀寫也可用Object Pascal中的文本文件一樣讀寫,但因初始化文件不同於一般的文本文件,它有自己固定的格式(見下面的初始化文件是ucdos中提供的rdfnt.ini文件),如果用文本文件的方式讀寫,不僅格式轉換十分繁瑣,而且很容易出現錯誤,為了方便程式設計師讀寫初始化文件中的數據,Delphi中向用戶提供了一個TIniFile類,透過TiniFile類就可十分方便地讀寫初始化文件。
Ucdos中rdfnt.ini檔案的內容為:
[True Type fonts directory]
Dir=C:WINDOWSSYSTEM
[True Type fonts list]
ARIAL.TTF=64
ARIALBD.TTF=65
ARIALI.TTF=66
ARIALBI.TTF=67
TIMES.TTF=68
TIMESBD.TTF=69
TIMESI.TTF=70
TIMESBI.TTF=71
COUR.TTF=72
COURBD.TTF=73
COURI.TTF=74
COURBI.TTF=75
[Use All True Type fonts]
All=0
TiniFile類不是一個Delphi的部件,因此不能在Delphi的VCL模板中找到,它在Delphi 系統中的inifiles單元中定義,因此要使用TiniFile類,必須在使用該類的單元文件中用Uses inifiles指令明確地說明。
TiniFile類別中定義了許多成員函數,這裡介紹幾個使用頻率較高的成員函數:
⑴ Create()
函數定義為: constructor Create(const FileName: string);
此函數建立TiniFile類別的物件。參數FileName是要讀寫的初始化檔名。
若讀寫的檔案在Windows的目錄裡(如system.ini檔案),則可以直接寫入檔案名稱而不必指定路徑,否則就必須指定路徑(如d:ucdos dfnt.ini)。
如依照下列規則在規定的目錄中存在該文件,則開啟該初始化文件;否則在規定的目錄中建立該初始化文件。
⑵ ReadSections()
過程定義為: PRocedure ReadSections(Strings: TStrings);
這個過程將從所建立的TiniFile類別的物件(即與之關聯的初始化檔案)中讀取所有的節點名(即用[]括號括起的那部分,如rdfnt.ini檔案中的[True Type fonts list])存入字串清單中。參數Strings即為字串列表的變數名。
⑶ ReadSectionValues()
過程定義為: procedure ReadSectionValues(const Section: string; Strings: TStrings);
過程將參數Section的值所對應的節點(如rdfnt.ini檔案中的[True Type fonts list])中的各個關鍵字(如ARIALBI.TTF)及其所含的值(如ARIALBI.TTF關鍵字值為67)讀入參數Strings所指明的字串清單中。
⑷ ReadSection()
過程定義為: procedure ReadSection(const Section: string; Strings: TStrings);
此過程將參數Section的值所對應的節點中的各個關鍵字讀入參數Strings所指明的字串清單中。與ReadSectionValues()不同的是它沒有讀取各個關鍵字的對應值。
⑸ ReadString()
函數定義為: function ReadString(const Section, Ident, Default: string): string;
函數傳回以參數Section的值為節點名稱、參數Ident的值為關鍵字名所對應的關鍵字值(如[True Type fonts list]節中ARIALBI.TTF關鍵字的值為67)。當指定的節點或節內的關鍵字不存在時,則函數會傳回參數Default的預設值。傳回的值是一個字串型資料。
當指定節點中關鍵字值的資料類型不是字串時,則可用ReadInteger()成員函數讀取一個整數值,並用ReadBool()成員函數讀取一個布林值。
⑹ WriteString()
過程定義為: procedure WriteString(const Section, Ident, Value: string);
過程將參數Section的值為節點名、參數Ident的值為關鍵字名的關鍵字值設定為參數Value的值。過程設定的是字串型資料。
當指定節點和關鍵字都存在時,則以Value的值取代原值;如指定節點不存在,則在關聯的初始化檔案中自動增加一個節點,該節點的值為參數Section的值,並在該節點下方自動增加一個關鍵字,關鍵字名為參數Ident的值,該關鍵字對應的值為參數Value的值;若節點存在,但關鍵字不存在,則在該節點下自動增加一個關鍵字,關鍵字名為參數Ident的值,此關鍵字對應的值為參數Value的值。
若要設定整數值,可呼叫WriteInteger()成員函數;用WriteBool()成員函數設定布林值。
知道了以上函數的作用,要建立或讀寫一個初始化檔就不難了。以下以一個實際範例說明初始化檔案的讀取方法,步驟如下:
⒈ 在需要讀取和寫入初始化檔案的窗體(Form)上放置一個名為SectionComboBox、IdentComboBox的兩個組合式列錶框,其中SectionComboBox存放節點名,IdentComboBox存放所選節點的關鍵字名。一個名為IdentValueEdit的輸入框,存放對應關鍵字的值。名為CmdChang的修改指令鈕可以用來修改關鍵字的值,修改後用名為CmdSave的儲存指令鈕將修改後的關鍵字的值存入關聯的初始化檔。窗體對應的單元名設為IniUnit,窗體名設為IniForm,窗體佈局如下圖一所示:
⒉ 在IniUnit單元的interface部分用uses inifiles;說明要引用的TiniFile類別所定義的單元名稱。並在變數說明部分定義TiniFile類別的對象,如
var IniFile: TiniFile;
⒊ 建立窗體的OnCreate事件過程。使用TIniFile類別的Create成員函數建立TIniFile對象,用該物件讀寫d:ucdos目錄中的rdfnt.ini初始化文件,並將該初始化文件中的所有節點透過ReadSections() 成員函數讀入SectionComboBox組合式列錶框中,用ReadSection()成員函數將第一個節點中的所有關鍵字讀入IdentComboBox組合式列錶框,用ReadString()成員函數將第一個關鍵字的值送入IdentValueEdit輸入框。
⒋ 建立SectionComboBox組合式列錶框的OnChange事件過程。當該選擇列錶框中的不同項目(即不同的節點名)時,用ReadSection()成員函數將選節點中的所有關鍵字讀入IdentComboBox 組合式列錶框,並用ReadString()成員函數將第一個關鍵字的值送入IdentValueEdit輸入框。
⒌ 建立IdentComboBox組合式列錶框的OnChange事件過程。當該選擇列錶框中的不同項目(即不同的關鍵字名)時,用ReadString()成員函數將該關鍵字的值送入IdentValueEdit輸入框。
⒍ 建立指令鈕CmdChang的OnClick事件過程。使IdentValueEdit輸入框中的內容可以修改(不按該指令鈕,IdentValueEdit輸入框是不能修改的),並設定指令鈕CmdSave有效,可以將修改後的關鍵字值存入關聯的初始化檔中。
⒎ 建立指令鈕CmdSave的OnClick事件過程。如果關鍵字值已改變,則呼叫WriteString()成員函數將修改後的關鍵字的值記憶體。
⒏ 建立窗體的OnDestroy事件過程。當窗體失效時,將建立的TIniFile物件釋放,以釋放該物件所戰用的系統資源。
至此,運行工程,初始化檔案的讀寫已能順利進行。當然也可以使用EraseSection()成員函數刪除指定的節,也可用DeleteKey()成員函數刪除指定的關鍵字,因篇幅有限,這裡就不詳細介紹了,有興趣的可參考Delphi的使用幫助。
下面是該單元的原始程式碼:
unit IniUnit;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, inifiles;
type
TIniForm = class(TForm)
SectionComboBox: TComboBox;
Label1: TLabel;
CmdSave: TButton;
CmdChang: TButton;
IdentComboBox: TComboBox;
IdentValueEdit: TEdit;
Label2: TLabel;
Label3: TLabel;
procedure FormCreate(Sender: TObject);
procedure SectionComboBoxChange(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure CmdChangClick(Sender: TObject);
procedure CmdSaveClick(Sender: TObject);
procedure IdentComboBoxChange(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
IniForm: TIniForm;
{ Delphi中透過TIniFile類別讀寫Windows的初始化檔}
IniFile: TIniFile;
implementation
{$R *.DFM}
procedure TIniForm.FormCreate(Sender: TObject);
begin
{ 使用TIniFile類別的Create成員函數建立TIniFile對
象,該物件用來讀寫d:ucdos目錄中的rdfnt.ini文件,
如果讀寫的檔案在Windows的目錄裡(如system.ini),
則可以直接寫入檔案名稱而不必指定路徑}
IniFile:=TIniFile.Create('d:ucdos dfnt.ini');
{ 將TIniFile物件關聯的初始化檔案system.ini中的所
有節(即用[]括號括起的那部分)的節名送入下拉式組
合列錶框SectionComboBox中}
SectionComboBox.Clear;
IniFile.ReadSections(SectionComboBox.Items);
{ 選擇system.ini檔案的第一個節名}
SectionComboBox.ItemIndex:=0;
SectionComboBoxChange(Sender);
CmdSave.Enabled:=False;
end;
{ 將組合列錶框IniComboBox中所選節中對應的各個
變數及對應的值送入多行文字編輯器IniMemo中}
procedure TIniForm.SectionComboBoxChange(Sender: TObject);
begin
IdentComboBox.Clear;
IniFile.ReadSection(SectionComboBox.Text,
IdentComboBox.Items);
IdentComboBox.ItemIndex:=0;
IdentComboBoxChange(Sender);
end;
procedure TIniForm.IdentComboBoxChange(Sender: TObject);
begin
IdentValueEdit.Enabled:=False;
{ 將選擇的關鍵字值讀入}
IdentValueEdit.Text:=
IniFile.ReadString(SectionComboBox.Text,
IdentComboBox.Text,');
end;
procedure TIniForm.CmdChangClick(Sender: TObject);
begin
CmdSave.Enabled:=True;
IdentValueEdit.Enabled:=True;
IdentValueEdit.SetFocus;
end;
procedure TIniForm.CmdSaveClick(Sender: TObject);
begin
if IdentValueEdit.Modified then begin
IniFile.WriteString(SectionComboBox.Text,
IdentComboBox.Text,
IdentValueEdit.Text);
end;
IdentValueEdit.Enabled:=False;
CmdSave.Enabled:=False;
end;
procedure TIniForm.FormDestroy(Sender: TObject);
begin
IniFile.Free; { 釋放已建立的物件}
end;
end.
以上方法在Windows 95下用Delphi 3.0調試通過。