汇编 | Java | C# | Delphi | C/C++ |

DELPHI基础教程 第十九章 Delphi自定义部件开发(四)

第十九章 Delphi自定义部件开发(四) 织梦内容管理系统

19.3.2 创建图形部件 

dedecms.com

图形控制是一类简单的部件。因为纯图形部件从不需要得到键盘焦点,所以它没有也不要窗口句柄。包含图形控制的应用程序用户仍然可以用鼠标操作控制,但没有键盘界面。

内容来自dedecms

  在本例中提供的图形部件是TShapeShape部件位于Component PaletteAdditional页。本例中的Shape部件有所不同,因此称其为TSampleShape 内容来自dedecms

  创建图形部件需要下列三个步骤:

dedecms.com

  ● 创建和注册部件

内容来自dedecms

  ● 公布(publishing)继承的属性 dedecms.com

增加图形功能 织梦好,好织梦

 

本文来自织梦

19.3.2.1 创建和注册部件 织梦好,好织梦

  内容来自dedecms

每个部件的创建都从相同的方式开始,在本例中如下:

本文来自织梦

建立名为Shapes的部件单元

copyright dedecms

TGraphicControl 继承,将新部件称为TSampleShape 本文来自织梦

Component PaletteSamples页上注册TSampleShape dedecms.com

  织梦好,好织梦

unit Shapes dedecms.com

 

本文来自织梦

intertace 织梦好,好织梦

 

内容来自dedecms

use SysUtils, WinTypes, WinProcs, Messages, Classes, 织梦好,好织梦

GraphicsControlsForms; 织梦好,好织梦

 

本文来自织梦

type 织梦好,好织梦

TSampleShape=class(TGraphicControl) 内容来自dedecms

end;

织梦内容管理系统

  本文来自织梦

implementation copyright dedecms

 

内容来自dedecms

procedure Register;

内容来自dedecms

begin 织梦好,好织梦

RegisterComponents('Samples'[TSampleShape]); 本文来自织梦

end; copyright dedecms

  织梦好,好织梦

end.

内容来自dedecms

  织梦内容管理系统

19.3.2.2 公布继承的属性 织梦好,好织梦

  织梦内容管理系统

一旦决定了部件类型,就能决定在父类的protected部分声明哪些属性和事件能为用户可见。TGraphicControl已经公布了所有作为图形控制的属性,因此,只需公布响应鼠标和拖放事件的属性。

本文来自织梦

 

dedecms.com

  type

织梦好,好织梦

TSampleShape=class(TGraphicControl) 织梦好,好织梦

published

内容来自dedecms

property DragCursor; dedecms.com

property DragMode;

dedecms.com

property OnDragDrop; dedecms.com

property OnDragOver;

copyright dedecms

property ONEndDrag; 本文来自织梦

property OnMouseDown; 本文来自织梦

property OnMouseMove;

织梦好,好织梦

property OnMouseup; copyright dedecms

end;

织梦好,好织梦

 

copyright dedecms

这样,该Shape控制具有通过鼠标和拖放与用户交互的能力。

织梦好,好织梦

 

织梦好,好织梦

19.3.2.3 .增加图形能力

本文来自织梦

 

织梦内容管理系统

一旦你声明了图形部件并公布了继承的属性,就可以给部件增加图形功能。这时需要知道两点:

copyright dedecms

  ● 决定画什么 内容来自dedecms

  ● 怎样画部件图形

本文来自织梦

  织梦内容管理系统

  Shape控制的例子中,需要增加一些能使用户在设计时改变形状的属性。

copyright dedecms

  dedecms.com

1. 决定画什么 内容来自dedecms

  图形部件通常都具有改变外观的能力,图形控制的外观取决于其某些属性的结合,例如Gauge控制具有决定其形状、方向和是否图形化地显示其过程的能力。同样,Shape控制也应有决定显示各种形状的能力. 织梦内容管理系统

