热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于Delphi的组件设计之概念

作为组件制作的开始,应该了解一些概念,我以为这些概念是非常重要的,将可以作为以后实践的理论基础。一、组件的简要层次结构一般情况下,VCL的组件可以从Tcomponent为开始。其最明显

作为组件制作的开始,应该了解一些概念,我以为这些概念是非常重要的,将可以作为以后实践的理论基础。

  一、组件的简要层次结构

  一般情况下,VCL的组件可以从Tcomponent为开始。其最明显的特征就是它的属性可以在设计时通过对象察看器来操纵,另外,他还能拥有其他组件。

  从Tcomponent下,分出非可视组件和可视组件。

  非可视组件如TOPenDialog,TTimer,TTable等,这些组件因为继承自Tomponent,所以也就继承了在设计时可以被操纵的特性。

  可视化组件始自TControl,是它引入了可视化属性和方法,使继承自它的类都有了这些可视化特性。

  TControl又分出两类组件类型:从TWinControl(窗口控件)自下的控件,和从TGraphicControl(图形控件)自下的控件。继承自TWinControl的控件将windows控件进行封装,所以拥有windows控件的很多特性,比如可以得到焦点,有唯一的句柄,用户可以通过发送消息与这些控件进行交互等。而继承自TGraphicControl的控件,也是可见的,但没有句柄,可以称之为图形控件,比如TLabel,TBevel,都是Delphi画出来的,并不占用系统资源。

  二、属性

  先看一个简单的属性定义:

TsomeObj=class

Private

FCount:integer;

Protected

Procedure SetCount(value:Integer);

published

Property count:integer read FCount write SetCount default 0;//属性定义

End;

  该属性从私有成员FCount读出值,而靠SetCount方法设置值到私有成员FCount。

  属性的优势在于可以很直观进行读写,而又不同于私有成员。因为属性可以通过写访问方法来保护私有成员:

Procedure TsomeBoj.SetCount(value:Integer);

Begin

If FCount<>value then

FCount:=value;

End;

  其中属性定义中的Default 0并不是默认值(即对象察看器显示的值),默认值要在组件类的构造函数中设定。而Default有这样的作用,决定DFM文件中是否要保存该属性的值,比如上面为Default 0,即当该属性值为0时,则该属性不会被保存到DFM中,如果该属性值不为0,则该属性会被保存到DFM中。另外属性定义还有一个关键字为

  NoDefault,设置了这个关键字,比如

Property count:integer read FCount write SetCount NoDefault;
  
  则无论它的值是什么,都会被写到DFM文件中。

  属性可以有如下几种类型,下面只给出简单介绍,而这些类型的属性,会在组件制作时详细的运用:

  简单类型属性:如上面定义的,加一个例子

Property text:string read Ftext write SetText;

  枚举类型属性:

TEnumtype=(Enum1,Enum2,Enum3);

FEnumtype:TEnumtype;

Property Enumtype:TEnumtype read FEnumtype write FEnumtype;

  在对象察看器中看来就是下拉列框选择值。

  集合类型属性:

Tset=(set1,set2,set3);

Tsets=set of Tset;

Fsets:Tsets;

Property sets:Tsets read Fsets write Fsets;

  在对象察看器中看来,就是列出几个选项分别设置真假。比如TForm的BorderIcons属性即是。

  对象类型属性:一个属性是一个对象,而这个对象必须派生自Tpersistent或者他之下的类,才能在对象察看器中可以展开它,并设置它里面的属性。

  数组类型属性:数组属性如果要在对象察看器中看见,需要有自己的属性编辑器(如果不想在对象察看器看当然就不用啦),是比较高级的组件,在后来的组件制作再来介绍,会更直观一些。这里只给出它的定义形式:

property Selected[Index: Integer]: Boolean read GetSelected write SetSelected;

   三、事件

  事件其实是一种特殊的属性,他是指针类型,指向一个事件方法类型。当有特定的事件发生时,它就会关联到一段执行代码。

  下面以一个例子来讲解事件是怎么发生的。

  我们先定义一个鼠标点下事件的鼠标事件类型,它其实就是方法指针:

type TMouseEvent = procedure (Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer) of object;

  又定义一个私有成员:鼠标事件类型的,即一个方法指针类型

FonMouseDown:TMouseEvent

  最后定义一个属性:类要通过这个属性将外部的事件处理函数和FonMouseDown关联在一起:

