20.3.1.1寫DFM文件的過程:WriteComponentResFie
該過程帶有兩個參數FileName和Instance。FileName參數指定要寫入的DFM文件名,Instance參數是TComponent類型的,它指定要寫入的部件名,一般是TForm對象的子類。該過程將Instance部件和其擁有的所有部件寫入DFM文件。
這個過程的意義在於,可以在程序運行過程中產生Delphi的窗體部件和在窗體中插入部件,並由該函數將窗體寫入DFM文件,支持了動態DFM文件的重用性。
該過程的程序是這樣的:
procedure WriteComponentResFile(const FileName: string; Instance: TComponent);
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmCreate);
try
Stream.WriteComponentRes(Instance.ClassName, Instance);
finally
Stream.Free;
end;
end;
函數中,用FileStream創建文件,用Stream對象的WriteComponetRes方法將Instance寫入流中。
20.3.1.2 讀DFM文件的函數:ReadComponentResFile
ReadComponentResFile函數帶有兩個參數FileName和Instance。FileName參數指定要讀DFM文件名,Instance參數指定從DFM文件中要讀的部件。該函數從DFM文件中將Instance和它擁有的所有部件,並返回該部件。
這個函數的意義在於,配合WriteComponentResFile過程的使用支持DFM文件的重用性。
該函數的程序是這樣的:
function ReadComponentResFile(const FileName: string; Instance: TComponent):
TComponent;
var
Stream: TStream;
begin
Stream := TFileStream.Create(FileName, fmOpenRead);
try
Result := Stream.ReadComponentRes(Instance);
finally
Stream.Free;
end;
end;
程序中使用FileStream對象打開由FileName指定的DFM文件,然後用Stream對象的ReadComponentRes方法讀出Instance,並將讀的結果作為函數的返回值。
20.3.1.3 讀取Delphi應用程序資源中的部件
函數InternalReadComponentRes可以讀取Delphi應用程序資源中的部件。Delphi 的DFM文件在程序經過編譯鏈接後被嵌入應用程序的資源中,而且格式發生了改變,即少了資源文件頭。
在第一節中曾經介紹過TResourceStream對象,該對象是操作資源媒介上的數據的。函數InternalReadComponentRes用了TResourceStream。程序是這樣的:
function InternalReadComponentRes(const ResName: string;
var Instance: TComponent): Boolean;
var
HRsrc: THandle;
begin { 避免“EResNotFound”異常事件的出現 }
HRsrc := FindResource(HInstance, PChar(ResName), RT_RCDATA);
Result := HRsrc <> 0;
if not Result then Exit;
FreeResource(HRsrc);
with TResourceStream.Create(HInstance, ResName, RT_RCDATA) do
try
Instance := ReadComponent(Instance);
finally
Free;
end;
Result := True;
end;
HInstance是一個Delphi VCL定義的全局變量,代表當前應用程序的句柄。函數用了資源訪問API函數FindResource來測定是否存在ResName所描述資源。因為在TResourceStream的創建過程還有FindResource等操作,所以函數中調用了FreeResource。最後函數調用了Stream對象的ReadComponent方法讀出部件。因為函數的Instance是var類型的參數,所以可以訪問Instance,得到讀出的部件。