Delphi自定义控件设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
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;//单元名称
Interface
uses //该控件需要调用的单元
SysUtils,Classes,Controls,StdCtrls;type
TNumEdit =class (TEdit)//控件类,继承自TEdit private //私有成员{Private declarations }protected //保护成员
{Protected declarations }public //公有成员
{Public declarations }published //发布成员
{Published declarations }end;
procedure Register;//过程声明implementation
//下面函数功能是将控件TNumEdit 的图标显示在Samples //面板上
procedure Register;begin
Register Components ('Samples',[TNumEdit]);end;end.
到目前为止,控件TNumEdit 已经具备了Tedit 编辑框的所有功能,下面就可以在这个基础上设计需求的功能了。
Abstract:this paper gives a systematic and detailed introduction of how to design custom control in Delphi though an exam -
ple program 。
The code of this custom control is not technically difficult 。
it ’s intended to illustrate how to design user control in Delphi ,including how it ’s created by appwizard 、code design 、icon design and the issue of the control 。
Key words:control ;custom control ;Delphi
control
图1
本文收稿日期:2009-2-12
Design Custom Control in Delphi
DENG Qingchuang,ZHANG Dan,JI Xina,LI Guojie
(Intermediate Test DPT.XJ Electric Co.,Ltd.Xuchang City Henan Province,Xuchang 461000)
23--
2设计控件功能
(1)只允许输入数字。
(2)可以设置输入范围,即可以设置输入数字的最小、最大值。
(3)可以设置输入数字的小数点位数。
基于上面需求,控件需要做如下几个方面处理:
(1)继承控件接收的按键事件,如果按的不是数字键直接返回。
(2)增加控件可以接收的最大值Max、最小值属性Min。
(3)增加控件小数点设置的属性dotnum。
(4)响应控件焦点离开消息(cm_exit),在这里处理控件中录入的内容,使其大于Min、小于Max且小数点位数等于dotnum。
下面结合该控件代码,通过代码的注释详细地讲解处理过程。
unit NumEdit;//单元名称
interface
uses//该控件需要调用的单元
SysUtils,Classes,Controls,StdCtrls;
type
TNumEdit=class(TEdit)//控件类,继承自TEdit
private//私有变量声明
FMin,FMax:Extended;
//编辑框允许输入的最大最小值。
Fdotnum:Cardinal;//小数点后位数个数
procedure CMExit(var Message:TCMExit);message cm_exit;//响应焦点离开控件的消息
protected//保护
procedure KeyPress(var Key:Char);override;
//重载按键事件
procedure SetMin(value:Extended);
procedure SetMax(value:Extended);
procedure setdotnum(value:Cardinal);
public//公有
constructor Create(AOwner:TComponent);override;
//重载构造函数
function formatstr(s:string):String;//规整字符串
procedure delaexit;//处理使控件中的内容
published
//发布三个属性,分别表示最小值,最大值和小数点数property Min:Extended read FMin write SetMin;//;
property Max:Extended read FMax write SetMax;//;
property dotnum:Cardinal read Fdotnum write setdotnum;//;
end;
procedure Register;//注册过程声明
implementation
/*函数描述:规整字符串,使其小数位数为:fdotnum。
参数s:要处理的数值的字符串形式。
返回值:字符串形式的数值,小数位数为fdotnum。
*/
function TNumEdit.formatstr(s:string):string;
var
i,j:integer;
len:cardinal;begin
i:=pos('.',s);//在s中定位小数点
if i<>0then//如果存在小数点
begin
if i=1then//如果小数点在第一位,则在前面加0
s:='0'+s;
len:=length(s)-pos('.',s);//获取小数点后的位数
if Fdotnum=0then
//如果小数点个数设置为0,则取小数点前的部分
s:=copy(s,1,length(s)-len-1)
else if len<Fdotnum then
//追加0使s满足小数点后有fdotnum位数
begin
for j:=0to Fdotnum-len-1do
s:=s+'0';
end
else
//小数点后位数过多,舍去多余部分,不考虑四舍五入
begin
s:=copy(s,1,length(s)-(len-Fdotnum));
end;
end
else//不存在小数点,加上小数点,再加n个0
begin
s:=s+'.';
if Fdotnum=0then
else
for j:=0to Fdotnum-1do
s:=s+'0';
end;
result:=s;
end;
/*过程描述:在自定义控件光标离开或者按回车键的时候处理,使控件里面的内容(text)符合数值范围和小数点位数设置的要求*/
procedure TNumEdit.delaexit();
var
curvalue:Extended;
stemp,stemp1:string;//存放符号和值的字符串形式begin
if trim(text)=''then text:='0';
//如果为空,默认填写0
if copy(text,1,1)='-'then//如果为负数
begin
stemp1:='-';
stemp:=copy(text,2,length(text)-1);
end
else//如果不是负数
begin
stemp1:='';
stemp:=text;
end;
try
curvalue:=StrToFloat(stemp);//转换为数字
except
//转换失败,默认填写0并格式或为设定的小数位数。
24 --
showmessage('不是有效的数字!请确认');
text:=formatstr(‘0');
self.SetFocus;
end;
//下面对最大值处理,分为大于0,等于0和小于0
//三种情况
if FMax>0then//设置的最大值大于0的处理
begin
if(stemp1='')and(curvalue>FMax)then
//为正且大于最大
curvalue:=FMax
end
else if FMax=0then//等于0的处理
begin
if(stemp1='')then
curvalue:=FMax;
end
else if FMax<0then//小于0多处理
begin
if(stemp1='')then
curvalue:=FMax
else if curvalue>abs(FMax)then
curvalue:=abs(FMax);
end;
//下面对最小值处理,分为大于0,等于0和小于0
//三种情况
if FMin>0then//最小值大于0
begin
if((stemp1='')and(curvalue<FMin))then
//支持负数
curvalue:=FMin
else if stemp1='-'then
curvalue:=FMin;
end
else if FMin=0then//最小值等于0
begin
if stemp1='-'then
curvalue:=FMin;
end
else if FMin<0then//最小值小于0
begin
if((stemp1='-')and(curvalue>abs(FMin)))then
curvalue:=abs(FMin);
end;
//下面对小数位数进行处理
if curvalue=0then
text:=formatstr(floattostr(curvalue))
else
text:=stemp1+formatstr(floattostr(curvalue)); end;
/*函数描述:重载构造函数,设置自定义控件三个新增属性的默认值*/
constructor TNumEdit.Create(AOwner:TComponent); begin
inherited Create(AOwner);
FMin:=0;//最小值默认为0
FMax:=255;//最大值默认为255
Fdotnum:=2;//小数点个数默认为2个
Text:=formatstr('0');
//text继承自Tedit,设置默认显示为0.00
end;
/*过程描述:响应焦点离开控件的消息:cm_exit。
在焦点离开时调用过程delaexit*/()处理控件内容}
procedure TNumEdit.CMExit(var Message:TCMExit);
begin
inherited;//继承父类Tedit的响应
delaexit();//处理控件内容
end;
//设置最小值
procedure TNumEdit.SetMin(value:Extended);
begin
FMin:=value;
if FMax<FMin then
FMax:=FMin;
end;
//设置最大值
procedure TNumEdit.SetMax(value:Extended);
begin
FMax:=value;
if FMin>FMax then
FMin:=FMax;
end;
//设置小数点位数
procedure TNumEdit.setdotnum(value:Cardinal);
begin
Fdotnum:=value;
Text:=formatstr('0');
end;
/*函数描述:重载按键响应,只响应输入数字和回车*/
procedure TNumEdit.KeyPress(var Key:Char);//override;
begin
inherited KeyPress(Key);//继承父类
if key in[#13]then//如果按回车键,处理控件内容
delaexit;
If not(key in[#45,#46,#48..#57,#8])then
//如果非数字键,不响应
begin
key:=#0;
//该语句使你按键时候,控件不予处理、不显示
end;
end;
/*注册控件使TNumEdit显示在Delphi控件面板的Sam-ples面板}*/
procedure Register;
begin
RegisterComponents('Samples',[TNumEdit]);
end;
end;
上面的编码设计使该控件已经满足了需求中提出的功能要求。
25
--
3
设计控件图标
Delphi 控件要使用一个图标显示在Delphi 的控件面板上供开发者使用(由上面设计可知,该控件要显示在Delphi 控件面板的samples 面板上),控件的图标有如下要求(注意图标文件名和图标名称的区别,下面有讲述):
(
1)图标文件名称为dcr (后缀名为dcr )格式,该类文件可认为是图标的容器,其中可以包含多个图标。
(2)图标文件名要与控件单元的文件名一致,如该控件的图标文件名应该为NumEdit.dcr 。
(3)图标名称要与控件类名称一致。
如本控件的图标名称应该为TNumEdit 。
(4)图标文件要与控件单元文件位于同一目录下,这样发布控件时候才能关联到一块。
下面通过用Delphi 自带的工具image editor 设计本控件的图标来介绍控件图标的设计,步骤如下:
(1)通过Delphi 的菜单“tools-image editor ”打开图标编辑工具。
(2)通过file-new-component resource file (.dcr)建立一个图标文件。
把它保存在NumEdit.pas 相同目录下,名称为:NumEdit.dcr 。
此时image-editor 如图2所示。
(3)在图2中,鼠标右键点“Contents ”,然后在弹出的菜单中选择“new-Bitmap ”打开“Bitmap Properties ”框,设置属性后点“OK ”即可创建一个默认名称为“bitmap1”的位图,把其名称修改为“TNumEdit ”,并双击打开,然后通过画笔等工具设计该位图,示意如图3所示。
设计位图根据自己的喜好,这里做简单的设计,设计好后保存即可。
至此,该控件对应的图标已经设计好。
4安装发布控件
目前已经完成了控件的设计,该控件包含两个文件,代
码文件NumEdit.pas 和图标文件NumEdit.dcr 。
下面介绍如何把该控件安装到Delphi 的控件面板上供开发者使用,步骤如下:
(1)把这两个文件拷贝到指定目录下,对于自定义控件,作为一种好的开发习惯,一般在Delphi 安装目录下建立custom 目录并把自定义控件拷贝过去。
这里也建立custom\numedit 目录,然后把该控件的文件拷贝到该目录下,如下:
C:\Program Files\Borland\Delphi7\custom\numedit\(2)在Delphi 库中增加该控件的路径。
通过菜单:“tools-environment-options ”打开“environment-options ”对话框,选择“library ”属性页,然后单击“library path ”后的选项按钮打开“Directories ”对话框,在该对话框中手工录入或者通过选项按钮把控件路径填写进去,如图4所示。
点击“Add ”按钮,点击“OK ”,回到“environment-op -
tions ”对话框,再点击“OK ”完成库文件路径添加。
(3)控件安装。
通过前两步的处理,就可以安装控件了,通过菜单“Component-Install Component ”打开控件安装对话框,点击“into existing package ”属性页中的“unit file name ”后的“Browse ”按钮,选中要安装的控件文件NumEdit.pas ,然后点“OK ”按钮即可。
系统提示是否编译,选择编译后便可以把该控件安装到Delphi 的控件面板,如图5所示。
至此已经完成了一个控件从最开始的需求分析到最终发布使用的全部过程。
设计程序的时候,把上面的控件(红色的,在控件图标设计中设计的那个图标)拖到Delphi 的窗体上,通过设置控件的属性就可以使用该控件了。
作者简介
邓清闯,男(1980-),测试工程师,主要研究电力系统测试
工具的开发。
图
2
图
3
图
4
图5
26--。