给予Shape控制这种能力,增加名为Shape的属性。这需要下列三步: 内容来自dedecms

声明属性类型

copyright dedecms

声明属性 内容来自dedecms

编写实现方法

织梦内容管理系统

 

dedecms.com

  ⑴ 声明属性类型 copyright dedecms

  当声明一个用户自定义类型的属性时,必须首先声明属性类型。最普通地用于属性的自定义类型是枚举类型。 织梦好,好织梦

  对Shape控制来说,需要声明一个该控制能画形状的枚举,下面是枚举类型的声明:

织梦内容管理系统

 

dedecms.com

type 织梦内容管理系统

TSampleShapeType=(sstRectangle, sstSquare, sstRoundRect,

dedecms.com

sstRoundSquare, sstEllipse, sstCircle);

织梦好,好织梦

TSampleShape = class(TGraphicControl) 内容来自dedecms

end; copyright dedecms

 

dedecms.com

这样,就可以用该类型来声明属性。 织梦内容管理系统

声明属性

本文来自织梦

当声明一个属性时,通常需要声明私有域来保存属性值,然后描述读写属性值的方法。

织梦好,好织梦

对于Shape控制,将声明一个域保存当前形状,然后声明一个属性通过方法调用来读写域值。 内容来自dedecms

 

织梦内容管理系统

type

织梦内容管理系统

TSampleShape=class(TGrahpicControl)

本文来自织梦

private 织梦好,好织梦

FShape: TSampleShapeType;

本文来自织梦

procedure SetShape(value: TSampleShapeType);

织梦内容管理系统

published

dedecms.com

property Shape: TSampleShapeType read FShape write SetShape; 织梦好,好织梦

end; copyright dedecms

  本文来自织梦

现在,只剩下SetShape的实现部分了。 织梦内容管理系统

编写实现方法 织梦内容管理系统

下面是SetShape的实现:

dedecms.com

  本文来自织梦

procedure TSampleShape.SetShape(value: TSampleShapeType); 织梦内容管理系统

begin 织梦内容管理系统

if FShape<>value then

织梦好,好织梦

begin copyright dedecms

FShape := value; 织梦内容管理系统

Invalidate(True); { 强制新形状的重画 }

dedecms.com

end;

dedecms.com

end; 织梦好,好织梦

 

copyright dedecms

2. 覆盖constructordestructor

本文来自织梦

为了改变缺省属性值和初始化部件拥有的对象,需要覆盖继承的constructordestructor方法。

内容来自dedecms

图形控制的缺省大小是相同的,因此需要改变WidthHeight属性。

织梦内容管理系统

本例中Shape控制的大小的初始设置为边长65个象素点。 dedecms.com

在部件声明中增加覆盖constructor

织梦好,好织梦

 

织梦内容管理系统

type

copyright dedecms

TSampleShape=class(TGraphicControl)

织梦内容管理系统

public 本文来自织梦

constructor Create(Aowner: TComponent); override; 织梦好,好织梦

end;

本文来自织梦

  织梦好,好织梦

用新的缺省值重新声明属性Heightwidth

copyright dedecms

  织梦内容管理系统

type copyright dedecms

TSampleShape=class(TGrahicControl) 内容来自dedecms

published 本文来自织梦

property Height default 65; 本文来自织梦

property Width default 65;

内容来自dedecms

end; 织梦内容管理系统

 

copyright dedecms

在库单元的实现部分编写新的constructor

本文来自织梦

 

本文来自织梦

constructor TSampleShape.Create(Aowner: TComponent);

内容来自dedecms

begin dedecms.com

inherited Create(AOwner);

织梦内容管理系统

width := 65; 内容来自dedecms

Height := 65;

本文来自织梦

end;

本文来自织梦

 

本文来自织梦

3. 公布PenBrush

内容来自dedecms

在缺省情况下,一个Canvas具有一个细的、黑笔和实心的白刷,为了使用户在使用Shape控制时能改变Canvas的这些性质,必须能在设计时提供这些对象;然后在画时使用这些对象,这样附属的PenBrush被称为Owned对象。 内容来自dedecms

