奇趣技术网 收藏本站
设为主页
商务合作
首页 新闻中心 行业动态 软件新闻 安全资讯 病毒预警 漏洞发布 操作系统 Dos Win9x Win2000 WinXP Win2003 WinVista Linux Unix
数据库 DB2 Access MSSQL MySQL Oracle Sybase 编程技术 ASP PHP JSP CGI/Perl XML .Net C/C++/C# VB VC Delphi Java 汇编
安全技术 安全教学 工具介绍 漏洞利用 病毒防范 入侵检测 防火墙 安全防范 汉化破解 攻击实例 加密解密 技术论坛
中华网络安全联盟 >> 程序开发 >> Delphi >> 通过实例看VCL组件开发全过程(二)
程序开发
Asp
PHP
JSP
CGI/Perl
XML
.Net
C/C++/C#
Visual Basic
Visual C++
Delphi
Java
汇编语言
  • Delphi实现网页表单数

  • 用Delphi开发Web服务数

  • Delphi中利用钩子实现

  • 一个判断定文件是否为

  • 把Flash文件转换为Exe

  • 用Delphi实现文件下载

  • Delphi中保存图像列表

  • 基于Delphi的接口编程

  • 通过实例看VCL组件开发全过程(二)
    字体:

    中华网络安全联盟    作者:佚名    来源:网络转载    时间:2006-3-22

    (接上文)

    组件的代码由于假设你已经熟悉delphi开发(它和一般开发没什么不同),我们就直接贴出来并加上适当的注释:



    unit Clock;



    interface



    uses

      SysUtils, Classes, Controls, StdCtrls,ExtCtrls;



    type

      TState=(StClock,StRunClock,StBackClock);//定义枚举类表示控件的3种状态:时钟、跑表、倒计时钟



      TClock = class(TCustomLabel)

      private

        fState:TState;

        fTimer:TTimer;//为什么使用这个组件作为我们组件的私有成员就不用说了吧

        RCD:array[1..8] of integer;//跑表中的各个数位。

        fBeginTime:string;//到计时时的开始时钟,之所以没用TTime类型是为了在后面演示属性编辑器

        fWakeTime:string;//闹钟时间,出于和上面同样的理由

        fAllowWake:boolean;//是否开启闹钟功能

        fOnWakeUp:TNotifyEvent;//为了使组件更加完美,我们允许组件用户能够响应闹钟到来时的时件

        fOnTimeUp:TNotifyEvent;//同上能够响应倒计时种完成时的事件,我们将发布这两个事件

        function GetActive:boolean;//控制Timer是否工作以控制3种状态的钟是否工作

        procedure SetActive(Value:boolean);

        procedure SetState(Value:TState);

        procedure SetBeginTime(Value:string);

        procedure SetWakeTime(Value:string);

      protected

        procedure WalkClock(sender:TObject);//作为时钟时走种的事件

        procedure RunClock(sender:TObject); //跑表

        procedure BackClock(sender:TObject);//倒计时

      public

        constructor Create(AOwner:TComponent);override;//完成一些初始化工作

        procedure ReSetRunClock; //跑表和倒计时都需要一个复位方法给组件使用者调用

        procedure ReSetBackClock;

      published

        property State:TState read fState write SetState default StClock;//默认为时钟状态

        property Active:boolean read GetActive write SetActive;//控制3种状态的钟是否工作

        property BeginTime:string read fBeginTime write SetBeginTime;

        property WakeTime:string read fWakeTime write SetWakeTime;

        property AllowWake:boolean read fAllowWake write fAllowWake;

        property OnWakeUp:TNotifyEvent read fOnWakeUp write fOnWakeUp;

        property OnTimeUp:TNotifyEvent read fOnTimeUp write fOnTimeUp;

        //最后我们再发布一些被TCustomLabel所隐藏而我们又需要的属性

        property Align;

        property Alignment;

        property Color;

        property Font;

        property ParentColor;

        property ParentFont;

        property ParentShowHint;

        property PopupMenu;

        property ShowHint;

        property Visible;

        property Transparent;

        property OnClick;

      end;



    procedure Register;



    implementation



    procedure Register;

    begin

      RegisterComponents('ClockAndTime', [TClock]);

    end;



    { TClock }



    constructor TClock.Create(AOwner: TComponent);

    begin

      inherited Create(AOwner);

      //设置默认值

      fTimer:=TTimer.Create(self);

      //将它属于我们的组件,这样便不用编写析构函数,而可以自动在释放本组件时释放Timer

      Active:=false;

      AllowWake:=false;

      State:=StClock;

      BeginTime:='00:00:00';

      WakeTime:='00:00:00';

    end;



    function TClock.GetActive: boolean;

    begin

    result:=fTimer.Enabled;

    end;



    procedure TClock.SetActive(Value: boolean);

    begin

    fTimer.Enabled:=Value;

    end;



    procedure TClock.SetState(Value: TState);

    var

    i:integer;

    begin

    case Value of

      StClock:

       begin

        Active:=false;

        fTimer.Interval:=1000;

        fTimer.OnTimer:=WalkClock;

        Active:=true;

       end;

      StRunClock://由于Time类型不好处理微秒操作,我们只有手工模仿这个操作,代码会稍微烦琐

       begin

        Active:=false;

        for i:=1 to 8 do RCD[i]:=0;

        Caption:=IntToStr(RCD[8])+IntToStr(RCD[7])+':'+IntToStr(RCD[6])+IntToStr(RCD[5])+':'+IntToStr(RCD[4]);

        Caption:=Caption+IntToStr(RCD[3])+':'+IntToStr(RCD[2])+IntToStr(RCD[1]);

        fTimer.Interval:=10;

        //经过测试,这个秒表的效果很好,然而这只是一个技术上的演示,

        //实际上这么频繁(1/100秒)的不断执行RunClock会使CPU的占用一直达到100%

        //这并不是一个好注意。事实上要想在跑表中显示微秒级别并做到合理的占用CPU

        //这需要更加灵活和复杂的编程

        fTimer.OnTimer:=RunClock;

       end;

      StBackClock:

       begin

        Active:=false;

        Caption:=BeginTime;

        fTimer.Interval:=1000;

        fTimer.OnTimer:=BackClock;

       end;

    end;

    fState:=Value;

    end;



    procedure TClock.SetBeginTime(Value: string);

    begin

      try

       StrToTime(Value);

       fBeginTime:=Value;

       if State=StBackClock then

       begin

        Active:=false;

        Caption:=Value;

       end;

      except

       on Exception do

       begin

        fBeginTime:='00:00:00';

        if State=StBackClock then Caption:='00:00:00';

       end;

      end;

    end;



    procedure TClock.SetWakeTime(Value: string);

    begin

    try

       StrToTime(Value);

       fWakeTime:=Value;

      except

       on Exception do

       begin

        fWakeTime:='00:00:00';

       end;

      end;

    end;



    procedure TClock.WalkClock(sender: TObject);

    begin

    Caption:=TimeToStr(Time);

    if AllowWake and (StrToTime(Caption)=StrToTime(WakeTime)) then

    begin

      Beep;//蜂鸣器

      if Assigned(fOnWakeUp) then

       fOnWakeUp(self);

    end;

    end;



    procedure TClock.RunClock(sender: TObject);

    begin

    RCD[1]:=RCD[1]+1;

    if RCD[1]=10 then begin RCD[2]:=RCD[2]+1;RCD[1]:=0; end;

    if RCD[2]=10 then begin RCD[3]:=RCD[3]+1;RCD[2]:=0; end;

    if RCD[3]=10 then begin RCD[4]:=RCD[4]+1;RCD[3]:=0; end;

    if RCD[4]=6 then begin RCD[5]:=RCD[5]+1;RCD[4]:=0; end;

    if RCD[5]=10 then begin RCD[6]:=RCD[6]+1;RCD[5]:=0; end;

    if RCD[6]=6 then begin RCD[7]:=RCD[7]+1;RCD[6]:=0; end;

    if RCD[7]=10 then begin RCD[8]:=RCD[8]+1;RCD[7]:=0; end;

    if RCD[8]=10 then RCD[8]:=0; //我们的跑表最多可计99个小时;

    Caption:=IntToStr(RCD[8])+IntToStr(RCD[7])+':'+IntToStr(RCD[6])+IntToStr(RCD[5])+':'+IntToStr(RCD[4]);

    Caption:=Caption+IntToStr(RCD[3])+':'+IntToStr(RCD[2])+IntToStr(RCD[1]);

    end;



    procedure TClock.BackClock(sender: TObject);//可以在一天之类的时间倒计时

    begin

    if StrToTime(Caption)<>StrToTime('00:00:00') then

      Caption:=TimeToStr(StrToTime(Caption)-0.00001)

    else

    begin

      Active:=false;

      Beep;

      if Assigned(fOnTimeUp) then

       fOnTimeUp(self);

    end;

    end;



    procedure TClock.ReSetBackClock;

    var

    i:integer;

    begin

    if State=StRunClock then

    begin

      Active:=false;

      for i:=1 to 8 do RCD[i]:=0;

      Caption:='00:00:00:00';

    end;

    end;



    procedure TClock.ReSetRunClock;

    begin

    if State=StBackClock then

    begin

      Active:=false;

      Caption:=BeginTime;

    end;

    end;



    end.



    为了测试我们的组件,现在你就可以安装这个组件包并建立一个应用测试它了,点击组件包窗体中的install即可(注意:一但你安装了组件包,当你想对组件修改时,在修改了原代码以后只用点击组件窗体的compile就可以了更新组件了),这时delphi的组件页的最后多出了我们定义的页,其中有了我们的组件!

    然而这个组件到目前为止仍然不够完善,还不能正式发布给用户,在下一篇中我们将解决两个重要的问题:1、给我们的组件添加一个默认的图标。2、将这个组件杂乱的属性归类。 

    字体:
     
    设为主页 收藏本站 联系我们 友情连接 商务合作 网友留言
    Copyright©2006-2008 中华网络安全联盟 All rights reserved.