delphi编写自定义组件
- 格式:pdf
- 大小:2.23 MB
- 文档页数:49
Delphi 自定义控件设计邓清闯,张丹,姬希娜,李国杰(河南许昌许继电气有限公司中试部,许昌461000)摘要:通过一个实例程序,系统、详尽地讲解了如何设计Delphi 的自定义控件。
该控件代码技术难度不高,旨在说明Delphi 控件的设计方法,包括自定义控件创建向导、代码设计、图标设计及控件发布。
关键词:控件;自定义控件;Delphi 控件Delphi 语言受众多程序员追捧,主要原因之一就是它有很多第三方的控件可供使用。
很多资深的Delphi 程序员都把自己积累的函数、过程等设计成控件,以方便使用,提高开发效率。
本文通过一个只允许输入数字、并且可以设置输入值范围和小数点位数的编辑框控件的设计,详细介绍了控件的实现方法。
该控件继承自edit 控件,控件单元名称为NumEdit ,控件类名称为TNumEdit 。
控件的实现主要分为4个阶段:(1)建立控件原型。
(2)设计控件功能代码。
(3)设计控件图标。
(4)安装发布控件。
下面对这四个阶段进行详细讲解。
1建立控件原型可以通过Delphi 向导建立控件原型。
通过Delphi 菜单“File-New-Other ”打开“New Items ”对话框,然后在New 属性页中选择“Component ”,点击“OK ”,弹出“New Compo -nent ”对话框,在该对话框中设置控件的基本信息,如图1。
Ancestor type :选择控件要继承的类,选择“TEdit (StdC -trls )”。
Class Name :要创建的控件的类名称,我们设置为“TNumEdit ”。
Palette Page :该自定义控件发布后将要停靠的控件面板。
Unit file name :该控件代码存放路径。
设置好上面信息后,点“OK ”按钮,向导自动生成最原始的控件代码,如下:unit NumEdit;//单元名称Interfaceuses //该控件需要调用的单元SysUtils,Classes,Controls,StdCtrls;typeTNumEdit =class (TEdit)//控件类,继承自TEdit private //私有成员{Private declarations }protected //保护成员{Protected declarations }public //公有成员{Public declarations }published //发布成员{Published declarations }end;procedure Register;//过程声明implementation//下面函数功能是将控件TNumEdit 的图标显示在Samples //面板上procedure Register;beginRegister Components ('Samples',[TNumEdit]);end;end.到目前为止,控件TNumEdit 已经具备了Tedit 编辑框的所有功能,下面就可以在这个基础上设计需求的功能了。
Delphi VCL 高级组件编程之设置自定义子组件的属性作者:金海龙(天主教)Google搜索:金海龙天主教,delphi VCL components,writecomponent,programming,setsubcomponent(true),TTestPanel今天打开软件开发经验记录本,发现一个以前没有解决的组件编程问题。
现在,我是开发Delphi 第三方组件的高手了,对于刚入门时的问题,解决一下,不留遗憾。
当时对这个问题的描述如下:“TestPanel组件有一个P子控件,通过下面的代码,只能够在设计时,改变P的属性,但是运行之后,你就会发现,P没有任何变化,即:在设计时所作的修改,全部无效。
”当时的努力写了下面的代码:TestPanel.pasunit TestPanel;interfaceusesWindows, Messages, graphics,SysUtils, Classes, Controls, ExtCtrls, ComCtrls;typeTTestPanel = class(TPanel)p:TPanel;private{ Private declarations }Function Getp:TPanel;Procedure Setp(Value:TPanel);protected{ Protected declarations }procedure CreateWindowHandle(const Params: TCreateParams); override; public{ Public declarations }constructor Create(AOwner: TComponent); override;destructor Destroy; override;published{ Published declarations }Property panel : TPanel Read Getp Write Setp;end;procedure Register;implementationFunction TTestPanel.Getp:TPanel;beginresult:=p;end;Procedure TTestPanel.Setp(Value:TPanel);beginif p<>Value thenp:=Value;end;procedure TTestPanel.CreateWindowHandle(const Params: TCreateParams); begininherited CreateWindowHandle(Params);with p dobeginwidth:=50; height:=50;left:=10; top:=10;color:=clred;end;end;constructor TTestPanel.Create(AOwner: TComponent);begininherited Create(AOwner);p:=tpanel.Create(self);p.parent:=self;width:=100; height:=100;end;destructor TTestPanel.Destroy;beginp.Free;inherited destroy;end;procedure Register;beginRegisterComponents('Jin Hailong', [TTestPanel]);end;end.看了上面的描述,明白了我当初的意图:设计一个包含子组件的Panel, 这个组件叫“TTestPanel”,它的子组件叫:P,它们都继承于TPanel,在设计时,使用属性编辑器可以改变子组件p的属性,但是按下F9调试程序,却发现所做的设置无效。
Delphi自定义控件开发Delphi控件开发浅入深出一Delphi程序员不是真正的程序员Delphi正是由于高度的可扩展性和大量的第三方控件的支持才能吸引无数程序员挑剔的目光即使是由于工作需要使用其他开发工具的开发者也常常怀念和Delphi度过的日日夜夜接触Delphi已经一年多了从当初对着Delphi组件面板上上百个控件不知所措到现在已经可以根据需要开发一些有一定难度的控件其中走过的路是十分艰辛的所以特此写下这篇文章将自己的经验留给后来者也算是献给同门师弟的一份厚礼吧需要说明的一点是在写这篇文章之前我假设读者已经对面向对象的基本知识有一定的了解所以对于文章中面向对象相关的概念将不再展开讲述一牛刀小试-TURLLabel控件我们从一个能够添加超链接的标签控件开始我们的控件开发之旅吧既然是Label我们就从Tlabel派生这个控件吧其实从TcustomLabel派生最好不过出于简单的目的我们这里先从Tlabel派生1选择File- New- Component将弹出如下的对话框在Ancestor type中选择TlabelClassName中填入TURLLabel名字可以任意取但是要以T开头否则的话会出现注册控件时候的问题这里Ancestor type代表控件的基类TURLLabel代表控件的名称2超链接的视觉效果是带下划线的文字所以我们覆盖父类的构造函数在构造函数里修改控件的字体属性constructorTUrlLabelCreateAOwnerTComponentbegin inherited CreateAOwner CursorcrHandPoint FontStyle [fsUnderline] end代码解释1 inherited CreateAOwner这句的意思是执行父类的构造函数我们制作控件的时候如果覆盖了父类的构造函数那么在新的构造函数中一定要首先调用父类的构造函数否则会引起错误这是很多初学控件开发的人常常遇到的问题当您把自己开发的控件从面板上拖放到窗体时如果跳出一个Access Violent的错误对话框的话那么十有八九是因为您忘了调用父类的构造函数 2 CursorcrHandPointFontStyle [fsUnderline] 这三句的意思是修改标签的视觉效果CursorcrHandPoint是设定当鼠标移动到控件上时鼠标的形状为手型FontStyle [fsUnderline] 是设定文字的下划线效果3既然是超链接控件那么我们肯定要能使用户在使用控件的时候能在Object Inspector中对超链接的URL进行修改所以我们应该为控件增加一个Url属性属性是访问控件字段的接口通过属性控件使用者可以间接读或者写控件的内部字段改变控件的状态组件属性的声明需要以下几部分属性名属性类型读方法或读字段写方法或写字段如果没有写方法或写字段则该属性为只读属性属性在控件类声明的Published部分声明在Published中声明的属性可以在设计期通过Object Inspector对属性值进行修改如果声明在Public部分则不可以在设计期通过Object Inspector对属性值进行修改但是可以在运行时通过代码进行读写在类声明的Private访问区域中添加如下字段声明 FUrl String 在类声明中添加Published访问区域并添加如下代码property Url String read FUrl write FUrl这段声明的意思是为控件添加一个Url属性属性的类型是string在读Url 属性时返回Furl的值在写 Url属性时设定Furl的值4超链接的视觉效果有了下面使它点击时调用浏览器打开Url指定的网址在Delphi控件的事件处理中很多事件都有对应的一个调度方法这是设计模式中模板模式的典型应用比如在鼠标点击控件时控件会首先调用Click方法由Click方法进行相应的处理而绝大多数调度方法都会引发一个事件句柄关于事件句柄我们后边有深入的介绍比如Tlabel 控件中在用户用点击Label时会首先调用控件的Click方法被声明为Protected级别Click方法再触发OnClick事件所以我们只要覆盖Tlabel的Click方法进行我们自己的处理就可以了在Protected部分添加如下的声明procedure Clickoverride 在实现部分为Click 方法写如下的代码procedure TUrlLabelClickbegin ShellExecuteApplicationHandle nil PCharUrl nil nilSW_NORMAL inheritedend代码解释1 ShellExecute的作用是用默认的程序打开第三个参数指定的文件所以当第三个参数为一个URL时则用浏览器打开这个网址关于ShellExecute其他参数的使用方法可以查阅MSDN 或其他相关资料2 Inherited的作用是调用父类的Click方法来由父类来对鼠标单击事件做其他的处理5源代码下面给出这个控件的全部源代码unit UrlLabelinterfaceuses Windows MessagesSysUtils Classes Controls StdCtrlsShellapi Graphics Formstype TUrlLabel classTLabel privateFUrlAnsiString protected procedure Clickoverridepublic constructor CreateAOwnerTComponentoverride published property UrlAnsiString read FUrl write FUrl endprocedure RegisterimplementationconstructorTUrlLabelCreateAOwnerTComponentbegin inheritedCreateAOwner CursorcrHandPointFontStyle[fsUnderline]endprocedure TUrlLabelClickbegin ShellExecuteApplicationHandle nil PCharUrl nil nilSW_NORMAL inheritedendprocedure Registerbegin RegisterComponentsLinco [TUrlLabel]控件生成向导生成的注册控件用代码endend6为控件添加图标如果没有给自定义的控件定义图标出现在控件面板上的自定义图标的图标是默认的图标很没有个性也不容易被用户与其他控件区别开来所以我们需要给组件指定一个图标首先利用Delphi的Image Editor创建一个2424的位图并把它保存到一个DCR文件中创建了一个位图后就需要给位图命名了位图的名称必须和控件的类名相同且为大写而DCR文件的名字则必须与控件所在单元的单元名相同如我们上边定义的控件位图的名字应该为TURLLABELDCR文件的名字应该是UrlLabeldcr此DCR文件应该与组件的单元文件放在同一个目录下打开Image Editor选择File-New - Component Resource Filedcr如下图在Contents上单击鼠标右键选择New- BitMap在WidthHeight中都填入24点OK即可可以在Bitmap1上点右键选择Rename为位图重命名为TURLLABEL然后双击TURLLABEL就可以像使用画图一样为您的控件设计图标了7注册组件点击Componet- Install Componet进行自定义组件安装此时将出现组件安装对话框在Unit FilName 中输入控件单元文件的文件名包括路径点击OK在弹出的Package Editor 中按下Install按钮如果安装成功系统就会提示安装成功关闭Package Editor时会提示您是否保存修改点击Yes即可安装成功建立一个测试程序将URLLabel 控件放到窗体上设定Url属性为httpcom 运行程序点击此Label就会弹出浏览器打开httpcom个网址思考题12Delphi3http开头且用户在编辑框上按回车时用浏览器打开此网址Delphi控件开发浅入深出二通过开发上边这个控件我们已经对Delphi控件开发有了基本的认识下面我们将系统的讲述一下控件开发的知识制作控件第一件事就是选择适当的 Delphi对象类型作为父对象以派生新的对象子对象可以继承父对象的全部非 private部件但不能摆脱不需要的部件因此所选父对象应尽可能多地包含子对象所需的属性事件和方法但不应包含子对象不需要的东西Delphi必须从Tcomponent或Tcomponent的子类派生TComponent是所有 Delphi控件的基点但若直接从 TComponent 派生新控件很多东西就需要自己从头做起一般只有非可视控件才直接从 TComponent派生 Delphi提供了若干专门用于制作控件可视控件的对象类型都是从 TControl和 TWinControl 派生而来TControl的子类型用于非窗口式控件 TWinControl的子类型则用于窗口式控件除非特殊需要一般不直接从 TControl和TWinControl派生新控件而是从其子类型派生这样可以充分利用原有的属性事件和方法减少很多工作量在这些控件类型中非通用的属性事件和方法都声明为 protected这样可以禁止控件用户访问又能被子类型继承和修改在新控件中可以简单地把继承来的属性和事件重新声明为 published使控件用户能在设计期通过对象编辑窗口访问也可以进而修改属性的默认值和读写方式或是重载 override事件处理子过程和其他控件方法以修改其中的程序代码重声明可以放宽访问权限但不能相反例如不可能把 published属性重声明为 private 或 protected Delphi控件也是Delphi的类所有的控件都有特定的结构一般控件包括三大组成部分属性方法和事件下面先介绍初学控件开发的最难懂的属性部分其他部分我们将在以后章节为大家介绍属性主要部分就是属性的读写方法或读写字段前面的例子用的是读写字段也就是对属性的读写都通过对字段的读写来完成下面为大家讲解一下读写方法的使用方法TmyComponent classTComponentPrivate Fcount Integer Procedure SetCountAvalue IntegerPulbished。
Delphi⼀个简单的DELPHI⾃定义事件的例⼦unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;type//定义⼀个事件格式,要传参数的格式后⾯必须要加上of objectTeacherArgnyEvent = procedure(ErrorCount: Integer) of object;typeTTeacher = class(TObject)privateFStudentErrorCount: Integer;FOnTeacherArngy: TeacherArgnyEvent; //定义⼀个内部事件,private⾥的只能在TTeacher类内部调⽤procedure SetStudentErrorCount(Value: Integer);publicconstructor Create;destructor Destroy; override;property StudentErrorCount: Integer read FStudentErrorCount write SetStudentErrorCount ;property OnTeacherArngy: TeacherArgnyEvent read FOnTeacherArngy write FOnTeacherArngy ; //定义⼀个外部的事件,在其它的对象⾥⾯可以通过FTeacher.ONTeacherArngy这样调⽤。
读写是通过内部的FOnTeacherArngyend;typeTForm1 = class(TForm)Button1: TButton;procedure FormCreate(Sender: TObject);procedure FormClose(Sender: TObject; var Action: TCloseAction);procedure Button1Click(Sender: TObject);procedure IfTeacherArngy(EC: Integer); //⾃⼰定义事件触发时要执⾏的函数,和Button控件在事件列表中双击时出来的那段代码⼀样,只是这⾥是你⾃⼰定义的,⽽不是DELPHI给你⽣成的privateFTeacher: TTeacher ;public{ Public declarations }end;varForm1: TForm1;implementation{$R *.dfm}{ TTeacher }constructor TTeacher.Create;beginFStudentErrorCount := 0;end;destructor TTeacher.Destroy;begininherited;end;procedure TTeacher.SetStudentErrorCount(Value: Integer);beginFStudentErrorCount := Value;if FStudentErrorCount > 3 then //给StudentErrorCount赋值的时候,判断是否触发FOnTeacherArngy事件if Assigned(FOnTeacherArngy) then //看FOnTeacherArngy是否为空,不为空则执⾏该事件,如果不判断是否为空,则执⾏下⾯⼀句的时候可能会有错误FOnTeacherArngy(FStudentErrorCount);end;{ TForm }procedure TForm1.FormCreate(Sender: TObject);beginFTeacher := TTeacher.Create ; //创建⼀个TTeacher的实例FTeacher.OnTeacherArngy := IfTeacherArngy; //把FOrm1⾥的IfTeacherArngy过程赋值给FTeacher的OnTeacherArngy,这样它就不为空了end;procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);beginFTeacher.Free ; //窗体关闭时释放end;procedure TForm1.Button1Click(Sender: TObject);beginFTeacher.StudentErrorCount := FTeacher.StudentErrorCount + 1; //给StudentErrorCount赋值,我只是给他赋值,就会触发那个事件// 有了这个类,就不⽤下⾯这⼀段了,给 StudentErrorCount属性赋值就能达到下⾯这段代码的效果。
利用Delphi编写Windows 控制面板组件及实例张建军(中国人民解放军合肥炮兵学院研究生系97级)韩莹(中保财险安徽省铜陵市分公司计财部)关键词:在windows95/Nt/98操作系统中,控制面板(controlpanel)提供了定制windows的操作方法,通过它可以完成设置打印机、显示、网络、添加新硬件等功能。
通常控制面板包含20多个组件(*.cpL),分别负责系统某一方面的设置。
鼠标双击任一组件图标,控制面板调用相应程序,弹出对话框,允许设置系统参数。
确认修改后系统参数保存在windows注册表或某一配置文件(*.INI)中。
一、控制面板组件基础知识控制面板是一个windows应用程序c:\wINDowS\coNtRoL.ExE,其配置文件是c:\wINDowS\coNtRoL.INI.控制面板组件是一些动态链接库,其扩展名不是DLL,而是cpL.通常,控制面板组件保存在c:\wINDowS\SyStEm\目录下。
在coNtRoL.INI中有一个[mmcpL]节,该节可指定由coNtRoL.ExE调用的动态链接库,其格式一般为:…[mmcpL]uniqueName=D:\pRoJEct1.DLL(这里假设pRoJEct1为用户编写的控制面板组板文件名,其访问路径可由读者自行确定)…采用此方法,pRoJEct1.DLL不必存放在c:\wINDowS\SyStEm\目录下,扩展名不必改为cpL.coNtRoL.ExE运行后按以下顺序调用这些动态链接库:在c:\wINDowS\SyStEm\目录下调用mAIN.INI.已加载并输出cplApplet()函数的可安装驱动程序。
在coNtRoL.INI[mmcpL]节中指定的DLL.在c:\wINDowS\SyStEm\目录下调用cpL.因此,编写控制面板组件近似于编写普通DLL.通常一个cpL支持控制面板中的一个组件(即一个图标),也可支持多个组件。
DELPHI基础教程:Delphi自定义部件开发(四)[2]⑵ 声明属性当声明一个属性时通常需要声明私有域来保存属性值然后描述读写属性值的方法对于Shape控制将声明一个域保存当前形状然后声明一个属性通过方法调用来读写域值typeTSampleShape=class(TGrahpicControl)privateFShape: TSampleShapeType;procedure SetShape(value: TSampleShapeType)publishedproperty Shape: TSampleShapeType read FShape write SetShape;end;现在只剩下SetShape的实现部分了⑶ 编写实现方法下面是SetShape的实现procedure TSampleShape SetShape(value: TSampleShapeType)beginif FShape<>value thenbeginFShape := value;Invalidate(True) { 强制新形状的重画 }end;end;覆蓋constructor和destructor为了改变缺省属性值和初始化部件拥有的对象需要覆蓋继承的constructor和destructor方法图形控制的缺省大小是相同的因此需要改变Width和Height属性本例中Shape控制的大小的初始设置为边长个象素点⑴ 在部件声明中增加覆蓋constructortypeTSampleShape=class(TGraphicControl)publicconstructor Create(Aowner: TComponent) override;end;⑵ 用新的缺省值重新声明属性Height和widthtypeTSampleShape=class(TGrahicControl)publishedproperty Height default ;property Width default ;end;⑶ 在库单元的实现部分编写新的constructorconstructor TSampleShape Create(Aowner: TComponent)begininherited Create(AOwner)width := ;Height := ;end;公布Pen和Brush在缺省情况下一个Canvas具有一个细的黑笔和实心的白刷为了使用户在使用Shape控制时能改变Canvas的这些性质必须能在设计时提供这些对象然后在画时使用这些对象这样附属的Pen或Brush被称为Owned对象管理Owned对象需要下列三步● 声明对象域● 声明访问属性● 初始化Owned对象⑴ 声明Owned对象域拥有的每一个对象必须有对象域的声明该域在部件存在时总指向Owned对象通常部件在constructor中创建它在destructor中撤消它Owned对象的域总是定义为私有的如果要使用户或其它部件访问该域通常要提供访问属性lishixinzhi/Article/program/Delphi/201311/25110。
第9章创建定制组件对Delphi研发人员来说,创建定制组件的前景非常好。
Delphi是用Object Pascal 实现的,包括了种类繁多的组件,有些是用Object Pascal实现的,另一些是ActiveX组件。
在本章中你可以建立几种组件,其中有一个调试组件可用于跟踪代码并输出到日志文件、捕获代码路径,和对代码中一些具有不变性的条件进行测试。
本章的内容包括:使用组件向导过程、编译并测试组件、将组件和图标关联起来,以及包的安装和管理。
许多类可以转换成组件,在设计时更加易于使用。
组件可能小而简单,也可能大而复杂。
TEdit和TLabel 控件是基本组件的例子。
而较大的商务组件能够对一整类问题提供完整的解决方案;例如Word和Excel 就是大而复杂的组件。
通常在创建大而复杂的组件时,需要创建许多较小的组件和子系统,然后使用这些小的模块来构造所需的解决方案。
本章相当于一块基脚石,它是更为强大的组件和应用程序的基础。
9.1 组件单元概览要成功创建组件,关键是要认识到组件是类。
对于好的类和好的组件来说,二者的规范是基本相同的。
TObject类是所有类的祖先;而TPersistent类是所有组件的祖先,它将组件与其他类区分开来。
TPersistent将持久状态的概念引入到类中。
即:在应用程序的多次运行之间,可以存储并再次获取类的特性。
区分组件与其他类的另一个因素是,组件可以在设计时进行修改;因为组件具有公开权限的接口。
并非所有组件都有精巧的公开接口,但大多数组件都有一些数据和事件特性,可以在设计时对其进行可视化的修改。
所有其他的类都是用代码编程修改,并且直到程序运行时才生效,但组件并非如此。
对组件数据特性的改变可以立即生效。
在使用组件时,首先要知道定义组件的单元如何编写。
unit UEditConvertType;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls,Forms, Dialogs,StdCtrls;typeTEditConvertType = class(TEdit)private{ Private declarations }protected{ Protected declarations }public{ Public declarations }published{ Published declarations }end;procedure Register;implementationprocedure Register;beginRegisterComponents('PKTools', [TEditConvertType]);end;end.从代码列表中可以看到,组件单元与其他单元基本上没有区别。
delphi 代码中设置控件的方法Delphi是一种基于面向对象的编程语言,广泛应用于Windows操作系统中的软件开发中。
通过Delphi代码的编写,开发人员可以有效地设置控件的属性和方法,以实现用户界面的设计和功能的实现。
本文将按照研究方案进行实验或调查,并对采集到的数据进行整理和分析。
在已有研究成果的基础上,将提出一些新的观点和方法,为解决实际问题提供有价值的参考。
1. 引言我们将介绍Delphi语言以及它在软件开发领域的应用。
随后,我们将阐述Delphi中设置控件的方法,包括属性和方法的使用。
2. Delphi中设置控件的方法我们将详细介绍Delphi中如何设置控件的方法,包括以下内容:- 属性设置:通过设置控件属性,开发人员可以更改控件的外观和行为。
我们将介绍如何在Delphi代码中设置控件属性,包括大小、位置、字体、背景色等。
- 事件处理:控件可以响应用户的操作,如点击按钮、输入文本等。
我们将介绍如何使用事件处理程序来实现这些功能。
- 方法调用:通过调用控件的方法,我们可以在代码中执行特定的操作。
我们将介绍如何调用控件的方法,包括显示消息框、打开文件等。
3. 实验设计我们将设计一个实验来验证Delphi中设置控件的方法的有效性。
实验的目的是测试不同控件设置方法的性能和效果。
4. 数据的采集与整理在实验中,我们将采集数据,并将其整理成可用于分析的格式。
我们将说明数据的采集方法和数据的整理过程。
5. 数据分析与结果在这一部分,我们将对采集到的数据进行分析。
我们将使用统计学方法和图表来呈现数据的分析结果,并得出结论。
6. 创新与发展在已有研究成果的基础上,我们将提出一些新的观点和方法。
我们将思考如何改进Delphi中设置控件的方法,以提高编写代码的效率和可读性。
7. 实际问题的解决我们将探讨如何将我们的研究成果应用于实际问题的解决。
我们将分析实际问题,并提供相关的建议和解决方案。
8. 结论在本文的我们将总结我们的研究成果,并给出未来进一步研究的建议。
DELPHI中自定义组件的制作方法介绍
高恩勇;谢德银
【期刊名称】《沧州师范学院学报》
【年(卷),期】2005(021)003
【摘要】组件是Delphi编程的核心,掌握自定义组件的编写方法,对于提高编程人员的编程能力是特别重要的一个方面,本文介绍了在Delphi中自定义组件的一般步骤,在每个步骤中的技巧和注意事项.对Delphi编程人员具有启发和指导作用.【总页数】3页(P59-61)
【作者】高恩勇;谢德银
【作者单位】沧州师范专科学校,河北,沧州,061001;沧州师范专科学校,河北,沧州,061001
【正文语种】中文
【中图分类】TP393
【相关文献】
1.在Delphi中DLL的制作与应用 [J], 魏景东
2.Delphi中COM组件的制作与调用 [J], 魏景东
3.用Delphi制作自定义组件 [J], 张仁平;卜淮原
4.Delphi中调用Excel制作报表的方法 [J], 蒋丽华;雷佳兵
5.Delphi下ADO技术连接Oracle数据库的一种方法介绍 [J], 郭风
因版权原因,仅展示原文概要,查看原文内容请购买。
第2 1章编写自定义组件本章内容:• 组件设计基础• 组件的示例• TddgButtonEdit—一个容器组件• 组件包• 附加包在D e l p h i5中,可以轻松地编写自定义组件,这一点优于其他的编程环境。
正因为可以将自定义组件运用到程序设计中,所以你可以随心所欲地设计应用程序的用户界面。
如果你的工作主要是编写组件,那肯定对本章所提供的内容感到非常满意。
你将学到设计组件的基本概念,以及将组件集成到D e l p h i开发环境中的方法。
并且,你将了解到设计组件的一些缺陷,以及关于开发高级功能和可扩展组件的一些提示与技巧。
即使你主要从事的是应用程序开发,而不是编写组件,也能从本章学到很多东西。
将自定义组件应用到程序中是很有意思的。
在编写应用程序时,现有的组件往往不能满足特殊要求。
这时,就需要自己设计一个合适的组件,使之满足程序设计时的特殊需要,并且设计的组件应当灵活巧妙,以便在其他应用程序中也能使用。
21.1 组件设计基础下面介绍编写组件所要求的基本技巧,并且通过范例演示如何应用技巧来设计组件。
21.1.1 确定是否需要编写组件其实,有些情况下没有必要编写自定义组件,只是在下列情况下才考虑编写自定义组件:• 希望设计一个可以被其他应用程序共享的组件。
• 希望将应用程序变成逻辑上独立的对象。
• 现有的D e l p h i组件和A c t i v e X组件不能满足某种特殊的需要。
• 你了解到一个特殊组件的市场,想设计一个组件作为商品出售。
• 你想更深入地了解D e l p h i、V C L和Win32 API。
学习创建自定义组件的最好途径就是剖析V C L的源代码。
对组件编写者而言,V C L的源代码是无价资源,在它的注释部分对自定义组件进行了详细介绍。
V C L源代码包括在客户服务器版本和专业版本里。
编写自定义组件看上去有点难,其实并非如此。
编写自定义组件是难是易取决于自己,当然按照这里所介绍的步骤和方法,你自己也可以非常轻松地设计出很有用的组件。
21.1.2 编写组件的一般步骤假设已经确定问题所在,并且要创建一个新组件,下面是创建一个组件时应该注意的几个方面:• 首先,要确定是否需要创建一个独特的新组件。
• 接着,坐下来好好规划一下组件的工作方式。
• 做好了准备工作,不要急于实际创建组件,得先问问自己:到底需要这个组件干什么?• 把组件从逻辑上分为几个部分。
这样,不仅有利于组件的模块化、简单化,而且能使代码精炼、组织良好。
设计组件时,要考虑到可能会有其他程序员要基于你的组件派生出一个新的组件。
• 设计完一个组件,必须先在一个程序中测试一下该组件,才能将它加到组件面板上。
• 最后,把组件及它的图标加到面板上,这样,就可以在应用程序中使用它。
编写一个组件分为6个步骤:1) 确定一个祖先类。
2) 创建一个组件单元。
3) 在新组件中添加属性、方法和事件。
4) 测试该组件。
5) 在D e l p h i中注册该组件。
6) 为该组件建立帮助文件。
本章只讨论了前面5个步骤,第6个步骤超出了本章的范围。
不过,这并不意味着这个步骤没有其他5个步骤重要。
我们建议借助于一个合适的第三方工具来制作帮助文件。
D e l p h i的在线帮助中提供了这方面的信息。
21.1.3 确定一个祖先类第2 0章“V C L元素和运行期类型信息”讨论了V C L的继承关系,以及在不同级继承关系上类的不同用途,介绍了四种基本组件:标准组件、自定义组件、图像组件和非可视组件。
譬如,如果需要扩展一个现有的Wi n32组件如T M e m o,应当创建一个标准组件。
如果需要创建一个全新的组件,应当创建一个自定义组件。
如果如果创建一个图形组件,那么它必须是可视的,并且不占用Wi n32系统太多资源。
如果要创建的组件设计时可以在Object Inspector 里编辑,运行时不可见,就应当创建一个非可视组件。
不同的V C L类代表不同的类型的组件。
你不妨回头复习一下第2 0章,除非已经熟练掌握了这些概念。
表2 1-1给出了V C L中的基类。
表21-1 VCL中的组件基类(祖先类)V C L类描述TO b j e c t直接从TO b j e c t继承下来的类不是组件。
有些以此为基类的对象在设计期不需要使用,如T I n i F i l eT C o m p o n e n t这是非可视组件的起点,它的特点是在设计时能够以流的方式在I D E上存取T G r a p h i c C o n t r o l创建一个不需要窗口句柄、但要在屏幕上显示的组件时,用这个类作为祖先类T W i n C o n t r o l所有需要窗口句柄的组件,都应以该类为基类。
该类提供了Wi n d o w s组件的一般属性和事件T C u s t o m C o n t r o l该类是从T W i n C o n t r o l继承下来的。
它具有C a n v a s属性和P a i n t()方法,能够控制组件的外观。
也用于需要句柄的组件T C u s t o m C l a s s N a m e V C L中有些类的属性是不公开的,它们用来作为组件的祖先类。
可以以它为祖先类创建出自定义组件,每个组件公开自己的属性T C o m p o n e n t N a m e一个现有的组件,譬如T E d i t、T P a n e l或T S c r o l l B o x。
与其创建一个新的组件,不如扩展一个现有的组件。
大部分自定义组件都是这样的你应该深刻理解这些类的现有组件的功能。
通常情况下,你会觉得以现有的组件作为起点,是很合适的。
只有掌握了现有组件的功能,才能有目标地选择现有的组件作为基础。
我们无法告诉你该选择哪个组件,只有完全掌握V C L中的每个组件和类,才能更好地扩展现有的组件。
21.1.4 创建一个组件单元确定了祖先类,就可以创建一个组件单元了。
下面几个部分演示了怎样设计一个新组件。
因为重点是讨论怎样创建一个组件,而不是组件的功能,所以这个组件实际没什么用。
这个组件被称为Tdd g W o r t h le s s 。
它是从T C u s t o m C o n t r o l 继承下来的,于是该组件既具有窗口句柄,又能画自己。
它继承了T C u s t o m C o n t r o l 的属性、方法和事件。
要创建该组件的单元,最容易的方法是使用组件专家( C o m p o n e n t E x p e r t ),如图2 1-1所示。
通过选择Component|New Component 菜单命令来打开组件专家。
在组件专家里,输入组件的祖先类名、组件的类名、组件显示在的面板页和组件的单元名。
单击O K ,D e l p h i 会自动创建组件单元,该单元有组件类型的声明和注册过程。
清单2 1-1列出该单元的代码。
清单21-1 一个范例组件的单元: W o r t h l e s s .p a s你可能发现,T d d g W o r t h l e s s 组件还只是一个空架子。
在后面的章节将逐步给T d d g W o r t h l e s s 加入属性、方法和事件。
21.1.5 添加属性第2 0章介绍了属性的用法和使用属性的好处。
本节介绍怎样在组件里加入属性。
属性的类型第2 0章的表2 0-1列出了各种属性的类型。
我们把各种类型的属性添加到T d d g W o r t h l e s s 组件中,以阐述不同类型属性的区别。
在Object Inspector 中不同类型的属性的编辑方式是不同的。
你不妨可以试验各种类型,看它们是怎样编辑的。
(1) 加入简单类型的属性简单类型的属性是指数字、字符串和字符。
用户在Object Inspector 中可以直接编辑它们,不要求图21-1 组件专家特殊的访问方法。
清单2 1-2列出了T d d g W o r t h l e s s组件的3个属性。
清单21-2 简单类型的属性你应该对声明属性的语法已经很熟悉了,因为在第2 0章已经讨论过了这个问题。
这里,组件的内部数据是在p r i v a t e部分声明的。
而属性是在p u b l i s h e d部分声明的,这就意味着当把组件安装到D e l p h i 的环境中时,就可以在Object Inspector中编辑这些属性。
注意编写组件时,组件内部的数据字段名一般以F打头,而组件和类一般以T打头。
如果遵守这样命名规则,程序代码就比较清晰易懂。
(2) 加入枚举型的属性如果在Object Inspector中编辑枚举型和布尔型的属性,可以反复双击值栏,直到需要的值出现,或者从下拉列表中选择一个值。
例如枚举型属性A l i g n,大部分可视的组件都有这个属性。
要加入一个枚举型属性,必须首先声明一个枚举类型,如下:然后声明一些内部的字段来代表每一个枚举值。
清单2 1-3列出了T d d g W o r t h l e s s组件中的两个枚举类型。
清单21-3 枚举型的属性这里其他类型的属性没有被包括。
如果要安装该组件,枚举型的属性将出现在Object Inspector中,如图2 1-2所示。
(3) 加入集合型的属性要在Object Inspect中编辑集合型的属性,可以把这个属性展开。
这样,集合型的每个元素就好像布尔类型的属性。
如果要给T d d g W o r t h l e s s组件加入一个集合型的属性,首先必须声明一个集合类型:这里首先声明了一个枚举类型T S e t P r o p O p t i o n,列举了集合中的元素。
图21-2 显示枚举型的属性然后,定义了集合T S e t P r o p O p t i o n s 。
现在可以把一个T Se t P r op O pti o n s 类型的属性加到T d d g W o r t h l e s s 组件中:图2 1-3显示了在Object Inspector 中展开这个属性的样子。
(4) 加入对象型的属性属性可以是对象,也可以是另一组件。
例如,T S h a p e 组件的B r u s h 属性和P e n 属性就分别是T B r u s h 对象和T P e n 对象。
如果一个属性是对象,它就可以在Object Inspector 中被展开,这样就可以编辑对象本身的属性。
如果属性是对象,该对象必须是从T P e r s i s t e n t 或其派生类继承下来的,这样对象的公开属性才能够被流操作并显示在Object Inspector 中。
要在T d d g W o r t h l e s s 组件中加入对象型属性,必须首先声明该对象。