Delphi构件制作方法 Delphi作为RAD工具，以其编译快速和友好的可视化界面受到广泛欢迎。Delphi提供了很多现成构件，而且随着版本更新不断增加新构件。另外还可以买到第三方开发的构件，也可从因特网下载免费构件。这些构件足以支持一般应用系统的开发。但应用开发人员仍有必要自己制作构件。 基本概念 制作构件的基本过程概括为： 1．编写构件单元（unit）。其中包含构件声明的构件实现代码。
2．编译和调试构件单元。
3创建构件注册单元。用uses语句连接构件单元，用Register过程完成构件的注册。
4．编写构件联机帮助信息，并编译成标准Windows帮助文件。
全部工作完成后，生成构件单元二进制文件（．DCU）。构件注册源文件（．PAS）、帮助信息文件（．HLP）及附加的关键词文件（．KWF）。用户有了这些文件后，就可以安装使用了。
在Delphi环境下调用某单命令，启动安装过程（安装过程中需指定注册文件名），可以把构件注册到DelPhi的VCL库中，并在构件工具条上生成一个新按钮。借助HelpInst安装工具可以把关键词文件并入Delphi帮助索引系统，用F1键实现联机帮助。
这样制作出的．DCU文件与一般Delphi单元没有根本区别，不安装到VCL库中也可以由其它单元直接调用。它们的区别在于：构件单元中某些属性和事件声明为published，从而在程序设计过程中对用户是可见的，用户可以通过对象编辑窗口访问这些属性和事件。这是可视化程序设计的关键所在。

对象的继承与修改
制作构件第一件事就是选择适当的Delphi对象类型作为父对象，以派生新的对象。子对象可以继承父对象的全部非private部件，但不能摆脱不需要的部件。因此，所一选父对象应尽可能多地包含于对象所需的属性、事件和方法，但不应包含子对象不需要的东西。
TComponent是所有Delphi构件的基点，但若直接从TComponent派生新构件，很多东西就需要自己从头做起。一般只有非可视构件才直接从TComponent派生。Delphi提供了若干专门用于制作控件（可视构件）的对象类型，都是从TControl和TWinControl派生而来。其派生关系如下：
TControl-－TGraphlcControl-一TCustomLabel
TWinControl-一TCustomControl-一TCustomGrid
--TButtonControl-一TCustomGroupBox
--TScrollingwinControl--TLustomPanel
--TCustomComboBox
--TCustomEdit
-一TCllstOOLISBOX
TControl的子类型用于非窗口式控件，TWinControl的子类型则用于窗口式控件。除非特殊需要，一般不直接从TControl和TWinControl派生新控件，而是从其子类型派生。这样可以充分利用原有的属性、事件和方法。
在这些构件类型中，非通用的属性、事件和方法都声明为protected。这样可以禁止构件用户访问，又能被子类型继承和修改。在新构件中，可以简单地把继承来的属性和事件重新声明为published，使构件用户能在设计期通过对象编辑窗口访问，也可以进而修改属性的默认值和读写方式，或是重载事件处理子过程和其它构件方法，以修改其中的程序代码。重声明可以放宽访问权限，但不能相反，例如，不可能把pulished属性重声明为priVate或protected。
为了增加新功能，常常需要定义全新的属性、事件和方法。定义时，一般总是把对用户开放的属性和事件声明为published，方法声明为Public或ProtectedO

