这是一个可以计数的组件
为了简单
我以秒为单位
当开始时
他就从
开始增加
并显示出来
到
时
它又回到
如此循环
当然它也可以停止
暂停
继续
另外
他还有一个时间事件
即可以设定每隔多少时间来触发这个事件
这倒是一个好的功能
我们可以设半个小时触发事件
在事件处理函数中来一个声音
然后睡个觉
半个小时后
就由这个声音来提醒你起床了
我们一开始不要新建组件单元而是把它当成一个工程中的一个类来应用这样更易于调试于是我们新建一个工程又新建一个空白单元用于放置这个类
一确定父类
接下来给这个类起名叫TTimeCount那么它的父类应该是什么呢它要能显示出来得有一个容量来让他显示TPanel是个不错的选择我看了一下源码发觉TPanel什么也没有做只是把它的父类TCustomPanel的属性显化出来(这个等一下讲)TCustomPanel把好多的属性声明为Protected为他的子类提供了选择他的子类如果要使这些属性能在对象察看器中看到可以在Published重新声明一下如果不想则不用去理会他而我们的计数器组件正好不用那么多属性正好合适于是我决定用TCusomPanel为父类
类建立如下
TTimeCount=class(TCustomPanel)
private
protected
public
published
end;
二确定成员方法和属性和事件
FCount; 只读私有成员保存计数值
FActive:Boolean; /确定是否发生类的时间间隔事件
FInterval:TInterval; 这个可以设置时间事件触发间隔本来用整型值会好一些但会了学习起见这里用了一个枚举形的在Type中声明如下
TInterval=(TenMTwentyMThirtyMFortyMFiftyMSixtyM);
分别表示十分钟到六十分钟
TimeLenTimeNum:integer;这两个用在类的时间事件发生的确定上与外界隔绝
FTimeOut:TNotifyEvent;时间间隔事件的方法指针通过调度方法实现他与外部的处理函数关联
我们要它能以秒为单位来计数则要涉及到时间的应用所以就有了这个最重要的成员
FTimer:TTimer;
这个成员对象要在类构造函数中实例化它并赋与他的属性值还要在析构函数在释放它
如下
//构造函数继承父类的构造函数并初始化类中的成员
constructor TTimeCountCreate(AOwner:TComponent);
//创建时间控件并设置相关的参数
procedure CreateTimer;
begin
FTimer:=TTimerCreate(self);
FTimerEnabled:=False;
FTimerInterval:=;
FTimerOnTimer:=FTimerTimer;
end;
begin
inherited Create(AOwner);
CreateTimer;
end;
//析构函数先释放时间控件再继承父类的析构函数
destructor TTimeCountDestroy;
begin
FTimerFree;
inherited Destroy;
end;
构造函数中还要设置该组件的外观和默认值这里把它删去到源代码再贴出来
其中
FTimerTimer;是很重要的函数在该类中有声明
procedure FTimerTimer(Sender:Tobject);//时间控件的事件处理函数
在这个处理函数中实现了计数值的递增并显示到容器中此外还在判断类的时间事件是否有足够条件触发了如果有则调用DoTimeOut;过程这个就是事件的调度函数啦
//事件调度函数将外部的事件处理函数和该类的事件方法指针联系起来
procedure TTimeCountDoTimeOut;
begin
if Assigned(FTimeOut) then
FTimeOut(Self);
end;
而属性则是根据私有成员来设定了
public
property Count:Integer read FCount default ; //计数值的只读属性这个属性不能声明在Published中因为它是只读的只在程序运行时通过它来得到计数值
published
property Interval:TInterval read FInterval write SetInterval Default TenM;
property Active:boolean read FActive write SetActive default false;
property OnTimeOut:TNotifyEvent read FTimeOut write FTimeOut;
此外还有几个自定义方法即
procedure pause; //暂停计数
procedure Resume;//从暂停的计数开始计数
procedure stop;//停止
procedure start;//开始计数
都比较简单
三父类属性的显化
TCustomPanel及其父类有好多的属性设为Protected使其子类可以有更灵活的选择是否把这些属性显示到对象察看器中如果想则到Published中重新声明这些属性就可以我参考了一下TPanel的源码并按需要选择了其中的一些属性声明到Published中注意哦事件也是属性只要你把它显化出来就可以设置处理事件了
以下是计数组件的源码相信有了上面的讲解应该不会很难了
unit CountUnit;
interface
uses
SysUtilsClassesGraphicsControlsExtCtrls;
type
//用于设置时间事件发生的间隔
TInterval=(TenMTwentyMThirtyMFortyMFiftyMSixtyM);
TTimeCount=class(TCustomPanel)
private
FTimer:TTimer;
FCount:integer; //只读私有成员计数值
FInterval:TInterval; //时间事件发生的间隔
FActive:Boolean; //决定是否发生间隔事件
TimeLen:Integer;//发生事件的时间长度以秒为单位
TimeNum:integer;//计数值和TimeLen一起有用以判断是否事件该发生了
FTimeOut:TNotifyEvent;//事件的方法指针
procedure SetInterval(I:TInterval);
procedure SetActive(A:boolean);
procedure FTimerTimer(Sender:Tobject);//时间控件的事件处理函数
protected
procedure DoTimeOut;dynamic; //调度方法用于关联事件
public
procedure pause; //暂停计数
procedure Resume;//从暂停的计数开始计数
procedure stop;//停止
procedure start;//开始计数
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
property Count:Integer read FCount; //计数值的只读属性
published
property Interval:TInterval read FInterval write SetInterval Default TenM;
property Active:boolean read FActive write SetActive default false;
property OnTimeOut:TNotifyEvent read FTimeOut write FTimeOut;
//显式祖先类的一些属性在对象察看器中
property BevelInner;
property BevelOuter;
property BevelWidth;
property Color;
property Font;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Visible;
property OnClick;
property OnDblClick;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
end;
implementation
//构造函数继承父类的构造函数并初始化类中的成员
constructor TTimeCountCreate(AOwner:TComponent);
//创建时间控件并设置相关的参数
procedure CreateTimer;
begin
FTimer:=TTimerCreate(self);
FTimerEnabled:=False;
FTimerInterval:=;
FTimerOnTimer:=FTimerTimer;
end;
//以下是设置外观的
procedure setView;
begin
Width:=;
Height:=;
Color:=$;
FontColor:=$FFFFFF;
FontSize:=;
FontStyle:=[fsBoldfsUnderline];;
BevelOuter := bvLowered ;
Caption:=;
end;
begin
inherited Create(AOwner);
FCount:=;
FInterval:=TenM;
FActive:=False;
TimeLen:=;//十分钟六百秒
TimeNum:=;
CreateTimer;
setView;
end;
//析构函数先释放时间控件再继承父类的析构函数
destructor TTimeCountDestroy;
begin
FTimerFree;
inherited Destroy;
end;
//设置时间事件发生间隔财时要赋相应的间隔秒数
procedure TTimeCountSetInterval(I:TInterval);
begin
if FInterval<>I then
begin
FInterval:=I;
case FInterval of
TenM: TimeLen:=;
TwentyM:TimeLen:=;
ThirtyM: TimeLen:=;
FortyM: TimeLen:=;
FiftyM:TimeLen:=;
SixtyM:TimeLen:=;
end;
end;
end;
procedure TTimeCountSetActive(A:boolean);
begin
if FActive<>A then
begin
FActive:=A;
TimeNum:=;
end;
end;
procedure TTimeCountpause;
begin
if FTimerEnabled then
FTimerEnabled:=False;
end;
procedure TTimeCountResume;
begin
if not FTimerEnabled then
FTimerEnabled:=True;
end;
procedure TTimeCountstop;
begin
FTimerEnabled:=False;
FCoun