有人说过“不会开发控件的
Delphi
程序员不是真正的程序员”。
Delphi
正是由于高度的可扩展性和大量的第三方控件的支持才能吸引无数程序员挑剔的目光。即使是由于工作需要使用其他开发工具的开发者也常常怀念和
Delphi
度过的日日夜夜。接触
Delphi
已经一年多了,从当初对着
Delphi
组件面板上上百个控件不知所措,到现在已经可以根据需要开发一些有一定难度的控件,其中走过的路是十分艰辛的,所以特此写下这篇文章,将自己的经验留给后来者,也算是献给“同门师弟”的一份厚礼吧!
需要说明的一点是:在写这篇文章之前我假设读者已经对面向对象的基本知识有一定的了解,所以对于文章中面向对象相关的概念将不再展开讲述。
一、牛刀小试-
TURLLabel
控件
我们从一个能够添加超链接的标签控件开始我们的控件开发之旅吧!
既然是
Label
我们就从
Tlabel
派生这个控件吧
(
其实从
TcustomLabel
派生最好,不过出于简单的目的我们这里先从
Tlabel
派生
)
!
1
、选择“
File
”-
>
“
New
”-
>
“
Component
”
,
将弹出如下的对话框:
在
Ancestor type
中选择
Tlabel
,
ClassName
中填入
TURLLabel(
名字可以任意取,但是要以
T
开头,否则的话会出现注册控件时候的问题
)
。这里
Ancestor type
代表控件的基类,
TURLLabel
代表控件的名称。
2
、超链接的视觉效果是带下划线的文字,所以我们覆盖父类的构造函数,在构造函数里修改控件的字体属性。
constructor TUrlLabel.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
Cursor:=crHandPoint;
Font.Style:= [fsUnderline];
end;
代码解释:
(1)
inherited Create(AOwner);
这句的意思是执行父类的构造函数。我们制作控件的时候,如果覆盖了父类的构造函数,那么在新的构造函数中一定要首先调用父类的构造函数,否则会引起错误。这是很多初学控件开发的人常常遇到的问题。当您把自己开发的控件从面板上拖放到窗体时,如果跳出一个“
Access Violent
”的错误对话框的话,那么十有八九是因为您忘了调用父类的构造函数。
(
2
)
Cursor:=crHandPoint;
Font.Style:= [fsUnderline];
这三句的意思是修改标签的视觉效果。
Cursor:=crHandPoint;
是设定当鼠
标移动到控件上时鼠标的形状为“手型”;
Font.Style:= [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 Click;override;
在实现部分为
Click
方法写如下的代码:
procedure TUrlLabel.Click;
begin
ShellExecute(Application.Handle, nil, PChar(Url), nil, nil,SW_NORMAL);
inherited;
end;
代码解释:
(1)
ShellExecute
的作用是用默认的程序打开第三个参数指定的文件。所以当第三个参数为一个
URL
时,则用浏览器打开这个网址。关于
ShellExecute
其他参数的使用方法可以查阅
MSDN
或其他相关资料。
(2)
Inherited;
的作用是调用父类的
Click
方法来由父类来对鼠标单击事件做其他的处理。
5
、源代码。
下面给出这个控件的全部源代码:
unit UrlLabel;
interface
uses
Windows, Messages, SysUtils, Classes, Controls, StdCtrls,Shellapi,
Graphics, Forms;
type
TUrlLabel = class(TLabel)
private
FUrl:AnsiString;
protected
procedure Click;override;
public
constructor Create(AOwner:TComponent);override;
published
property Url:AnsiString read FUrl write FUrl;
end;
procedure Register;
implementation
constructor TUrlLabel.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
Cursor:=crHandPoint;
Font.Style:=[fsUnderline];
end;
procedure TUrlLabel.Click;
begin
ShellExecute(Application.Handle, nil, PChar(Url), nil, nil,SW_NORMAL);
inherited;
end;
procedure Register;
begin
RegisterComponents('Linco', [TUrlLabel]);//
控件生成向导生成的注册控件用代码
end;
end.
6
、为控件添加图标。
如果没有给自定义的控件定义图标,出现在控件面板上的自定义图标的图标是默认的图标,很没有“个性”,也不容易被用户与其他控件区别开来,所以我们需要给组件指定一个图标。
首先利用
Delphi
的
Image Editor
创建一个
24*24
的位图,并把它保存到一个
DCR
文件中。创建了一个位图后,就需要给位图命名了。位图的名称必须和控件的类名相同,且为大写,而
DCR
文件的名字则必须与控件所在单元的单元名相同。如我们上边定义的控件,位图的名字应该为
TURLLABEL
,
DCR
文件的名字应该是
UrlLabel.dcr
,此
DCR
文件应该与组件的单元文件放在同一个目录下。
打开
Image Editor,
选择
”File”
-
>
“
New
”
-
>
“
Component Resource File(.dcr)
”,如下图:
在“
Contents
”上单击鼠标右键,选择“
New
”-
>
“
BitMap
”:
在
Width,Height
中都填入
24
,点“
OK
”即可。
可以在
Bitmap1
上点右键选择“
Rename
”为位图重命名为
TURLLABEL
,然后双击
TURLLABEL
,就可以像使用“画图”一样为您的控件设计图标了。
7
、注册组件。
点击
Componet
-
>Install Componet
进行自定义组件安装,此时将出现组件安装对话框。
在
Unit FilName
中输入控件单元文件的文件名(包括路径),点击“
OK
”
,
在弹出的
Package Editor
中按下
Install
按钮。如果安装成功系统就会提示安装成功。关闭
Package Editor
时,会提示您是否保存修改,点击
Yes
即可。
安装成功,建立一个测试程序。将
URLLabel
控件放到窗体上,设定
Url
属性为
http://www.sohu.com
运行程序,点击此
Label
,就会弹出浏览器打开
http://www.sohu.com
这个网址。