管理Owned对象需要下列三步:

dedecms.com

声明对象域 织梦内容管理系统

声明访问属性 织梦内容管理系统

初始化Owned对象 织梦好,好织梦

 

内容来自dedecms

声明Owned对象域 织梦内容管理系统

拥有的每一个对象必须有对象域的声明,该域在部件存在时总指向Owned对象。通常,部件在constructor中创建它,在destructor中撤消它。

dedecms.com

Owned对象的域总是定义为私有的,如果要使用户或其它部件访问该域,通常要提供访问属性。

copyright dedecms

下面的代码声明了PenBrush的对象域: 内容来自dedecms

  内容来自dedecms

type copyright dedecms

TSampleShape=class(TGraphicControl) 本文来自织梦

private 本文来自织梦

FPen: TPen;

本文来自织梦

FBrush: TBrush;

copyright dedecms

end;

内容来自dedecms

 

本文来自织梦

声明访问属性

织梦好,好织梦

可以通过声明与Owned对象相同类型的属性来提供对Owned对象的访问能力。这给使用部件的开发者提供在设计时或运行时访问对象的途径。

织梦好,好织梦

下面给Shape控制提供了访问PenBrush的方法 织梦内容管理系统

 

内容来自dedecms

type

织梦好,好织梦

TSampleShape=class(TGraphicControl)

copyright dedecms

private 织梦好,好织梦

procedure SetBrush(Value: TBrush); 织梦内容管理系统

procedure SetPen(Value: TPen); 织梦内容管理系统

published dedecms.com

property Brush: TBrush read FBrush write SetBrush; 本文来自织梦

property Pen: TPen read FPen write SetPen; 织梦内容管理系统

end;

织梦好,好织梦

  织梦内容管理系统

然后在库单元的implementation部分写SetBrushSetPen方法: 织梦内容管理系统

 

织梦内容管理系统

procedure TSampleShape.SetBrush(Value: TBrush);

copyright dedecms

begin dedecms.com

FBrush.Assign(Value);

copyright dedecms

end; 织梦内容管理系统

  copyright dedecms

procedure TSampleShape.SetPen(Value: TPen);

dedecms.com

begin 内容来自dedecms

FPen.Assign(Value);

内容来自dedecms

end;

织梦内容管理系统

 

织梦好,好织梦

初始化Owned对象

copyright dedecms

部件中增加了的新对象,必须在部件constructor中建立,这样用户才能在运行时与对象交互。相应地,部件的destructor必须在撤消自身之前撤消Owned对象。

内容来自dedecms

因为Shape控制中加入了PenBrush对象,因此,要在constructor中初始化它们,在destructor中撤消它们。 copyright dedecms

Shape控制的constructor中创建PenBrush

织梦好,好织梦

  织梦好,好织梦

constructor TSampleShape.Create(Aowner: TComponent); 本文来自织梦

begin

copyright dedecms

inherited Create(AOwner);

内容来自dedecms

Width := 65; 织梦好,好织梦

Height := 65;

织梦内容管理系统

FPen := TPen.Create;

本文来自织梦

FBrush := TBrush.Create;

dedecms.com

end;

dedecms.com

  织梦内容管理系统

在部件对象的声明中覆盖destructor

dedecms.com

 

内容来自dedecms

type

织梦内容管理系统

TSampleShape=class(TGraphicControl) copyright dedecms

public 内容来自dedecms

construstor.Create(Aowner: TComponent); override;

织梦好,好织梦

destructor.destroy; override;

织梦内容管理系统

end; copyright dedecms

 

本文来自织梦

在库单元中的实现部分编写新的destructor copyright dedecms

  织梦好,好织梦

destructor TSampleShape.destroy;

内容来自dedecms

begin

织梦好,好织梦

FPen.Free;

织梦好,好织梦

FBrush.Free;