构件属性
在构件中，属性和方法往往可以相互替代。对构件用户来说，属性比方法更直观简便。因此，只要可能，应尽量以属性取代方法。
属性类型包括简单类型。枚举类型、集合类型、对象类型和数组类型，其定义方法如下：
type
private
Flayers：Integerr；｛内部存储用的变量｝
function CetLayers：Integer；｛用来读属性值的方法｝
procedure SetLayers（ALayers：Integer）；｛用来写属性值的方法｝
published
property Layers：Integer read GetLayers write SetLayers detault 1：end；
每个属性都需要相应的private变量用于内部存储。按照约定，变量名以F打头，后跟属性名（此处为Layers），读写方法名称分别为Get加属性名和S。t加属性名。写方法总是带一个与属性类型相同的参数，用以传送属性值。此参数可以传值，也可以传递变量。如果不定义写方法（省略write部分），此属性便成为只读属性。读写方法应该在private声明，以使其对构件用户和构件的派生对象保持隐蔽。
读写方法除了取值和赋值之外，还可以附加其它操作代码，使属性读写产生附加效应。这是属性可以取代方法的原因。如果不需要附加效应，可以不定义读写方法，采用直接访问格式来声明属性：
property Layers：Integer read FLayers wtite Flayers default 1；
default命令符用来指定属性的默认值，同时需要在构件的构造函数中为属性设置初值。如果省略default命令，属性当前值总是保存在窗体文件中。

事件与事件处理过程
创建构件时，事件也被当做属性来处理，区别仅在于事件必须定义为过程类型，使其成为一个隐蔽指针，指向某个潜在的过程。当构件用户为事件指定处理子程序后，事件便成为指向该于程序的指针。事件的定义方法如下：
type
pyivate
FOnClick：TNotifyEvent； ｛声明事件变量以保存过程指针｝
published
property OnCllck：TNotifyEvent read FOnClick write FonClick；
end；
这是Delphi标准控件中Click事件的定义方式。可以看出，除了OnClick被定义为过程类型外，其定义格式与一般属性的直接访问格式几乎完全相同。DelPhi预定义了所有标准事件的过程类型及标准事件所引发的虚方法。其中， Click事件将引发如下虚方法：
procedure TControl．Click；
begin
if Assigned（OnClick）then OnClick（Self）；
｛以下是默认处理部分｝
end；
其中，Assigned函数检验OnClick是否已分配了事件处理过程。如果返回值为True，则调用用户指定的事件处理过程。通过重载此虚方法，可以修改CliCk事件的处理方式。在重载的方法中，一般应先调用用户处理程序，然后再安排后续处理。
需要注意的是，构件用户不一定会给事件指定处理程序，因此事件不能定义为函数类型，否则可能会指向返回值类型不定的空函数。如果需要事件处理过程返回某个值，可以借助var参数。调用用户程序之前应确保此参数包含有效返回值，以免用户未指定事件处理过程时出错。

构件测试
制作构件的核心工作是编写构件单元，包括根据构件功能要求设定对用户开放的属性、事件和方法，设定用以实现这些部件的变量、过程和函数等等。除了属性和事件有特殊格式之外，构件单元的设计方式与一般Delphi单元没有什么不同，只是单元中不能包含窗体。
在编写构件单元的过程中，可以借助一个测试窗体直接对其测试。
测试时，需先建立一个窗体单元，然后进行以下操作：
1．把被测构件单元名称加人窗体单元的uses语句中，并在pCbliC部分声明被测构件的对象实例。
2．在窗体单元的FormCreate子程序中调用被测构件的Greate方法，以构造构件实例，其Owner参数设置为Self，即窗体本身。然后给Parent属性赋值，并适当设置其它属性值。Parent是容纳构件的父对象，如果是窗体本身，应设置为Self。
3运行包含测试窗体的工程，找出构件程序中的错误。
注册构件用的程序代码可以放在构件单元中，但在Delphi下注册构件时要求提供包含注册代码的源程序文件（．PAS文件），因此，比较好的方式是把构件核心代码编译成．DCU文件或．DLL动态链接库，在注册源文件中只放注册代码和外围程序。
Delphi环境提供了一个构件生成器（component expert），可用来自动生成注册单元。
构件工具条上每个构件需要一个24x24点阵bitmap图标。图标可以借助Delphi的Image Editor编辑生成，以．DCR资源文件的形式提供给构件用户，文件与注册单元文件相同。如果不提供此文件，Delphi将采用默认图标。
（尘土）