• 首页
  • 小学语文
  • 中学语文
  • 中学英语
  • 免费论文
  • 教学随笔
  • 学生作文
  • 综合考试
  • 试题教案
  • 育儿话题
  • 教学资源
  • 编程技术
  • 博客
  • 组件制作之二(一个简单组件的制作过程)

    日期:2003-03-28  地址:  作者:

    接下来要动手来做一个组件了,我想了一个计数器组件,功能方面是比较简单的,但这不是本章的重点,这一章的重点是说明一个组件的制作全过程。在其中可以学到很多组件制作的技巧,当然这些也是我从书上学得的。好了,开始制作吧:

     

    这是一个可以计数的组件,为了简单,我以秒为单位,当开始时,他就从0开始增加,并显示出来,到3600时,它又回到0,如此循环。当然它也可以停止,暂停,继续。另外,他还有一个时间事件,即可以设定每隔多少时间来触发这个事件,这倒是一个好的功能,我们可以设半个小时触发事件,在事件处理函数中来一个声音,然后睡个觉,半个小时后,就由这个声音来提醒你起床了。

     

    我们一开始不要新建组件单元,而是把它当成一个工程中的一个类来应用,这样更易于调试,于是我们新建一个工程,又新建一个空白单元用于放置这个类

     

    一,确定父类:

     

    接下来给这个类起名叫TTimeCount,那么它的父类应该是什么呢,它要能显示出来,得有一个容量来让他显示,TPanel是个不错的选择,我看了一下源码,发觉TPanel什么也没有做,只是把它的父类TCustomPanel的属性显化出来(这个等一下讲),TCustomPanel把好多的属性声明为Protected,为他的子类提供了选择,他的子类如果要使这些属性能在对象察看器中看到,可以在Published重新声明一下,如果不想,则不用去理会他。而我们的计数器组件正好不用那么多属性,正好合适。于是我决定用TCusomPanel为父类

    类建立如下:

    TTimeCount=class(TCustomPanel)

      private

      protected

      public

      published

    end;

     

    二,确定成员,方法和属性和事件

     

    FCount; 只读私有成员,保存计数值

    FActive:Boolean; /确定是否发生类的时间间隔事件

    FInterval:TInterval; 这个可以设置时间事件触发间隔,本来用整型值会好一些,但会了学习起见,这里用了一个枚举形的,在Type中声明如下:

    TInterval=(TenM,TwentyM,ThirtyM,FortyM,FiftyM,SixtyM);

    分别表示十分钟到六十分钟。

    TimeLenTimeNum:integer;这两个用在类的时间事件发生的确定上,与外界隔绝。

    FTimeOut:TNotifyEvent;时间间隔事件的方法指针,通过调度方法实现他与外部的处理函数关联。

     

    我们要它能以秒为单位来计数,则要涉及到时间的应用,所以就有了这个最重要的成员:

    FTimer:TTimer;

    这个成员对象要在类构造函数中实例化它,并赋与他的属性值,还要在析构函数在释放它。

    如下:

     //构造函数,继承父类的构造函数,并初始化类中的成员。

    constructor TTimeCount.Create(AOwner:TComponent);

    //创建时间控件并设置相关的参数

      procedure CreateTimer;

      begin

          FTimer:=TTimer.Create(self);

          FTimer.Enabled:=False;

          FTimer.Interval:=1000;

          FTimer.OnTimer:=FTimerTimer;

      end;

    begin

      inherited Create(AOwner);

      CreateTimer;

    end;

    //析构函数,先释放时间控件,再继承父类的析构函数

    destructor TTimeCount.Destroy;

    begin

      FTimer.Free;

      inherited Destroy;

    end;

    构造函数中还要设置该组件的外观和默认值,这里把它删去,到源代码再贴出来。

    其中

    FTimerTimer;是很重要的函数,在该类中有声明:

    procedure FTimerTimer(Sender:Tobject);//时间控件的事件处理函数

    在这个处理函数中,实现了计数值的递增并显示到容器中,此外,还在判断类的时间事件是否有足够条件触发了,如果有则调用DoTimeOut;过程,这个就是事件的调度函数啦:

    //事件调度函数,将外部的事件处理函数和该类的事件方法指针联系起来

    procedure TTimeCount.DoTimeOut;

    begin

      if Assigned(FTimeOut) then

         FTimeOut(Self);

    end;

     

    而属性则是根据私有成员来设定了:

    public

    property Count:Integer read FCount default 0; //计数值的只读属性,这个属性不能声明在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

      SysUtils,Classes,Graphics,Controls,ExtCtrls;

     

    type

    //用于设置时间事件发生的间隔

      TInterval=(TenM,TwentyM,ThirtyM,FortyM,FiftyM,SixtyM);

     

      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 TTimeCount.Create(AOwner:TComponent);

    //创建时间控件并设置相关的参数

      procedure CreateTimer;

      begin

          FTimer:=TTimer.Create(self);

          FTimer.Enabled:=False;

          FTimer.Interval:=1000;

          FTimer.OnTimer:=FTimerTimer;

      end;

    //以下是设置外观的

      procedure setView;

      begin

        Width:=100;

        Height:=50;

        Color:=$000000;

        Font.Color:=$FFFFFF;

        Font.Size:=14;

        Font.Style:=[fsBold,fsUnderline];;

        BevelOuter := bvLowered      ;

        Caption:='0';

      end;

    begin

      inherited Create(AOwner);

      FCount:=0;

      FInterval:=TenM;

      FActive:=False;

      TimeLen:=600;//十分钟,六百秒

      TimeNum:=0;

      CreateTimer;

      setView;

    end;

    //析构函数,先释放时间控件,再继承父类的析构函数

    destructor TTimeCount.Destroy;

    begin

      FTimer.Free;

      inherited Destroy;

    end;

    //设置时间事件发生间隔,财时要赋相应的间隔秒数

    procedure TTimeCount.SetInterval(I:TInterval);

    begin

      if FInterval<>I then

      begin

        FInterval:=I;

        case FInterval of

        TenM: TimeLen:=600;

        TwentyM:TimeLen:=1200;

        ThirtyM: TimeLen:=1800;

        FortyM: TimeLen:=2400;

        FiftyM:TimeLen:=3000;

        SixtyM:TimeLen:=3600;

        end;

      end;

    end;

     

    procedure TTimeCount.SetActive(A:boolean);

    begin

      if FActive<>A then

      begin

          FActive:=A;

          TimeNum:=0;

      end;

    end;

     

    procedure TTimeCount.pause;

    begin

     if FTimer.Enabled then

      FTimer.Enabled:=False;

    end;

     

    procedure TTimeCount.Resume;

    begin

      if not FTimer.Enabled then

        FTimer.Enabled:=True;

    end;

     

    procedure TTimeCount.stop;

    begin

      FTimer.Enabled:=False;

      FCount:=0;

      TimeNum:=0;

      caption:='0'

    end;

     

    procedure TTimeCount.start;

    begin

      if (not FTimer.Enabled)and(TimeNum=0) then

         FTimer.Enabled:=True;

    end;

     

    //最重要的时间函数,用于调用该类的事件触发高度函数。

    //以及在容器中显示计数值

    procedure TTimeCount.FTimerTimer(Sender:TObject);

    begin

      inc(FCount);

      if (FCount mod 3600)=0 then FCount:=0;

      Caption:=InttoStr(FCount);//这个就是显示计数值

      inc(TimeNum);

      if (TimeNum=TimeLen)and(FActive) then

      begin

           DoTimeOut;

           TimeNum:=0;

      end;

    end;

    //事件调度函数,将外部的事件处理函数和该类的事件方法指针联系起来

    procedure TTimeCount.DoTimeOut;

    begin

      if Assigned(FTimeOut) then

         FTimeOut(Self);

    end;

     

    end.

     

    五,组件注册安装与删除。

     

    组件类编写完毕,接着就要测试了,这个从略,可以在刚才的工程中动态创建它,设置相应属性,指定时间事件,看看是否正确。上面是经过测试的。

    到确定正确后,就要来看看装组件的步骤了:

     

    首先,我们要把组件单元放在一个指定的文件夹中,以便以后管理,和IDE统一指定路径。

    我在Delphi目录下新建了MyCom文件夹,用来存放组件单元

    然后选:

    Component—>New Component;

    启动Component Wizard

    Ancestor type(父类):中填TCustomPanel

    Class Name(你的组件类名)中填:TimeCount

    Palette Page,默认为Samples,我就用这个吧,当然也可以自己创建一个。

    Unit File Name(组件类所在的单元名),就写TimeCount吧。

    Search Path(搜索路径),必须把上面所建的文件夹路径包含进去,编译时才能能过。

                          点击旁边的”…”按钮,出现一个对话框,里面的编辑框旁边又有一个”…“按钮,点击它出现浏览文件夹框,在其中选中上面建的文件夹的路径,点确定,再点OK,回去New Component;

                          这时再点下面的OK就行啦,出现代码如下:

    unit TimeCount;

     

    interface

     

    uses

     messages, SysUtils,Classes,Graphics,Controls,ExtCtrls;

     

    type

      TTimeCount=class(TCustomPanel)

      private

      published

      public

      published  

      end;

     

    procedure Register;

     

    implementation

     

    procedure Register;

    对 组件制作之二(一个简单组件的制作过程) 文章的评论    [查看网友评论]

    验证码:
    匿名发表: