组件制作之一(概念)

为国办事真难

为国办事真难

2016-02-19 12:48

get新技能是需要付出行动的,即使看得再多也还是要动手试一试。今天图老师小编跟大家分享的是组件制作之一(概念),一起来学习了解下吧!
作为组件制作的开始,应该了解一些概念,我以为这些概念是非常重要的,将可以作为以后实践的理论基础。
  
  ?
  
  一,?组件的简要层次结构。一般情况下,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?FCountvalue?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测试,安装组件和写帮助,这个内容比较次要,后面的例子会讲怎么样安装,包括单个单元,或用包的形式安装。而写帮助,己超出范围,这里就不说了。
  
  ?
  
  关于组件基本概念就到这里讲完了,接下来就是实践了,有了上面的知识,实践起来也不是很难,很多东西都在上面了,而一些高级的特性,会在以后慢慢说的。
  
  ?
  
  下一篇是做一个简单的组件,其实只用到了这里讲到了一些基本原理,而最重要的是给出了一个完整的组件制作过程。到了以后难度更大的组件,则重点会在代码的实现上,其他则从略了
展开更多 50%)
分享

猜你喜欢

组件制作之一(概念)

编程语言 网络编程
组件制作之一(概念)

HTML组件(HTML COMPONENTS)之一

Html CSS布局 Div+CSS XHTML
HTML组件(HTML COMPONENTS)之一

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

Enterprise JavaBeans组件慨述之一

编程语言 网络编程
Enterprise JavaBeans组件慨述之一

XML轻松学习手册(3)XML概念之一

Web开发
XML轻松学习手册(3)XML概念之一

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

组件制作之二(一个简单组件的制作过程)

编程语言 网络编程
组件制作之二(一个简单组件的制作过程)

基于Delphi的组件设计之概念

Delphi
基于Delphi的组件设计之概念

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

以最少的资源耗用显示系统键状态

以最少的资源耗用显示系统键状态

改变Windows的缺省打印机

改变Windows的缺省打印机
下拉加载更多内容 ↓