Delphi 7学习开发控件(续)

    技术2022-05-20  38

          继上次我们学习开发一个简单的画线控件后,基本的制作控件步骤已经清楚了,这次我们继续加深学习控件的制作。我们打开Delphi 7创建一个应用程序,拖动LineTo控件到窗体上,仔细看左边的对象设计器,可以看到默认的属性Properties有11个,而事件Events没有一个,如下图所示:

    我们上次开发的TLineTo控件,只重写了Paint方法,使之能够画直线,并没有添加任何属性,从其父类TGraphicControl的源代码,我们也看不到那些属性,继续跟踪TGraphicControl的父类TControl,可以看到其长长的源代码:

      TControl =  class(TComponent)     private      FLeft: Integer;      FTop: Integer;      FVisible: Boolean;      FOnClick: TNotifyEvent;       {中间代码太长,省略,具体请看Delphi源代码}     protected           procedure Click;  dynamic;       property OnClick: TNotifyEvent  read FOnClick  write FOnClick  stored IsOnClickStored;           {中间代码太长,省略,具体请看Delphi源代码}     public       constructor Create(AOwner: TComponent);  override;       destructor Destroy;  override;       property Visible: Boolean  read FVisible  write SetVisible  stored IsVisibleStored  default True;         {中间代码太长,省略,具体请看Delphi源代码}     published       property Left: Integer  read FLeft  write SetLeft;       property Top: Integer  read FTop  write SetTop;       property Width: Integer  read FWidth  write SetWidth;       property Height: Integer  read FHeight  write SetHeight;       property Cursor: TCursor  read FCursor  write SetCursor  default crDefault;       property Hint:  string  read FHint  write FHint  stored IsHintStored;       property HelpType: THelpType  read FHelpType  write FHelpType  default htContext;       property HelpKeyword:  String  read FHelpKeyword  write SetHelpKeyword  stored IsHelpContextStored;       property HelpContext: THelpContext  read FHelpContext  write SetHelpContext  stored IsHelpContextStored  default  0end

    可以看到TControl派生自组件基类TComponent,而类TControl有四个保留字声明,控制着类中对象的访问权限。我们可以看到其published声明中的属性与我们所创建的TLineTo画线控件的默认属性一致,这是发行类型成员。其他一般控件有的属性被TControl声明为public,比如Visible属性被声明成public,要使我们创建的控件带有Visible属性,就必须把Visible重声明为published。

    type    TLineTo =  class(TGraphicControl)     {省略····}     published       property Visible;     end

    而在TControl的protected声明里包含了最基本的标准事件,比如OnClick、OnDblClick、OnMouseDown等等。如果我们要让创建的组件在对象设计器可以对相应的标准事件进行响应的话,就必须要重声明事件属性的保护级别,比如把OnClick声明为published,就可以在对象设计器的Events中对组件进行事件响应。

    type    TLineTo =  class(TGraphicControl)     {省略······}     published       property OnClick;     end

    假设我们要让创建的组件在内部自己实现对标准事件的响应,意思是改写标准事件处理过程,那么可以重写事件处理代码,所有标准事件在TControl中都定义了相应的Protected动态方法,只是没有加On,例如OnClick事件调用名为Click的方法,所以我们只要覆盖TControl的Click方法,就可以重写此事件响应。

    type    TLineTo =  class(TGraphicControl)     protected           procedure Click;  override;     endimplementation  procedure TLineTo.Click;  begin     inherited Click;    {执行标准处理,包括调用事件处理过程}  end

    我们所做的画线控件,线笔宽度被固定了,所以我们得添加一个画笔宽度PenWidth,以改变画线的粗细。在此,我们创建的TLineTo控件,为它添加PenWidth属性,开放Visible属性,开放OnClick事件,重写它的Click消息,具体的完整源码如下:

    unit LineTo;    interface    uses    SysUtils, Classes, Controls, Dialogs;    type    TLineTo =  class(TGraphicControl)     private      FPenWidth: Integer;       procedure SetPenWidth(Value: Integer);     protected       procedure Paint;  override;       procedure Click;  override;     public       constructor Create(AOwner: TComponent);  override;       destructor Destroy;  override;     published       property PenWidth: Integer  read FPenWidth  write SetPenWidth  default  1{如果值是1的话就不写进窗体DFM文件,节省空间}       property Visible;       property OnClick;     end;    procedure  Register;    implementation    procedure  Registerbegin    RegisterComponents( 'Samples'[TLineTo]);  end;    constructor TLineTo.Create(Aowner: TComponent);  begin     inherited Create(AOwner);     {一些字段可以在这里初始化}    FPenWidth :=  1end;    destructor TLineTo.Destroy;  begin     {一些资源可以在这里释放}     inherited Destroy;  end;    procedure TLineTo.Paint;  begin     with Canvas  do     begin      MoveTo( 00);      LineTo(Self.Width, Self.Height);     endend;    procedure TLineTo.Click;  begin     inherited Click;  {执行标准处理,包括调用事件处理过程}    ShowMessage( '画线控件 V1.0 by 无幻');    {需要uses Dialogs}  end;    procedure TLineTo.SetPenWidth(Value: Integer);  begin     if FPenWidth <> Value  then     begin      FPenWidth := Value;      Canvas.Pen.Width := FPenWidth;      Invalidate;     endendend.   

    由于在上一次,我们已经安装过TLineTo控件了,所以这次我们只需重新编译下TLineTo组件就可以了。打开dclusr.dpk,选中LineTo.pas再点击编译Compile,没有弹出错误就是重新编译成功。保存关闭文件。

    下面新建一个应用程序来测试,拖动TLineTo控件到窗体上,左边的对象设计器如下图所示:

    可以看到属性Properties多了PenWidthVisible属性,事件多了OnClick,我们添加对TLineTO组件的OnClick事件处理,如下代码:

    procedure TForm1.lnt1Click(Sender: TObject);  begin    ShowMessage( '你点击了TLineTo控件');  end

    运行结果如下图所示:

    我们可以看到先弹出了“你点击了TLineTo控件”,再弹出了“画线控件 V1.0 by 无幻,这就是因为TLineTo.Click事件的处理是先调用继承的方法,然后再执行自己添加的代码,而继承的方法就是OnClick函数。Delphi自定义组件所涉及到的知识不少,有些难以理解,有些比较少使用到,以后再继续介绍。


    最新回复(0)