织梦内容管理系统

inherited destroy;

copyright dedecms

end; 织梦好,好织梦

  dedecms.com

设置Owned对象的属性 copyright dedecms

处理PenBrush对象的最后一步是处理PenBrush发生改变时对Shape控制的重画问题。PenBrush对象都有OnChange事件,因此能够在Shape控制中声明OnChange事件指向的事件处理过程。 dedecms.com

下面给Shape控制增加了该方法并更新了部件的constructor以使PenBrush事件指向新方法:

织梦好,好织梦

  内容来自dedecms

type 内容来自dedecms

TSampleShape = class(TGraphicControl)

本文来自织梦

published

织梦好,好织梦

procdeure StyleChanged(Sender: TObject); 内容来自dedecms

end;

内容来自dedecms

 

织梦内容管理系统

implemintation

内容来自dedecms

  dedecms.com

constructor TSampleShape.Create(AOwner:TComponent); dedecms.com

begin

内容来自dedecms

inherited Create(AOwner);

织梦内容管理系统

Width := 65; 本文来自织梦

Height := 65;

内容来自dedecms

Fpen := TPen.Create; copyright dedecms

FPen.OnChange := StyleChanged;

内容来自dedecms

Fbrush := TBrush.Create; 内容来自dedecms

FBrush.OnChange := StyleChanged; dedecms.com

end;

织梦内容管理系统

 

内容来自dedecms

procedure TSampleShape.StyleChanged(Sender: TObject); 本文来自织梦

begin

织梦好,好织梦

Invalidate(true); 内容来自dedecms

end; 本文来自织梦

 

织梦内容管理系统

当变化发生时,部件重画以响应PenBrush的改变。

dedecms.com

  织梦内容管理系统

4. 怎样画部件图形

dedecms.com

图形控制基本要素是在屏幕上画图形的方法。抽象类TGraphicControl定义了名为Paint的虚方法,可以覆盖该方法来画所要的图形。

织梦好,好织梦

Shape控制的paint方法需要做:

本文来自织梦

使用用户选择的PenBrush

本文来自织梦

使用所选的形状

本文来自织梦

调整座标。这样,方形和圆可以使用相同的WidthHeight

织梦内容管理系统

  织梦好,好织梦

覆盖paint方法需要两步: 内容来自dedecms

在部件声明中增加Paint方法的声明

织梦好,好织梦

implementation部分写Paint方法的实现 织梦内容管理系统

  织梦好,好织梦

下面是Paint方法的声明: 织梦好,好织梦

  织梦好,好织梦

type 织梦内容管理系统

TSampleShape = class(TGraphicControl)

内容来自dedecms

protected 织梦好,好织梦

procedure Paint; override;

本文来自织梦

end; 织梦内容管理系统

 

织梦内容管理系统

然后,编写Paint的实现:

dedecms.com

  内容来自dedecms

procedure TSampleShape.Paint; 织梦好,好织梦

begin

织梦好,好织梦

with Canvas do dedecms.com

begin

内容来自dedecms

Pen := FPen; 本文来自织梦

Brush := FBrush; dedecms.com

case FShape of

内容来自dedecms

sstRectangle, sstSquare :

dedecms.com

Rectangle(0, 0, Width, Height);

本文来自织梦

sstRoundRect, sstRoundSquare: 织梦好,好织梦

RoundRect(0, 0, Width, Height, Width div 4, Height div 4);

dedecms.com

sstCircle, sstEllipse :

织梦好,好织梦

Ellipse(0, 0, Width, Height);

内容来自dedecms

end; 本文来自织梦

end; copyright dedecms

end;  内容来自dedecms

无论任何控制需要更新图形时,Paint就被调用。当控制第一次出现,或者当控制前面的窗口消失时,Windows会通知控制画自己。也可以通过调用Invalidate方法强制重画,就象StyleChanged方法所做的那样。

内容来自dedecms

精彩推荐
热点内容
最近更新