关于VCL的编写 (一) 如何编写自己的VCL控件

如何编写自己的VCL控件

用过Delphi的朋友们,大概对Delphi的最喜欢Delphi的不是他的强类型的pascal语法,而是强大的VCL控件,本人就是一位VCL控件的爱好者。

VCL控件的开源,给我们带来了享之不尽的优点。不像曾经的ole控件以及ActiveX,你全然能够重写Delphhi标准控件,并且网上这方面的资源非常多。

关于怎样编写VCL控件,和多Delphi的书籍里都有介绍,在此简单的说明一下。

在Delphi中,TComponent是全部VCL构件的基础。编写非可视构件以便从TComponent派生。Delphi提供了若干专门用于制作控件(可视构件)的基本构件类型,都是从TControl和TWinControl派生而来。其派生关系例如以下:

TControl---TGraphicControl---TCustomLabel

TWinControl--TCustomControl---TCustomGrid

---TButtonControl--TCustomGroupBox

---TScrollingWinControl--TCustomPanel

---TCustomComboBox

---TCustomEdit

---TCustomListBox

TControl的子类型用于非窗体式控件,TWinControl的子类型 则用于窗体式控件。除非特殊须要,一般不直接从TControl和 TWinControl派生新控件,而是从其子类型派生。这样能够充分利 用原有的属性、事件和方法,降低非常多工作量。

编写控件,首先要选择适当的VCL对象类型作为父对象,以派生新的对象。

以下给出一个详细的样例,来实现一个增强型的Edit输入框,是他能够依据输入的数据类型对输入字符进行有效性推断,添加相似于TLabel一样的左对齐、中对齐、右对齐功能。

通过Delphi的构件向导从TEdit继承生成自己的控件:

TEditDataType = (dtpString, dtpInteger, dtpFloat); //输入的数据类型

TMyEdit=class(TEdit)

private

FAlignment: TAlignment;

FDataType: TEditDataType;

Fprecision: Integer;

procedure SetAlignment(const Value: TAlignment);?? //用来设置对齐方式方法

procedure SetPrecision(const Value: Integer);????????????

procedure SetDataType(const Value: TEditDataType);

function GetAsFloat: double;

function GetAsInteger: Integer;

procedure SetAsFloat(const Value: double);

procedure SetAsInteger(const Value: Integer);

function GetAsText: String;

procedure SetAsText(const Value: String);

protected

procedure CMExit(var Message: TCMExit); message CM_EXIT; //重写消息, 下一篇将具体介绍消息

procedure KeyPress(var Key: Char); override; //重写键盘按键事件,用来控制键盘输入

public

constructor Create(AOwner: TComponent); override;

procedure CreateParams(var Params: TCreateParams); override;//重写,实现左右对其

property Alignment: TAlignment read FAlignment write SetAlignment default

taLeftJustify; //对齐方式

property DataType: TEditDataType read FDataType write SetDataType default

dtpString; //设置输入的数据类型

published

property Precision: Integer read Fprecision write SetPrecision; //小数点有效位数property AsFloat :double read GetAsFloat write SetAsFloat; //? 添加相似于C++一样 的类型转换函数,不用每一次自己调用函数转换

property AsInteger:Integer read GetAsInteger write SetAsInteger;

property AsString :String read GetAsText write SetAsText;

end;

//以下我们来一个一个实现我们想要实现的功能。

第一个实现左对其必须重写CreateParams函数,详细实现例如以下:

procedure TMyEdit.CreateParams(var Params: TCreateParams);

const

Alignments: array[Boolean, TAlignment] of DWORD =

((SS_LEFT, SS_RIGHT, SS_CENTER), (SS_RIGHT, SS_LEFT, SS_CENTER));

begin

inherited CreateParams(Params);

CreateSubClass(Params, ‘EDIT‘);

with Params do

begin

Style := Style or SS_NOTIFY or

Alignments[UseRightToLeftAlignment, FAlignment];

end;

end;

//设置对齐方式

procedure TMyEdit.SetAlignment(const Value: TAlignment);

begin

if FAlignment <> Value then

begin

FAlignment := Value;

RecreateWnd; //重画控件

end;

end;

依据所设定的数据类型控制输入的字符串,重写KeyPress事件

procedure TlsCustomEdit.KeyPress(var Key: Char);

begin

case FDataType of

dtpInteger:  //假设是整数

begin

