继上次我们学习开发一个简单的画线控件后,基本的制作控件步骤已经清楚了,这次我们继续加深学习控件的制作。我们打开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 ;
end;

可以看到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;
end;
implementation
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的话就不写进窗体DFM文件,节省空间}
property Visible;
property OnClick;
end; procedure Register; implementation procedure Register;
begin
RegisterComponents('Samples', [TLineTo]);
end; constructor TLineTo.Create(Aowner: TComponent);
begin
inherited Create(AOwner);
{一些字段可以在这里初始化}
FPenWidth := ;
end; destructor TLineTo.Destroy;
begin
{一些资源可以在这里释放}
inherited Destroy;
end; procedure TLineTo.Paint;
begin
with Canvas do
begin
MoveTo(, );
LineTo(Self.Width, Self.Height);
end;
end; 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;
end;
end;
end.

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

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

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

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

运行结果如下图所示:

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

Delphi 7学习开发控件(续)的更多相关文章

  1. Delphi 7学习开发控件

    我们知道使用Delphi快速开发,很大的一方面就是其强大的VCL控件,另外丰富的第三方控件也使得Delphi程序员更加快速的开发出所需要的程序.在此不特别介绍一些概念,只记录自己学习开发控件的步骤.假 ...

  2. Delphi 7学习开发控件(继承TGraphicControl只画一条线)

    我们知道使用Delphi快速开发,很大的一方面就是其强大的VCL控件,另外丰富的第三方控件也使得Delphi程序员更加快速的开发出所需要的程序.在此不特别介绍一些概念,只记录自己学习开发控件的步骤.假 ...

  3. Delphi中,indy控件实现收发邮件的几点学习记录( 可以考虑加入多线程,用多个邮箱做一个邮箱群发器) 转

    关于用Delphi中的Indy控件实现收发邮件的几点学习记录             这几天心里颇不宁静,不是因为项目延期,而是因为自己几个月前做的邮件发送程序至今无任何进展,虽然一向谦虚的人在网上发 ...

  4. Delphi中的DBGrid控件

    在Delphi中,DBGrid控件是一个开发数据库软件不能不使用的控件,其功能非常强大,可以配合SQL语句实现几乎所有数据报表的显示,操作也非常简单,属性.过程.事件等都非常直观,但是使用中,有时侯还 ...

  5. JS调用Delphi编写的OCX控件

    原文:http://www.mamicode.com/info-detail-471283.html 一.使用Delphi XE2编写OCX控件 生成OCX工程: 1.File-New-Other,在 ...

  6. Delphi中使用TXMLDocument控件应注意的问题 转

    Delphi中使用TXMLDocument控件应注意的问题 delphiconstructorxmlclass今天写了一个类,其中用到了TXMLDocument控件.这个控件我是要动态生成的. 但是却 ...

  7. 过实现鹰眼图这个功能来进一步学习MapControl控件

    我们通过实现鹰眼图这个功能来进一步学习MapControl控件.在实现鹰眼图之前,我们需 要接口有更深入的了解. 变主动为被动-出接口(OutBound interface) COM编程类似客户端和服 ...

  8. 【使用指南】ComponentOne Enterprise .NET开发控件集

    为方便广大 .NET开发人员更好的使用 ComponentOne Enterprise .NET开发控件集,葡萄城专门推出了 ComponentOne Enterprise 使用指南,该指南详细地介绍 ...

  9. Expression Blend学习四控件

    原文:Expression Blend学习四控件 Expression Blend制作自定义按钮 1.从Blend工具箱中添加一个Button,按住shift,将尺寸调整为125*125; 2.右键点 ...

随机推荐

  1. Java分享笔记:自定义枚举类 & 使用enum关键字定义枚举类

    在JDK1.5之前没有enum关键字,如果想使用枚举类,程序员需要根据Java语言的规则自行设计.从JDK1.5开始,Java语言添加了enum关键字,可以通过该关键字方便地定义枚举类.这种枚举类有自 ...

  2. 微信小程序bindtap与catchtap的区别

    1.什么是事件 (1) 事件是视图层到逻辑层的通讯方式. (2) 事件可以将用户的行为反馈到逻辑层进行处理. (3) 事件可以绑定在组件上,当达到触发事件,就会执行逻辑层中对应的事件处理函数. (4) ...

  3. PHP将二位数组按照第二维的某个元素的值进行排序

    例如: //原始数组是这样的,希望能够按照第二维中的run_date升序或者降序进行排序: $arr=array( 0=>array( 'run_date'=>'2017-11-21', ...

  4. hibernate中配置单向多对一关联,和双向一对多,双向多对多

    什么是一对多,多对一? 一对多,比如你去找一个父亲的所有孩子,孩子可能有两个,三个甚至四个孩子. 这就是一对多 父亲是1 孩子是多 多对一,比如你到了两个孩子,它们都是有一个共同的父亲. 此时孩子就是 ...

  5. angularjs路由不断刷新当前页面

    最近做项目遇到个问题,使用angular-route的时候,第一次点击 [按钮 a]会进入按钮a对应的控制器,接着再次点击a按钮的的时候就不会进入控制器了.我想要的效果是每次点击都能进入control ...

  6. python-三级菜单的优化实现

    三级菜单需求: 1.可依次选择进入各子菜单 2.可从任意一层往回退到上一层 3.可从任意一层退出程序 所需新知识点:列表.字典 先通过字典建立数据结构 #创建字典 city_dic = { " ...

  7. C++常量(const)的使用

    #include <iostream> using namespace std; class MyClass { public: int GetValue() const ; int Ge ...

  8. poj2230 欧拉回路

    http://poj.org/problem?id=2230 Description Bessie's been appointed the new watch-cow for the farm. E ...

  9. javascript 之 为函数设置默认参数值

    方法一: function example(a,b){ var a = arguments[0] ? arguments[0] : 1;//设置参数a默认为1 var b = arguments[1] ...

  10. FIFO的使用场景

    (1) 数据的缓冲.如模型图所示,如果数据的写入速率高,但间隔大,且会有突发;读出速率小,但相对均匀.则通过设置相应深度的FIFO,可以起到数据暂存的功能,且能够使后续处理流程平滑,避免前级突发时,后 ...