當前位置:編程學習大全網 - 編程語言 - DELPHI基礎教程:開發Delphi對象式數據管理功能(五)[1]

DELPHI基礎教程:開發Delphi對象式數據管理功能(五)[1]

  第二十章 開發Delphi對象式數據管理功能(五)

 

寫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寫入流中

  讀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 並將讀的結果作為函數的返回值

  讀取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 <> ;

 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 得到讀出的部件

  DFM文件與標準文本文件(TXT文件)的相互轉換

 在Delphi可視化設計環境中 允許程序員在代碼編輯器中以文本的方式瀏覽和修改DFM文件內容 當用File/Open命令直接打開DFM文件或者選擇窗體設計窗口的彈出式菜單上的View as Text命令時 就會在編輯器中出現文本形式的信息 我們姑且將這種文本形式稱之為窗體設計腳本 Delphi提供的這種腳本編輯功能是對Delphi可視化設計的壹大補充 當然這個腳本編輯能力是有限制的 比方說不能在腳本任意地添加和刪除部件 因為代碼和DFM腳本是緊密相連的 任意添加和修改會導致不壹致性 然而在動態生成的DFM文件中 就不存在這壹限制 後面會介紹DFM動態生成技術的應用

 實際上 DFM文件內容是二進制數據 它的腳本是經過Delphi開發環境自動轉化的 而且Delphi VCL中的Classes庫單元中提供了在二進制流中的文件DFM和它的腳本之相互轉化的過程 它們是ObjectBinaryToText和ObjectTextBinary ObjectResourceToText和ObjectTextToResource

 ObjectBinaryToText過程將二進制流中存儲的部件轉化為基於文本的表現形式 這樣就可以用文本處理函數進行處理 還可以用文本編輯器進行查找和替代操作 最後可以將文本再轉化成二進制流中的部件

 ObjectBinaryToText過程的主程序是這樣的

 procedure ObjectBinaryToText(Input Output: TStream)

 var

 NestingLevel: Integer;

 SaveSeparator: Char;

 Reader: TReader;

 Writer: riter;

 procedure WriteIndent;

 const

 Blanks: array[ ] of Char = ;

 var

 I: Integer;

 begin

 for I := to NestingLevel do Writer Write(Blanks SizeOf(Blanks))

 end;

 procedure WriteStr(const S: string)

 begin

 Writer Write(S[ ] Length(S))

 end;

 procedure NewLine;

 begin

 WriteStr(# # )

 WriteIndent;

 end;

 procedure ConvertHeader;

 begin

 …

 end;

 procedure ConvertBinary;

 begin

 …

 end;

 procedure ConvertValue;

 begin

 …

 end;

 procedure ConvertProperty;

 begin

 …

 end;

 procedure ConvertObject;

 begin

 …

 end;

 begin

 NestingLevel := ;

 Reader := TReader Create(Input )

 SaveSeparator := DecimalSeparator;

 DecimalSeparator := ;

 try

 Writer := riter Create(Output )

 try

 Reader ReadSignature;

 ConvertObject;

 finally

 Writer Free;

 end;

 finally

 DecimalSeparator := SaveSeparator;

 Reader Free;

 end;

 end;

 過程中調用的ConvertObject過程是個遞歸過程 用於將DFM文件中的每壹個部件轉化為文本形式 因為由於部件的擁有關系 所以部件成嵌套結構 采用遞歸是最好的方式

 procedure ConvertObject;

 begin

 ConvertHeader;

 Inc(NestingLevel)

 while not Reader EndOfList do ConvertProperty;

 Reader ReadListEnd;

 while not Reader EndOfList do ConvertObject;

 Reader ReadListEnd;

 Dec(NestingLevel)

 WriteIndent;

 WriteStr( end # # )

 end;

 NestStingLevel變量表示部件的嵌套層次 WriteIndent是寫入每壹行起始字符前的空格 ConvertHeader過程是處理部件的繼承標誌信息 轉換成的頭信息文本有兩種形式

 Inherited TestForm : TTestForm[ ]

 或者

 Object TestForm : TTestForm

 前者是ffInherited和ffChildPos置位 後面是都沒置位

 ConvertProperty過程用於轉化屬性

 procedure ConvertProperty;

 begin

 WriteIndent;

 WriteStr(Reader ReadStr)

 WriteStr( = )

 ConvertValue;

 WriteStr(# # )

 end;

 WriteIndent語句寫入屬性名前的空格 WriteStr(Reader ReadStr)語句寫入屬性名ConvertValue過程根據屬性的類型將屬性值轉化為字符串 然後寫入流中

lishixinzhi/Article/program/Delphi/201311/25088

  • 上一篇:和男朋友“相愛相殺”是種怎樣的體驗
  • 下一篇:大智慧公式不能通過
  • copyright 2024編程學習大全網