if not (Key in [‘0‘..‘9‘, ‘-‘, #8, #13, #35, #39]) then

Key := #0;

if (Key = ‘-‘) and ((Pos(‘-‘, Text) > 0) or (SelStart <> 0)) then

Key := #0;

end;

dtpFloat:  //假设是符点数

begin

if not (Key in [‘0‘..‘9‘, ‘.‘, ‘-‘, #8, #13, #35, #36, #37, #39]) then

Key := #0;

if (Key = ‘.‘) and (Pos(‘.‘, Text) > 0) then

Key := #0;

if (Key = ‘-‘) and ((Pos(‘-‘, Text) > 0) or (SelStart <> 0)) then

Key := #0;

end

end;

inherited KeyPress(Key);? //调用父类的KeyPress方法

end;

号了,如今这个控件就差点儿相同了.

关于简单控件的编写,一般仅仅须要从Delphi为你准备好的基本构件类型继承下来,然后重写父类的一些方法,加入自己的一些方法,以及属性就能够了.你还能够学Delphi一样写出一些抽象构件类型来, 比方说上面的TMyEdit, 你能够先写一个主要的TCustomMyEdit 然后,从他继承,引伸出很多其它控件出来.? 基本构件类型的编写,你得高瞻远瞩, 让你的基本类型足够抽象. 在这里, 你所学的OOP的思想就能够在此大展身手了. 习惯上, 基本构件类型,不须要published.

在制作构件时,有要接触到非常多类和非常多的属性和方法,在这里,列出了一些比較重要并且比較经常使用的类和它的属性和方法。

TComponent

ComponentState 属性,标志构件正处于的状态,如编辑,调入,读取等。能够跟据状态来决定当前构件要做的事情;

Notification方法:当一个构件被删除,增加时,会使用这一个方法通知全部的构件(除了被删除或增加的那一个构件)。这一个方法有两个參数:AComponent,Operation。进入的參数通知构件如今对哪一个构件进行操作,进行什么样的操作。使用时,在新的构件里覆盖掉Notification方法,在Notification方法里写上接收到通知的代码就能够了;在做一些容器控件,控件关联,如DB构件时非常实用.否则,你删除时会有一个地址错误.

Loaded方法:当一个构件加载完成后,该方法被调用。与Notification方法一样,使用时,在新的构件里覆盖掉Loaded方法,然后在Loaded方法里写上加载完成的代码就能够了;

Updating方法:当一个构件正在被改变时,被调用;

Updated方法:当一个构件改变完成时,被调用。

TGraphicControl

Canvas属性:画布,图形构件必须有的属性;

Left, Top, Width, Height属性:在父构件里显示出来的大小;

ControlState属性:控制状态,如鼠标按下,是否接受调色板更改信息,是否接受焦点等;

ControlStyle属性:控制类型,如是否透明,是否有3D Frame等等;

Paint方法:该方法在接受到WM_PAINT消息后就被调用,画出自己;

VCL的初步学习一般还算easy,和不论什么计算机语言一样,当你须要更深入的时候,进展就比較慢了,所须要的知识是越来越多。就VCL的编写一些难点列举一二:一个是系统消息几Windows API。你须要写一个比較复杂的控件,你须要对系统消息比較熟悉。还有一个是属性编辑器以及组件编辑器的编写。别看Delphi中VCL有源代码,但不是所有的,就属性编辑器来说,想找到一些非常有參考价值的,非常难。本人将在接下来的篇章中慢馒和读者探讨。

时间: 2024-08-03 10:57:56

关于VCL的编写 (一) 如何编写自己的VCL控件的相关文章

Delphi 编写ActiveX控件(OCX控件)的知识和样例(有详细步骤)

一.ActiveX应用情况简介: ActiveX控件也就是一般所说的OCX控件,它是 ActiveX技术的一部分.ActiveX是微软公司推出的基于组件对象模型COM的技术,包括对Windows 32位应用编程接口(Win32 API)和组件对象模型的一系列扩充和增强,目标是把计算机桌面环境与因特网环境集成起来,同时保护在Windows技术中现有的开发投资.微软的 ActiveX技术根本上就是修改过的OCX技术,使它能够跨越Internet,主要是使用WWW来传递控件.            A

Android高级图片滚动控件,编写3D版的图片轮播器

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17482089 大家好,好久不见了,最近由于工作特别繁忙,已经有一个多月的时间没写博客了,我也是深感惭愧.那么今天的这篇既然是阔别了一个多月的文章,当然要带来更加给力点的内容了,那么话不多说,赶快进入到今天的正题吧. 说 到图片轮播器,很多的Android应用中都会带有这个功能,比如说网易新闻.淘宝等.最新我们公司的一款应用也加入了这个功能,并且在图片轮播的基础上 还增加了三维立体

WinForm下编写分页控件,实现DataGridView的分页效果

 前几天做C/S项目的时候用到了分页查询,所以就想去网上找一些封装好的分页控件,类似BS项目中的那种.但是找了好几个都不是特别的好,没有自己想要的.而且WinForm 里面的DataGridView也不像WebForm里面的GridView那样有自带的分页功能.没办法还是自己动手封装一个吧,以后复用也方便. 从网上找了几个demo做了一下,实现挺简单的. 用到的方法就是编写一个用户控件,下面说明如何实现: 一,先画界面 新建一个用户控件,然后拖拽几个标签,文本框和按钮,排列好.如下图所示:

C#编写第三方控件,实现窗体控件的一键取值

上篇博客中讲到了利用编写第三方控件的方法,实现给窗体控件的Text属性赋值,比如说:TextBox,Combox等.有赋值,当然也有取值操作.从窗体的控件中取值,然后存入变量或者实体属性当中,传入到数据访问层进行添加,更新等操作也是我们经常使用的.如何实现一键取值呢? 使用的方法在上篇博客中已经做了详细说明,这里就不再累述了. 代码写在这里: 该方法的作用是,遍历传入窗体中的控件,并且获取其值赋给实体类的相应属性. /// <summary> /// 从窗体控件取值,填充到学生实体类中 ///

C#编写第三方控件,实现窗体控件的一键赋值

. 事出有因 在写程序的时候,经常会写上面这样的代码,把查询的结果显示到窗体上,我们怎么做的呢? 一行一行的进行赋值,这样的代码写起来最枯燥,而且还容易出错.大家有没有发现,上面的代码都在做相同的事情-赋值.相类似的代码写了三遍以上,就要考虑是不是能对这个过程进行封装.封装出一个方法,帮我们自动完成这些重复性的操作. 思考过程 所接触项目中也有写好的类似方法.只是它涉及到了很多其它的方法,一个套一个,抽离出来特别不方便.而且还有几个令人不爽的地方: 第一是,控件在命名的时候必须和相对应实体属性相

关于Edit控件focused状态,调用自己编写的键盘

一.涉及编写自己的自己的键盘 由于只使用英文字母跟数字等简单的字符而已,没有包括全角或者中文字符.所以直接使用跟手机的输入密码键盘一样的键盘即可. 遇到的问题:1.使用法keybd_event()的方式进行发送消息,不管发送大小写字母都是显示小写字母 2.键盘不能有焦点状态,否则使用的keybd_event则无法将字符发送给edit框.如果使用有焦点的状态则会导致edit控件跟我自己编写的键盘耦合性太大. 3.由于使用duilib的tilelayout而出现键盘的所有按键无法正常对齐. 解决方案

【C#基础】CSA控件编写秘籍

新建CSA控件 1.新建一个纯类,命名空间是: namespace SimPerfect.CSAControlLibrary.CSAControls 2.实现两个构造函数:无参和传Candy参数 public CDealProcess() { InitMe(); } public CDealProcess(Candy parentCandy) { this.ParentCandy = parentCandy; InitMe(); } 3.编写InitMe()方法初始化控件属性: private

编写 ATL ActiveX 控件

一直想写一些ATL.ActiveX的东西,但是一直都没有下定决心去写,一来是自己对这方面的东西不太了解,写不出什么名堂:二来就是懒,懒得思考,懒得动手.这篇文章只是记录一下ATL ActiveX控件的一个大概写法跟使用方法,方便有这方面需求的同学快速上手. 一.ATL ActiveX控件编写 我做的是一个简单的图表控件,提供扇形图跟柱状图两种表现方式. 我们先简单列一下图表的成员属性: 1.图表样式:柱状图还是扇形图. typedef enum _em_chart_type { ctNull,

JS调用Delphi编写的OCX控件

原文:http://www.mamicode.com/info-detail-471283.html 一.使用Delphi XE2编写OCX控件 生成OCX工程: 1.File-New-Other,在New Items对话框中选择Delphi Projects-ActiveX-ActiveX Library 2.File-New-Other,在New Items对话框中选择Delphi Projects-ActiveX-ActiveX Control,这里要封Delphi的TStringGrid