======================================================
注:本文源代码点此下载
======================================================
上一篇,介绍了组件开发的一般概述,以及组件类层次结构的各个类的大致信息!现在就开始通过实例进行来简单的讲述一下一般组件的开发过程!我这里先采用最基本的方式来创建一个组件!也就是使用delphi自己的组件开发向导来建立一个新的组件。在这里,我以扩充tedit为例进行讲解。
那么首先,要介绍的就是如何使用delphi的组件开发向导了!这个向导在delphi ide的component菜单下的newcomponent打开就是向导了,可以参照如下:
从图上可以看到,我通过向导,我先选择了从组件tedit往下继承,于是delphi自动生成了新组件类tedit1,然后我选择了将本组件注册到standard这个控件面板上去,然后保存了单元文件到c:\test这个目录下!然后点击下一步完成,delphi自动帮我们生成了一个edit1.pas的单元文件。这样一个新的基本控件就完成了!此时,就可以在我们的工程中使用tedit1.create(nil)这样的语句来创建刚刚建立的新edit组件了,只是现在的这个控件与tedit没有任何功能上的区别,唯一的却别就是仅仅变了变组件的类名称而已!是一个没有任何意义的组件!下面,我要开始讲解的便是扩充一下这个edit,使得这个控件具备一些delphi的tedit所不具备的功能!
我想一想,扩充几个啥功能呢!貌似delphi自己的tedit没有alignment这个属性哈,那么第一步,就来先为我们刚刚创建的那个新组件增加一个alignment属性,可以让用户来设置edit中文字的对齐方式吧!怎么能设置edit编辑框的文字的对齐方式呢!这个网上有很多资料的,我们查查msdn,可以发现edit有几种样式es_left, es_right, es_center分别用来设置文字的左对齐,右对齐和居中对齐!一般情况下,默认的是左对齐,如果要修改edit的对齐方式为其他的对齐方式,那么,我们就需要设置编辑框的样式为新的样式,windows有一个api函数,专门用于设置其控件的样式的函数为setwindowlong,如果要在运行时直接对delphi的edit设置对齐方式,就可以用该函数来实现!比如
setwindowlong(edit1.handle,gwl_style,getwindowlong(edit1.handle,gwl_style) or es_right);
这一句就能让edit1的对齐方式变成右对齐,于是,我们可以想象,我们可以在组件内部开放一个属性,用户一设置,就能调用这个代码来执行!所以,我先在我们刚刚生成的那个单元类tedit1的published域中添加上一个新的属性
published
{ published declarations }
property alignment: talignment;
然后按住ctrl+shift+c,delphi就会自动帮你把属性设置补全!变为
property alignment: talignment read falignment write setalignment;
此时,有必要来介绍一下delphi的属性property,delphi的属性由property关键字定义,后面跟上一个属性名称,以及属性的数据类型声明,然后跟上属性的读写来源,读写来源采用read和write关键字标记,那么当我们调用属性的数据的时候就会调用属性的读方法,如果向属性中写入值的时候,就会调用属性对应的写方法或者写的对应变量值!
好,我们看一下alignment这个属性的声明,read域指定的是falignment,这就表示当外部调用alignment的时候,实际上就是直接调用的falignment的值了,而当我们外部向alignment属性写入值的时候,那么此时,就是调用的write域所对应的setalignment方法了!我们现在最主要最关键的就是要实现setalignment这个方法。当用户设置了这个属性的时候,就会直接触发改变编辑框的对齐方式!前面已经给出了代码setwindowlong可以实现修改edit的编辑框样式,那么我们这里也就用那个方法来实现一下这个改变对齐方式的属性
这个代码很简单,我就直接给出来算了
代码
procedure tedit1.setalignment(const value: talignment);
var
style: dword;
begin
if falignmentvalue then
begin
falignment := value;
style := getwindowlong(handle,gwl_style);
style := style and (not es_left) and (not es_center) and (not es_right);
case falignment of
taleftjustify: setwindowlong(handle,gwl_style,style or es_left);
tarightjustify: setwindowlong(handle,gwl_style,style or es_right);
tacenter: setwindowlong(handle,gwl_style,style or es_center);
end;
invalidate;
end;
end;
我在里面写的代码比前面给的代码多了一个
style := style and (not es_left) and (not es_center) and (not es_right);这样的东西,可以试着思考一下为什么要这样写!
然后在最后还添加了一个invalidate;可以试着注释掉这个函数,然后试着改变属性,看看会有什么样的效果!为什么会这样?
最后,我再给一个不是用setwindowlong这个api来实现改变这个属性的效果的方法代码,大家可以先参考参考,至于原理若何,后面再做介绍!
那便是改写edit控件的createparams方法,先在protected域中声明
protected
procedure createparams(var params: tcreateparams); override;
之后实现如下
procedure tedit1.createparams(var params: tcreateparams);
const
alignments: array[talignment] of dword = (es_left, es_right, es_center);
begin
inherited createparams(params);
with params do
begin
exstyle := exstyle and not ws_ex_transparent;
style := style and not ws_border or alignments[falignment];
end;
end;
然后setalignment修改为
procedure tedit1.setalignment(const value: talignment);
begin
if falignmentvalue then
begin
falignment := value;
recreatewnd;
end;
end;
注意两者setalignment的实现方式!然后思考一下!
另外,这里,我并没有将这个控件注册到delphi的ide中去!如何注册进去,在以后的指南中,我会说明!
======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/