onMouseDown:TMouseEvent read FonMouseDown write FonMouseDown;

  当有鼠标左键点击的,系统会向窗口会发送WM_LBUTTONDOWN;消息

  Delphi可以截获这个消息,如下定义消息函数:

procedure WMLButtonDown(var Message: TWMLButtonDown);
message WM_LBUTTONDOWN;

  在这个消息处理函数中调DOMouseDown,DoMouseDown又调 用了MouseDown

  在这个函数里面才到了最重要的部分

  该函数是这样的:

procedure TControl.MouseDown(Button: TMouseButton;Shift: TShiftState; X, Y: Integer);

begin

if Assigned(FOnMouseDown) then FOnMouseDown(Self, Button, Shift, X, Y);

end;

  而我们先来看看用户外部是怎么操作的,

  他自己定义一个SomeobjMouseDown; 是一个事件处理函数,必须和TMouseEvent的形式一样:

Procedure SomeobjMouseDown(Sender: TObject; Button: TMouseButton;

Shift: TShiftState; X, Y: Integer);

  然后他这样赋值:

someobj.onMouseDown:=SomeobjMouseDown;

  当赋值以后,类内部其实是通过onMouseDown属性,将SomeobjMouseDown;与FonMouseDwon关联在一起,也就是说,MouseDown方法中调用了FOnMouseDown(Self, Button, Shift, X, Y);其实就等于调用了Procedure SomeobjMouseDown(Sender: TObject; Button: TMouseButton;Shift: TShiftState; X, Y: Integer);

  所以用户就可以在这个自定义的事件方法中写自己的代码,当事件发生时,该类的调度机制就会自动调用这个事件方法啦

  也许有人会问,为什么从消息处理函数要调用DoMouseDown,DoMouseDown又调用MouseDown,然后再调用事件方法呢。为什么不直接在消息处理函数WMLButtonDown中调用呢,其实它这样的做的目的是要进行一些保护判断,以及一些消息附加值的转换,使这些值看起来更加直观。

  好了,事件就讲了这里,不知道你们明白了没有,可能是我的表达能力不行,但没有关系,到真正做的时候,大家应该能明白了。

   四、组件制作步骤

  有了上面的基本概念,其实制作简单组件已经不是什么问题了,而要做真正的组件,还需要有一个正确过程,我们以后学做组件,也会顺着这个过程来做。主要如下:

  1, 确定一个祖先类。怎么确定,可以根据上面组件的简要层次结构来确定。如果你想做非可视化组件,可以从继承TComponent开始。如果想做可视要可视化组件,可以从TControl的子类开始。

  2 创建组件的单元,这个在制作组件时再说,不过是在IDE里面做几个操作而已。

  3 给组件写属性,方法,事件,成员,等。这些在上面己有详细说明,是写组件的核心部分,事实上也是后面实践的主要内容。

  4 测试,安装组件和写帮助,这个内容比较次要,后面的例子会讲怎么样安装,包括单个单元,或用包的形式安装。而写帮助,己超出范围,这里就不说了。

  关于组件基本概念就到这里讲完了,接下来就是实践了,有了上面的知识,实践起来也不是很难,很多东西都在上面了,而一些高级的特性,会在以后慢慢说的。

 

转自:http://www.yesky.com/186/1850186.shtml


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 开发笔记:spring boot项目打成war包部署到服务器的步骤与注意事项
    本文介绍了将spring boot项目打成war包并部署到服务器的步骤与注意事项。通过本文的学习,读者可以了解到如何将spring boot项目打包成war包,并成功地部署到服务器上。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • IhaveconfiguredanactionforaremotenotificationwhenitarrivestomyiOsapp.Iwanttwodiff ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
  • 接下来要动手来做一个组件了,我想了一个计数器组件,功能方面是比较简单的,但这不是本章的重点,这一章的重点是说明一个组件的制作全过程。在其中可以学到很多组件制作的技巧,当然这些也是我从书上学得的。 ... [详细]
  • 一、MyEclipse中的一些常用的快捷键:ctrl+shift+x大写ctrl+shift+y小写alt+内容提示写住方法的时候可以先写main然后按alt+就可以了ctrl+1 ... [详细]
  • 联系人:石虎QQ:1224614774昵称:嗡嘛呢叭咪哄*简单约束*CREATETABLEIFNOTEXISTSt_student(idINTEGERPRIMARYKEYAUTOI ... [详细]
author-avatar
End---的天空_808
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有