Delphi除了支持使用可視化部件所見即所得地建立應用程序外,還支持為開發應用而設計自己的部件。
在本章中將闡述如何為Delphi應用程序編寫部件。這一章將達到兩個目的:
● 教你如何自定義部件
● 使你的部件成為Delphi環境的有機組合部分
19.1 Delphi部件原理
19.1.1 什麼是部件
部件是Delphi應用程序的程序構件。盡管大多數部件代表用戶界面的可見元素,但部件也可以是程序中的不可見元素,如數據庫部件。為弄清什麼是部件可以從三個方面來考察它:功能定義、技術定義和經驗定義。
1. 部件的功能定義
從最終用戶角度,部件是在Component Palette上選擇的,並在窗體設計窗口和代碼窗口中操作的元素。從部件編寫者角度,部件是代碼中的對象。在編寫部件之前,你應用相當熟悉已有的Delphi部件,這樣才能使你的部件適合用戶的需要。編寫部件的目標之一是使部件盡可能的類似其它部件。
2. 部件的技術定義
從最簡單的角度看,部件是任何從TComponent繼承的對象。TComponent定義了所有部件必須要的、最基本的行為。例如,出現在Component Palette上和在窗體設計窗口中編輯的功能。但是TComponent並不知如何處理你的部件的具體功能,因此,你必須自己描述它。
3. 部件編寫者自己的定義。
在實際編程中,部件是能插入Delphi開發環境的任何元素。它可能具有程序的各種復雜性。簡而言之,只要能融入部件框架,部件就是你用代碼編寫的一切。部件定義只是接口描述,本章將詳細闡述部件框架,說明部件的有限性,正如說明編程的有限性。本章不准備教你用所給語言編寫每一種部件,只能告訴編定代碼的方法和怎樣使部件融入Delphi環境。
19.1.2 編寫部件的不同之處
在Delphi環境中建立部件和在應用程序中使用部件有三個重要差別:
● 編寫部件的過程是非可視化的
● 編寫部件需要更深入的關於對象的知識
● 編寫部件需要遵循更多的規則
1. 編寫部件是非可視化的
編寫部件與建立Delphi應用最明顯的區別是部件編寫完全以代碼的形式進行,即非可視化的 。因為Delphi應用的可視化設計需要已完成的部件,而建立這些部件就需要用Object Pascal 代碼編寫。
雖然你無法使用可視化工具來建立部件,但你能運用 Delphi開發環境的所有編程特性如代碼編輯器、集成化調試和對象浏覽。
2. 編寫部件需要更深的有關對象的知識
除了非可視化編程之外,建立部件和使用它們的最大區別是:當建立新部件時,需要從已存部件中繼承產生一個新對象類型,並增加新的屬性和方法。另一方面,部件使用者,在建立Delphi應用時,只是使用已有部件。在設計階段通過改變部件屬性和描述響應事件的方法來定制它們的行為。
當繼承產生一個新對象時,你有權訪問祖先對象中對最終用戶不可見的部分。這些部分被稱為protected界面的。在很大部分的實現上,後代對象也需要調用他們的祖先對象的方法,因此,編寫部件者應相當熟悉面向對象編程特性。
3. 編寫部件要遵循更多的規則
編寫部件過程比可視化應用生成采用更傳統的編程方法,與使用已有部件相比,有更多的規則要遵循。在開始編寫自己的部件之前,最重要的事莫過於熟練應用Delphi自帶的部件,以得到對命名規則以及部件用戶所期望功能等的直觀認識。部件用戶期望部件做到的最重要的事情莫過於他們在任何時候能對部件做任何事。編寫滿足這些期望的部件並不難,只要預先想到和遵循規則。
19.1.3 建立部件過程概略
簡而言之,建立自定義部件的過程包含下列幾步:
● 建立包含新部件的庫單元
● 從已有部件類型中繼承得到新的部件類型
● 增加屬性、方法和事件
● 用Delphi注冊部件
● 為部件的屬性方法和事件建立Help文件
如果完成這些工作,完整的部件包含下列4個文件
● 編譯的庫單元 ( .DCU文件)
● 選擇板位圖 (.DCR文件)
● Help文件 (.HLP文件)
● Help-keyword文件 (.KWF文件)
19.2 Delphi部件編程方法
19.2.1 Delphi部件編程概述
19.2.1.1 Delphi可視部件類庫
Delphi的部件都是可視部件類庫(VCL)的對象繼承樹的一部分,下面列出組成VCL的對象的關系。TComponent是VCL中每一個部件的共同祖先。TComponent提供了Delphi部件正常工作的最基本的屬性和事件。庫中的各條分支提供了其它的更專一的功能。
當建立部件時,通過從對象樹中已有的對象繼承獲得新對象,並將其加入VCL中。
19.2.1.2 建立部件的起點
部件是你在設計時想操作的任意程序元素。建立新部件意味著從已有類型中繼承得到新的部件對象類。
建立新部件的主要途徑如下:
● 修改已有的控制
● 建立原始控制
● 建立圖形控制
● 建立Windows控制的子類
● 建立非可視部件
下表列出了不同建立途徑的起始類
表19.1 定義部件的起始點
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
途 徑 起 始 類
─────────────────────────────
修改已有部件 任何已有部件,如TButton、TListBox
或抽象部件對象如TCustomListBox
建立原始控制 TCustomControl
建立圖形控制 TGraphicControl
建立窗口控制的子類 TWinControl
建立非可視部件 TComponent
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
也可以繼承非部件的其它對象,但無法在窗體設計窗口中操作它們。Delphi包括許多這種對象,如TINIFile、TFont等。
1. 修改已有控制
建立部件的最簡單的方法是繼承一個已有的、可用的部件並定制它。可以從Delphi提供的任何部件中繼承。例如,可以改變標准控制的缺省屬性值,如TButton。
有些控制,如Listbox和Grid等有許多相同變量,在這種情況下,Delphi提供了抽象控制類型,從該類型出發可定制出許多的類型。例如,你也許想建立TListBox的特殊類型,這種部件沒有標准TListBox的某些屬性,你不能將屬性從一個祖先類型中移去,因此你需要從比TListBox更高層次的部件繼承。例如TCustomListBox,該部件實現了TCustomListBox的所有屬性但沒有公布(Publishing)它們。當從一個諸如TCustomListBox的抽象類中繼承時,你公布那些你想使之可獲得的屬性而讓其它的保護起來(protected)。