精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Delphi>>其他>>Delphi的Tips(四)(转载)

主题:Delphi的Tips(四)(转载)
发信人: liudq()
整理人: windfire(2000-12-05 20:06:27), 站内信件
发信人: icefh (冰原)
信  区: RAD
标  题: Delphi的Tips(四)
发信站: '紫金飞鸿' (Fri May  1 11:39:02 1998) , 转信

让按钮连续工作--兼谈Delphi元件开发        (1998.03.11)    唐春晖


    不知大家是否见过一种按钮,当它被按下的时侯,它所执行的功能(如向上或
向下)就
持续执行,当松开时,就停止,其实滚动棒两边的按钮就是这样的。下面我们来
做个按钮
元件,让它也有这样的功能。
    在我们做元件之前,让我们了解一下它的原理,要想实现这个功能,我们可
以做一个
定时器,把触发一次的代码写在定时器的触发代码里面,其实我们要实现的功能
很简单,
就是让一个按钮按下时,EDIT1里面的数字就一直加一,当松开时就停止。先向F
orm1里面
放一个Edit,然后放一个Timer,写下如下代码



procedure TForm1.Timer1Timer(Sender: TObject);
begin
  try
    edit1.text:=inttostr(strtoint(edit1.text)+1);
  except
    edit1.text:='1';
  end;
end;


然后,我们还需要有个Button, 让按钮按下时激活时间触发器,当按钮
松开时关闭时关闭时间触发器就可以了。我们再写下如下代码


procedure TForm1.Button1MouseDown(Sender: TObject; Button: TMouseButto
n;
?Shift: TShiftState; X, Y: Integer);
begin
?timer1.enabled:=true;
end;

procedure TForm1.Button1MouseUp(Sender: TObject; Button: TMouseButton;

?Shift: TShiftState; X, Y: Integer);
begin
?timer1.enabled:=false;
end;


这样,我们想要的功能就做成了,非常简单,是不是?但是,如果要做许多这样
的按钮,
我们势必要重复写这样的代码很多遍,那编程岂不变成打字了,而且还容易出错
,这是我
们所不愿看到的。下面,我就这个功能,把它做成一个可重复利用的元件,这样
,每当我
们想要这个功能时,我们便可以从元件板里面把它放到Form上,只写我们想要做
的代码,
就可以了。

首先要为我们的按钮取一个名字,就叫TTimerButton吧,然后从元件板里选个已
经存在的
元件,从头做元件固然可以,但是会做许多无用功,本来人家Delphi已经实现的
功能,我
们还重复去写它做什么,又浪费时间,又容易出错,其实,OOP编程的根本就是让
大家从
重复的劳动中脱离出来,写程序时只写有用的代码,其余的事情呢,就交给Delp
hi去做,
不然,我们花了这么多精力来学它干什么,不就是为了省点时间吗,否则还不如
拿汇编来
干呢.
书归正转,我们选了个元件,TButton,因为我们要做的本身就是个Button,所以

TButton开始着手是最合适的,你完全可以从其他种类的按钮开始。选定了父元件
后,让
我们来想想要加哪些自己的东西呢,第一个是要加个定时器,但是,定时器是与
Button固
化在一起的,所以我们把它加在私有部分,但是,定时器的时间是要可调的,我
们把它声
明成一个属性。在Delphi里,所有的属性都需要声明并实现它的读写方法,否则
,就无法
存取这个属性,关于属性的声明语法,请参见代码 其中TimerTriger是时间触发
器执行
时的过程

TTimerButton = class (TButton)
private
  FTimer    :TTimer;
  FInterval :Integer;
