基于Delphi的组件设计之概念
2008-02-23 07:18:51来源:互联网 阅读 ()
一、组件的简要层次结构
一般情况下,VCL的组件可以从Tcomponent为开始。其最明显的特征就是它的属性可以在设计时通过对象察看器来操纵,另外,他还能拥有其他组件。
从Tcomponent下,分出非可视组件和可视组件。
非可视组件如TOPenDialog,TTimer,TTable等,这些组件因为继承自Tomponent,所以也就继承了在设计时可以被操纵的特性。
可视化组件始自TControl,是它引入了可视化属性和方法,使继承自它的类都有了这些可视化特性。
TControl又分出两类组件类型:从TWinControl(窗口控件)自下的控件,和从TGraphicControl(图形控件)自下的控件。继承自TWinControl的控件将Windows控件进行封装,所以拥有windows控件的很多特性,比如可以得到焦点,有唯一的句柄,用户可以通过发送消息与这些控件进行交互等。而继承自TGraphicControl的控件,也是可见的,但没有句柄,可以称之为图形控件,比如TLabel,TBevel,都是Delphi画出来的,并不占用系统资源。
二、属性
先看一个简单的属性定义:
TsomeObj=class
Private
FCount:integer;
Protected
Procedure SetCount(value:Integer);
published
Property count:integer read FCount write SetCount default 0;//属性定义
End;
该属性从私有成员FCount读出值,而靠SetCount方法设置值到私有成员FCount。
属性的优势在于可以很直观进行读写,而又不同于私有成员。因为属性可以通过写访问方法来保护私有成员:
Procedure TsomeBoj.SetCount(value:Integer);
Begin
If FCount<>value then
FCount:=value;
End;
其中属性定义中的Default 0并不是默认值(即对象察看器显示的值),默认值要在组件类的构造函数中设定。而Default有这样的作用,决定DFM文件中是否要保存该属性的值,比如上面为Default 0,即当该属性值为0时,则该属性不会被保存到DFM中,如果该属性值不为0,则该属性会被保存到DFM中。另外属性定义还有一个关键字为
NoDefault,设置了这个关键字,比如
Property count:integer read FCount write SetCount NoDefault;
则无论它的值是什么,都会被写到DFM文件中。
属性可以有如下几种类型,下面只给出简单介绍,而这些类型的属性,会在组件制作时详细的运用:
简单类型属性:如上面定义的,加一个例子
Property text:string read Ftext write SetText;
枚举类型属性:
TEnumtype=(Enum1,Enum2,Enum3);
FEnumtype:TEnumtype;
Property Enumtype:TEnumtype read FEnumtype write FEnumtype;
在对象察看器中看来就是下拉列框选择值。
集合类型属性:
Tset=(set1,set2,set3);
Tsets=set of Tset;
Fsets:Tsets;
Property sets:Tsets read Fsets write Fsets;
在对象察看器中看来,就是列出几个选项分别设置真假。比如TForm的BorderIcons属性即是。
对象类型属性:一个属性是一个对象,而这个对象必须派生自Tpersistent或者他之下的类,才能在对象察看器中可以展开它,并设置它里面的属性。
数组类型属性:数组属性如果要在对象察看器中看见,需要有自己的属性编辑器(如果不想在对象察看器看当然就不用啦),是比较高级的组件,在后来的组件制作再来介绍,会更直观一些。这里只给出它的定义形式:
property Selected[Index: Integer]: Boolean read GetSelected write SetSelected;
三、事件
事件其实是一种特殊的属性,他是指针类型,指向一个事件方法类型。当有特定的事件发生时,它就会关联到一段执行代码。
下面以一个例子来讲解事件是怎么发生的。
我们先定义一个鼠标点下事件的鼠标事件类型,它其实就是方法指针:
type TMouseEvent = procedure (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object;
又定义一个私有成员:鼠标事件类型的,即一个方法指针类型
FonMouseDown:TMouseEvent
最后定义一个属性:类要通过这个属性将外部的事件处理函数和FonMouseDown关联在一起:
onMouseDown:TMouseEvent read FonMouseDown write FonMouseDown;
当有鼠标左键点击的,系统会向窗口会发送WM_LBUTTONDOWN;消息
Delphi可以截获这个消息,如下定义消息函数:
procedure WMLButtonDown(var Message: TWMLButtonDown);
message WM_LBUTTONDOWN;
在这个消息处理函数中调DOMouseDown,DoMouseDown又调 用了MouseDown
在这个函数里面才到了最重要的部分
该函数是这样的:
procedure TControl.MouseDown(Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
begin
if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);
end;
而我们先来看看用户外部是怎么操作的,
他自己定义一个SomeobjMouseDown; 是一个事件处理函数,必须和TMouseEvent的形式一样:
Procedure SomeobjMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
然后他这样赋值:
someobj.onMouseDown:=SomeobjMouseDown;
当赋值以后,类内部其实是通过onMouseDown属性,将SomeobjMouseDown;与FonMouseDwon关联在一起,也就是说,MouseDown方法中调用了FOnMouseDown(Self, Button, Shift, X, Y);其实就等于调用了Procedure SomeobjMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash