组件制作之一(概念)

2016-02-19 12:48 8 1 收藏

get新技能是需要付出行动的,即使看得再多也还是要动手试一试。今天图老师小编跟大家分享的是组件制作之一(概念),一起来学习了解下吧!

【 tulaoshi.com - 编程语言 】

作为组件制作的开始,应该了解一些概念,我以为这些概念是非常重要的,将可以作为以后实践的理论基础。
  
  ?
  
  一,?组件的简要层次结构。一般情况下,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测试,安装组件和写帮助,这个内容比较次要,后面的例子会讲怎么样安装,包括单个单元,或用包的形式安装。而写帮助,己超出范围,这里就不说了。
  
  ?
  
  关于组件基本概念就到这里讲完了,接下来就是实践了,有了上面的知识,实践起来也不是很难,很多东西都在上面了,而一些高级的特性,会在以后慢慢说的。
  
  ?
  
  下一篇是做一个简单的组件,其实只用到了这里讲到了一些基本原理,而最重要的是给出了一个完整的组件制作过程。到了以后难度更大的组件,则重点会在代码的实现上,其他则从略了

来源:http://www.tulaoshi.com/n/20160219/1602015.html

延伸阅读
标签: Web开发
本文配合免费下载的Kaxaml 工具,演示XAML 的一些基本用法。关于Kaxaml 工具的介绍和下载,请参考文章:推荐一款免费下载 XAML 编辑调试工具-Kaxaml。 XAML 系列文章为学习笔记,这是我今年春节期间安排的学习任务。 StackPanel、Menu、Expander 元素的演示 Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/prese...
本文是TC的第一部分,主要介绍一些TC相关的基础知识,并着重针对循环、变量等TC基本概念中的易混的淆部分加以辨析,即是一份编程初学者的指南,也可算作是对《C how to program》的一些补充。 在正式进入编程部分之前,让我们先详细了解一下Turbo C的编译环境,以便在编程时可以更加得心应手。 File菜单 Pick--快速读取最近的9个...
标签: PS PS教程
1. 快速打开文件 双击Photoshop的背景空白处(默认为灰色显示区域)即可打开选择文件的浏览窗口。 2. 随意更换画布颜色 选择油漆桶工具并按住Shift点击画布边缘,即可设置画布底色为当前选择的前景色。如果要还原到默认的颜色,设置前景色为25%灰度(R192,G192,B192)再次按住Shift点击画布边缘。 3. 选择工...
标签: ASP
  @CODEPAGE 可以使用 @CODEPAGE 指令为 .asp 文件设置代码页。代码页是一个字符集,包括数字、标点符号及其他字符。不同的语言和现场 用不同的代码页。例如,ANSI 代码页 1252 为美国英语和大多欧洲语言所使用,而 OEM 代码页 932 为日本汉字所使用。 代码页可表示为一个字符到单字节值或多字节值的映射表。许多代码页都共享在 0x00-0x...
标签: Java JAVA基础
JSP和SERVLET到底在应用上有什么区别,很多人搞不清楚。我来胡扯几句吧。简单的说,SUN首先发展出SERVLET,其功能比较强劲,体系设计也很先进,只是,它输出HTML语句还是采用了老的CGI方式,是一句一句输出,所以,编写和修改HTML非常不方便。 后来SUN推出了类似于ASP的镶嵌型的JSP,把JSP TAG镶嵌到HTML语句中,这样,就大大简化和方便了网...

经验教程

887

收藏

21
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部