protected
  procedure TimerTrigger(Sender: TObject);
  function  SetInterval(Value :integer);
  procedure MouseDown(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
  procedure MouseUp(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
published
  property Interval :Integer read FInterval write SetInterval default 
200;
end;



第二,我们需要创建一个事件,以便在实际应用时,将代码写在这个事件
里面执行。其实一个事件也是一个Property, 它的声明语法请参见以下代码


TTimerButton = class (TButton)
private
  FOnPush: TNotifyEvent;
published
  property OnPush: TNotifyEvent read FOnPush write FOnPush;
end;


对于Delphi中的一个类来说,都需要有构造函数和析构函数,我们这个类也不例
外,
下面的代码就是加上构造函数和析构函数的完整声明


TTimerButton = class (TButton)
  private
    FTimer    :TTimer;
    FInterval :Integer;
    FOnPush   :TNotifyEvent;
  protected
    procedure TimerTrigger(Sender: TObject);
    function  SetInterval(Value :integer);
    procedure MouseDown(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
    procedure MouseUp(Sender: TObject; Button: TMouseButton;
              Shift: TShiftState; X, Y: Integer);
  public
    Constructor Create(AOwner:TComponent); override;
    Destructor Destroy; override;
  published
    property Interval :Integer read FInterval write SetInterval defaul
t 200;
    property OnPush   :TNotifyEvent read FOnPush write FOnPush;
  end;

下面,就该写代码了,首先写构造函数与析构函数,当创建这个按钮(类)时,类
里面的
定时器同时也被创建,但处于非激活状态,同时,缺省值也应被置入;当这个按
钮(类)
被消除时,定时器也应被释放。下面的代码就是构造函数与析构函数



Constructor TTimerButton.Create(AOwner: TComponent);
begin
  Inherited Create(AOwner);
  FTimer:=TTimer.Create(self);
  with FTimer do begin
    Ontimer:=TimerTrigger;
    Enabled:=false;
  end;
  FInterval := 200;
  FTimer.Interval := 200;
  OnMouseDown:= MouseDown;
  OnMouseUp  := MouseUp;
end;
Destructor TTimerButton.Destroy; 
begin
  FTimer.free;
  inherited Destroy;
end;



下面,就该写属性的读写方法了,属性的读写方法比较简单,只要把值写入
对应的字段就可以了,下面,就是这部分代码


procedure TTimerButton.SetInterval(Value :integer);
begin
  FInterval:=value;
  FTimer.Interval:=value;
end;



 这样,元件的框架就搭好了,下面要做的工作,就是把我们刚开始的工作
在做一遍,这比较容易,请参看下面的代码,其中TimerTrigger执行的是,判
断是否写了事件代码,如果写了就执行。 


procedure TTimerButton.TimerTrigger(Sender: TObject);
begin
?if assigned(FOnPush) then
牋牋 FOnPush(self);
end;
procedure TTimerButton.MouseDown(Sender: TObject; Button: TMouseButton
;
?Shift: TShiftState; X, Y: Integer);
begin
?FTimer.enabled:=true;
end;
procedure TTimerButton.MouseUp(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);
begin
?FTimer.enabled:=False;
end;

最后,是元件的注册部分,注册表示将这个元件加到元件表的位置,调用
一个RegisterComponent函数即可,代码如下:


procedure Register;
begin
  RegisterComponents('Tang', [TRotatePicture]);
end;


然后在加上文件的头,我们这个元件就做成了,使用Delphi的增加元件功能
将元件加入元件板,新开始一个Form测试,完全实现了我们想要的功能,
成功地将比较繁琐的代码,采用元件的形式了封装起来。 


这一次,我们成功地运用ObjectPascal语言实现了代码的封装,把比较繁琐
的代码做到了元件里面,如此看来,用Delphi开发元件其实也不是很困难的
事情,但愿我的这一篇文章能给大家起个抛砖引玉的作用,祝愿大家写出更
加出色的元件来


---------------
  评语:但是由于Windows限制每个窗体TIMER的投递个数,这样作的话Button一多

  就可能让你的程序不工作,这个Tip简述了制作构件的方法,但这样做成的构件

  不安全!

--

                          /\           
  我在冰雪原中         // /\  \\       
       跋涉         / / /  |  \ \ \    
     远方的路啊    /^^^^--冰原--^^^^\  
      在哪里?    /__________________\ 

※ 修改:·icefh 於 May  1 11:51:22 修改本文·[FROM: 202.119.236.104]
※ 来源:·紫金飞鸿 bbs.njupt.edu.cn·[FROM: 202.119.236.104]


----------------------------------------------------------------------
----------

[返回首页] [分类讨论区] [全部讨论区]

--
※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.96.167.200]

[关闭][返回]