全國(guó)計(jì)算機(jī)等級(jí)考試二級(jí)Delphi輔導(dǎo)講義 218

字號(hào):

7. SetName方法和OnSetName事件
    因?yàn)樵贠nSetName事件中,Name參數(shù)是var型的,所以可以用OnSetName事件處理過(guò)程修改所讀部件的名字。而OnSetName事件處理過(guò)程是在SetName方法中實(shí)現(xiàn)的。
    procedure TReader.SetName(Component: TComponent; var Name: string);
    begin
    if Assigned(FOnSetName) then FOnSetName(Self, Component, Name);
    Component.Name := Name;
    end;
    SetName方法和OnSetName事件在動(dòng)態(tài)DFM文件的編程中有很重要的作用。
    8. TReader的錯(cuò)誤處理
    TReader的錯(cuò)誤處理是由Error方法和OnError事件的配合使用完成的。OnError 事件處理過(guò)程的Handled參數(shù)是var型的布爾變量,通過(guò)將Handled設(shè)為True或False可影響TReader 的錯(cuò)誤處理。OnError事件處理過(guò)程是在Error方法中調(diào)用的。
    function TReader.Error(const Message: string): Boolean;
    begin
    Result := False;
    if Assigned(FOnError) then FOnError(Self, Message, Result);
    end;
    9. FindMethod和OnFindMethod事件
    有時(shí),在程序運(yùn)行期間,給部件的方法指針(主要是事件處理過(guò)程)動(dòng)態(tài)賦值是很有用的,這樣就能動(dòng)態(tài)地改變部件響應(yīng)事件的方式。在流中讀取部件捍做到一點(diǎn)就要利用OnFindMehtod事件。OnFIndMethod事件是在FindMethod方法中被調(diào)用的。
    function TReader.FindMethod(Root: TComponent;
    const MethodName: string): Pointer;
    var
    Error: Boolean;
    begin
    Result := Root.MethodAddress(MethodName);
    Error := Result = nil;
    if Assigned(FOnFindMethod) then FOnFindMethod(Self, MethodName, Result,
    Error);
    if Error then PropValueError;
    end;
    OnFindMethod 方法除了可以給部件的MethodName所指定的方法指針動(dòng)態(tài)賦值外,還可修改Error參數(shù)來(lái)決定是否處理Missing Method錯(cuò)誤。方法中調(diào)用的MehtodAddress 方法定義在TObject中,它是個(gè)很有用的方法,它可以得到對(duì)象中定義的public方法的地址。FindMethod方法和OnFindMethod事件在動(dòng)態(tài)DFM的編程中有很重要的作用。
    20.3 Delphi對(duì)象式數(shù)據(jù)管理應(yīng)用實(shí)例
    Delphi 2.0無(wú)論是其可視化設(shè)計(jì)工具,還是可視化部件類庫(kù)(VCL),都處處滲透了對(duì)象存儲(chǔ)技術(shù),本節(jié)將從Delphi可視化設(shè)計(jì)內(nèi)部機(jī)制、VCL中的數(shù)據(jù)存儲(chǔ)、BLOB數(shù)據(jù)操作和動(dòng)態(tài)生成部件的存儲(chǔ)幾方面介紹對(duì)象存儲(chǔ)功能的實(shí)例應(yīng)用。
    20.3.1 Delphi 動(dòng)態(tài)DFM文件及部件的存取在超媒體系統(tǒng)中的應(yīng)用
    Delphi的可視化設(shè)計(jì)工具是同其部件類庫(kù)緊密結(jié)合在一起的。
    每個(gè)部件只有通過(guò)一段注冊(cè)程序并通過(guò)Delphi的Install Component功能,才能出現(xiàn)在Component Palette上;部件的屬性才有可能出現(xiàn)在Object Inspector窗口中;部件的屬性編輯器才能被Delphi環(huán)境使用。因?yàn)檫@種渾然天成的關(guān)系,DFM文件存取必然得到VCL在程序上的支持。
    DFM文件的部件存取是Delphi可視化設(shè)計(jì)環(huán)境中文件存取的中心問(wèn)題。因?yàn)镈elphi可視化設(shè)計(jì)的核心是窗體的設(shè)計(jì)。每個(gè)窗體對(duì)應(yīng)一個(gè)庫(kù)單元,是應(yīng)用程序的模塊,窗體在磁盤上的存儲(chǔ)就是DFM文件。
    DFM文件結(jié)構(gòu)我們前面介紹過(guò)了。它實(shí)際上是存儲(chǔ)窗體及其擁有的所有部件的屬性。這種擁有關(guān)系是遞歸的。問(wèn)題在于如何將這些屬性數(shù)據(jù)與程序中的變量(屬性)代碼聯(lián)系起來(lái)。
    在Delphi中處理這種聯(lián)系的過(guò)程分為兩種情況:設(shè)計(jì)時(shí)和運(yùn)行時(shí)。
    在設(shè)計(jì)時(shí),建立聯(lián)系表現(xiàn)為讀取DFM 文件,建立DFM文件中的部件及其屬性與可視化設(shè)計(jì)工具(Object Inspector、窗體設(shè)計(jì)窗口和代碼編輯器)的聯(lián)系,也就是說(shuō)讓這些部件及其屬性能出現(xiàn)在這些窗口中,并與代碼中的屬性定義聯(lián)系起來(lái);分解聯(lián)系表現(xiàn)為存儲(chǔ)DFM文件,將窗體窗口中的部件及其屬性寫入DFM文件。
    在運(yùn)行時(shí),主要是建立聯(lián)系的過(guò)程,即讀取DFM文件。這時(shí),DFM文件不是作為獨(dú)立的磁盤文件,而是以應(yīng)用程序資源中的RCDATA類型的二進(jìn)制數(shù)據(jù)存在。建立聯(lián)系的過(guò)程表現(xiàn)為將資源中的部件及其屬性與應(yīng)用程序中的對(duì)象及其數(shù)據(jù)域聯(lián)系起來(lái)。其過(guò)程為:根據(jù)DFM中的部件類名創(chuàng)建對(duì)象,再將用DFM中的部件屬性值給程序中的部件屬性賦值。當(dāng)然要完成這一過(guò)程,還必須在代碼中有相應(yīng)的窗體定義,因?yàn)榉椒ǖ却a是不存入部件的。
    VCL對(duì)讀取DFM文件在代碼上的支持是通過(guò)Stream對(duì)象和Filer對(duì)象達(dá)到的。在20. 1和20.1節(jié)中,我們可以看到Stream對(duì)象和Filer對(duì)象中有大量的用于存取部件及其屬性的方法,尤其在TReader對(duì)象中,還有關(guān)于錯(cuò)誤處理和動(dòng)態(tài)的方法賦值的方法。下面我們就通過(guò)程序?qū)嵗榻B存取DFM文件方法、步驟和注意事項(xiàng)。
    20.3.1.1寫DFM文件的過(guò)程:WriteComponentResFie
    該過(guò)程帶有兩個(gè)參數(shù)FileName和Instance。FileName參數(shù)指定要寫入的DFM文件名,Instance參數(shù)是TComponent類型的,它指定要寫入的部件名,一般是TForm對(duì)象的子類。該過(guò)程將Instance部件和其擁有的所有部件寫入DFM文件。
    這個(gè)過(guò)程的意義在于,可以在程序運(yùn)行過(guò)程中產(chǎn)生Delphi的窗體部件和在窗體中插入部件,并由該函數(shù)將窗體寫入DFM文件,支持了動(dòng)態(tài)DFM文件的重用性。
    該過(guò)程的程序是這樣的:
    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;
    函數(shù)中,用FileStream創(chuàng)建文件,用Stream對(duì)象的WriteComponetRes方法將Instance寫入流中。