在开讲之前,首先,我假设你了解什么是面向对象,什么是类。如果不了解的话,建议先去了解一下相关知识!
在Delphi中,组件,我们可以将它理解为一个个的封装好了的功能对象库,使用这个库,就只用简单的几句代码,甚至仅仅简单的设置几个属性就能实现某些功能,我们可以将组件想象成日常生活中使用的某些工具,比如说收音机,我们不必了解其内部构造,只用在播放器上点一个收听按钮就能收听广播。其实这不仅仅是Delphi组件,Delphi的中的各种对象库都是如此,比如TStingList,只用简单几句代码就能实现一些功能,组件与对象库本质相同,唯一不同的就是组件通过Delphi的IDE接口注册到了IDE中,可以进行可视化的设计,而其他的对象库,需要我们手动创建,然后调用!
上面简单阐述了一下Delphi的组件的某些特性以及与其他对象库的一些区别。下面,咱在说说Delphi的组件的构造层次,说到这个类的层次,有一个非常有名的Delphi对象层次图的(但是我不晓得在什么地方了,有兴趣的可以自己搜搜看,不看也不影响下面的讲解说明)。上面说了,Delphi的组件其实也是一个对象库,也就是一个类,在Delphi中所有对象的基类都是TObject,组件的最最最基类也是TObject,这里有一个来源于网络的不完整的类结构图
这个结构中组件的类层次用黑色粗体标记出来了,也就是
TObject---------->TPersistent------------>TComponent------------->TControl
TControl又继续分支
TPersistent这个类,这个类是一个可持续化的对象库,只要从这个类继承下来的,都自动具备了串行化的功能,可以非常方便的读入与写入到流,这个特性就方便了组件中的属性信息能非常方便的记录到窗体资源文件。
TComponent这个就是所有Delphi组件的基类,所有想要注册到IDE直接进行可视化设计的对象库,都要从这个类继承。TComponent提供了必不可少的信息以使组件能够在Delphi的IDE上运作。然后TComponent下衍生出了TControl的类,这个类就是所有的在运行期间可视控件的基类,比如Label,Panel等,只要从TControl继承下来,就能实现运行期间可视化。如果直接从TComponent向下继承的话,那么在运行期间就不可见了,比如说TTimer等。
TControl类,从图上可见,从他开始又有了分支了,分了TGraphicControl,TWinControl。先说TWinControl,TWincontrol就是Windows控件库的基类,这个类封装了大部分Windows的消息响应以及创建参数。再来看TGraphicControl,这个是个特殊的控件基类,也就是Label,Image等控件库的基类,其实,他本身不算是一个Windows的控件,而是依托于Windows控件之上的一块区域,所有的消息信息都由他所依托的Windows控件(也就是他的Parent)来响应,然后分派出来,之后他本身才响应这些消息(比如说,TImage控件创建的一个图片显示控件Image1,它的Parent是Form,那么他的MouseDown,MouseUp,MouseMove等消息的响应,实际上是当这个图片控件创建了之后,它的Parent就指定了一块区域是属于用来显示那个图片的,当鼠标在Form上移动,移动到那个区域的时候,就给TImage派发一个MouseMove消息,于是这个消息就响应了,鼠标按下与鼠标弹起消息也都是如此),从TGraphicControl继承过来的组件,它内部都有Canvas画布属性,其实,这个Canvas在大多数时刻实际上是用的它的Parent的Canvas,也就是说他的Canvas与GraphicControl.Parent.Canvas是同一个设备场景,那么为什么是大多数时刻,而不是任何时刻,且听我慢慢说来!其实也是在任意时刻都是Parent的canvas,不过那个任意时刻是有条件的,也就是在那个组件的实现内部,开放给用户使用的Canvas就未必是Parent的Canvas了,这个最典型的列子就是TImage这个控件了,TImage开放给我们使用的Canvas实际上是一个TBitmap的Canvas,而其内部的Canvas并未真正开放出来,而仅仅是作为将图片绘制到Parent的设备场景上使用。所以此时,我郑重指出,TGraphicControl实际上是一个虚拟的界面控件,本控件不具备句柄,切莫在未给它指定Parent的情况下,试图去使用引起控件重绘等消息的方法,比如Invalidate等。
从TwinControl继承下来的控件,都是具备有控件句柄的,也就是在Windows内部具备有唯一标记,能动态索引找到的。
TScrollingWinControl就是具备有滚动条的,Form就是来源于此。
TcustomControl这个就是通常给咱使用来开发继承新的控件地。
在创建组件之前,我们需要明确,这个组件是可视的组件(运行期间可见)还是非可视组件,如果是可视的组件,那么我们就要从TWincontrol或者TGraphicControl继承一个新的对象类来实现,如果是非可视的组件,那么我们就从TComponent继承来实现,至于为什么,上面已经说了。由于在开发组件的时候,各个人的水平层次不一样,然而创建一个新的组件,都需要创建一个新的对象类,所以此时各人根据各人的需求和能力做不同的构造,能力需求点不一样,创建方式也可能不同,一般新手,建议采用向导,找到菜单中的Component那个菜单,然后选择第一个菜单NewComponent,就能打开这个新建控件的向导,这个向导中列出来了Delphi的组件库中的所有组件,根据自己的需要选择一个你需要扩充的控件或者选择TComponent或者TCustomControl创建您的新组件。创建好了之后就能进行组件的扩充与编写了!
休息一下,敬请期待下一篇,简单扩充TEdit
由于个人水平有限,文中,难免有纰漏错误之处,欢迎各位大虾拍砖指正!