组件制作之二(一个简单组件的制作过程)

马叶涛1

马叶涛1

2016-02-19 12:50

清醒时做事,糊涂时读书,大怒时睡觉,无聊时关注图老师为大家准备的精彩内容。下面为大家推荐组件制作之二(一个简单组件的制作过程),无聊中的都看过来。
接下来要动手来做一个组件了,我想了一个计数器组件,功能方面是比较简单的,但这不是本章的重点,这一章的重点是说明一个组件的制作全过程。在其中可以学到很多组件制作的技巧,当然这些也是我从书上学得的。好了,开始制作吧:
  
   
  
  这是一个可以计数的组件,为了简单,我以秒为单位,当开始时,他就从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);
  
  分别表示十分钟到六十分钟。
  
  TimeLen,TimeNum: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 FIntervalI 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 FActiveA 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;
  
  begin
  
    RegisterComponents('Samples', [TTimeCount]);  //注册控件用的函数,自动帮你生成
  
  end;
  
  end.
  
  这时再把上面的组件类替换掉这个类就行啦(当然上面的注册函数可要保留呀)。然后保存到上面所建的文件夹中。
  
   
  
  接着就要安装组件了,点Component-install Component
  
  对话框中第一项Unit file Name,是组件单元.pas文件的路径名字。其他只要按缺省。
  
             记得第三项的。。delphi7Libdclusr.dpk,这个就是存放组件的包名,等一下删除组件时用到的
  
                     接下来点OK,就可以了,看看Samples是不是有了一个新组件啦。
  
                      
  
   不过面板上的组件图标似乎不好看,应该给他一个新的图标了:
  
   但之前应该把它先从面板删除,File-Open…打开dclusr.dpk.
  
  选中其中的Contains下的TimeCount.pas,点上面的Remove。将其删除
  
  然后再点Compile,重新将包编译一次。就行啦。Samples上的新组件就消失了。
  
   
  
  接下来是做组件图标:
  
  打开Image Eidtor,新建一个DCR文件,在其中建一个24×24的位图,画上你喜欢的图标,将位图的名字起为组件类名一样,而且用大写,即:TTIMECOUNT
  
  将DCR文件起名为组件类所在单元名一样,而且大写,即:TIMECOUNT。
  
  保存文件到单元所在的文件夹中,
  
  最后依上面的方法再装一次,看是不是有一个漂亮的图标啦
  
   
  
   
  
  六,讲完了,大家应该有一个清楚的概念了吧,其中涉及到了好多的技巧。在以后的篇章中将不再讲这些内容了,只把主要精力花在组件实现技术上。因为我们这个组件还是比较简单,没有涉及到多少高级的主题。但没有关系,跟着我慢慢地做下来,你们会了解组件制作的方方面面的。 
展开更多 50%)
分享

猜你喜欢

组件制作之二(一个简单组件的制作过程)

编程语言 网络编程
组件制作之二(一个简单组件的制作过程)

HTML组件(HTML COMPONENTS)之二

Html CSS布局 Div+CSS XHTML
HTML组件(HTML COMPONENTS)之二

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

组件制作之一(概念)

编程语言 网络编程
组件制作之一(概念)

为你的ASP程序制作一个编译组件(上)

ASP
为你的ASP程序制作一个编译组件(上)

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

为你的ASP程序制作一个编译组件(下)

ASP
为你的ASP程序制作一个编译组件(下)

为你的ASP程序制作一个编译组件(中)

ASP
为你的ASP程序制作一个编译组件(中)

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

了解WEB页面工具语言XML(二) 定义

了解WEB页面工具语言XML(二)  定义

数字随机排序

数字随机排序
下拉加载更多内容 ↓