如何用Delphi编写自己的可视化控件

如何用Delphi编写自己的可视化控件,第1张

可视化控件(Visual Component)实际上就是一个类(class) 要编写一个类 可以直接在* pas文件中编写 但是要编写控件 则必须使橘陆陆用包(package) 从File菜单中选择New 新建一个Package 这就是存放和安装控件用的包 然后单击Package窗口中的Add按钮 添加一个元件(Unit)

在d出的对话框最上方选择New Component 因为一个控件的所有属性 方法 事件不可能都由自己编 所以就需要选择祖先类(或者叫做 父类 或 基类 ) 然后再在其上面添加自己的属性 方法 事件 在Ancestor type后的下拉框中选择所需的祖先类 由于编写可视化控件必须要画图 所以选择TGraphicControl作为祖先类 再在Class Name框中输入新控件(类)的名称 一般以 T 开头 Palette Page是用来选择新控件在Delphi的窗口中的控件页面名称 例如 Standard 这个可以自己取 在Unit File Name中添好新控件文件的路径及文件名 单击OK按钮 新的控件便加入了 现在可以为该控件编写代码了

下面以编写一个可以自定义图片的滚动条为例 说明编写可视化控件的方法 按照上面的方法 选择TGraphicControl为祖先类 新控件的名称是TPigHorizontalScroller (小猪水平滚动条) 选择好文件路径和文件名后 单击OK按钮 开始编写代码

每一个控件 都会被创建(Create)和删除(Destroy) 所以必须首先编写这两个过程 对于控件中的每一个过程 都必须在前面先定义 然后再在后面编写 定义的过程或属性有三种 (1)在private后定义的是属于控件圆顷内部使用的 使用该控件的人无法看到 (2)在protected后定义的一般是看不到的 只在别人使用该控件作为祖先类编写其它控件时才可见 (3)在public后定义的只允许别人在程序中调用 (4)在published后定义的可以在属性窗口(Object Inspector)中看到 由于创建和删除过程除了在编程过程中建立控件时自动执行外 还可能在程序运行过程中动态创建控件时被调用 所以把它定义在public后⑴ (该序号表示次步骤在所附源程序中的代码的位置 下同)现在也许还不知到应该在这两个过程中编写什么 如何去编 我们在下面将会讲到

我们首先为这个控件添加一些属性 我们定义一个Max属性用于设置或读取滚动条的最大值 因为在程序中一般不直接使用属性 所以要定义一个变量 和该属性对应起来 一边修改或读取其值 因为它只在控件内部使用 所以我们把它定义在private后⑵ (一般与属性相关联的变量都以 F 开头 例如FMax)定义好变量后 再定义属性 这个属性需要再Object Inspector窗口中可见 所以把它定义再published后⑶ 定义的语法是

property <属性名>:<类型>read <读取该属性时对应的变量>write <写入该属性时对应的变量或过程>

其它的变量和属性也类似的定义(例如Min最小值 Value当前值等) 下面我们定义几个属性和变量 用于设置滚动条的图片(因为图片变量比较特殊 所以单独讲一下) 我们把LeftButtonUpPicture(向左按钮图片) LeftButtonDownPicture(向左按钮按下图片)等定义为TBitmap类型(一定要定义相对应的变量)

大家一定注意到了 在所附的源程序中悉橡 定义这几个属性时 read后所指定的读取属性时对应的变量是F… 而write后指定的写入该属性时对应的不是一个变量 而是一个Set…之类的东西 这是一个自定义的过程 作为该功能的过程的定义为

procedure <过程名>(Value: <被设置的属性的值的类型>)

因为执行写入该类属性的时候需要做其它的事情 所以不能光用一个变量来处理 应该用一个过程来处理 这中过程一般定义在protected后 在该类过程中 使用一个在⑷处这样一个语句来给TBitmap类型的变量来赋值 这是由于该类型的变量不能直接赋值而采用的

定义完这些TBitmap类型的变量的属性后 上面讲的create过程和destroy过程中就需要编写代码了 因为TBitmap也是一个类 所以在create过程中必须创建⑸ 在destroy过程中必须释放掉(free)⑹ 这里⑺所指的inherited语句是用于指明该过程是从祖先类类中继承来的 (这个一定不能掉)

因为我们编写的是可视化控件 所以必须在控件上画图 我们这个控件的祖先类TGraphicControl中封装有一个Canvas(画布)对象 我们可以直接使用它来画图 如果你对画布的使用还不太熟悉 最好去找一本书来看一看

下面要做的工作就是画图了 如何在控件上画图呢?祖先类TGraphicControl中有一个Paint事件 当控件需要重画时便会自动触发 我们现在要做的就是要为这个事件编写一段程序 首先在protected后定义一个Canvas对象 由于它是祖先类中已有的 所以不需要加任何说明⑻ 我们将使用这个对象来画图 接着 就要定义一个Paint过程 编写绘制控件的代码 先在public后定义Paint过程 由于它是由祖先类触发的 而不是由用户调用的 所以后面必须加上override 否则 该控件将会由于Paint过程永远不会被调用而不成为可视化控件⑼ 下面我们就来编写Paint过程的代码⑽

该文章所附的源程序的Paint过程中的T_Height等变量是用来保存滚动条中按钮 滑块等的大小的 这部分程序和普通的Application中的程序差别不大 大部分都是对画布进行 *** 作 相信大家一看就明白 值得注意的是下面对FAutoSize变量的判断⑾ FAutoSize是和该控件的属性AutoSize相关联的布尔型变量 是用来设置这个控件的大小是否随图片的大小而变化的 注意 在控件的代码中 一般都不直接调用属性 而是使用与其相对应的的变量

程序编到这里 就算是终于给自己的新控件做了一个外型了 不过它还不能滚动 现在我们来编写鼠标事件 让我们能够 *** 纵它 鼠标事件的过程的定义和Paint过程很相似 只是后面要加上参数说明⑿ 鼠标事件分为MouseDown MouseMove和MouseUp三个 在定义后面都要加上override 接下来在后面编写它的代码 注意 这里的鼠标事件是Mouse… 而不是通常的OnMouse… 可是在⒀处的定义是干什么用的呢?这里的事件定义 都是给用户使用的 也就是说 当使用该控件时 会在Object Inspector中的Event页面中显示出来

这些鼠标事件的代码也非常简单 判断鼠标的坐标 在画布上画出相应的图片等 并同时触发相应的事件 值得注意的是 在调用自定义事件时 都要先用⒁处的这样一个语句来判断用户是否已经为该事件编写代码 这一点非常重要 否则会调用出错

大家注意到了 刚才所调用的事件都是自定义的 定义的方法也很简单 和定义属性差不多 只是类型时TNotifyEvent罢了  

TNotifyEvent是默认事件 其定义为

TNotifyEvent = procedure(Sender: TObject)

如果你要定义另外形式的事件 就必须这样 先在type后编写

<事件类型名称>= procedure(<参?gt:<类型>)

例如

TCustomEvent = procedure(a: Integerb:String)

然后在public后定义

<事件名称>:<事件类型名称>

例如

AnEvent: TCustomEvent

看完这些 这整个程序你应该理解了吧 如果编译或运行出错 注意检查以下几点

(1)create和destroy过程中是否有inherited语句 (2)TBitmap类型的变量create和free了没有 (3)过程前有没有控件名 例如 TPigHorizontalScroller MoseMove

判断鼠标是否进入或离开控件的方法

定义如下的过程

procedure MouseEnter(var Msg: TMessage)message CM_MOUSEENTERprocedure MouseLeave(var Msg: TMessage)message CM_MOUSELEAVE

lishixinzhi/Article/program/Delphi/201311/8448

对象:是一件事、一个实体、一个名词,是铅段御可以获得的东西,可以想像有自己的标识的任何东西,是类的实例化

控件:窗体槐岩中的组件,也可以理解为工具

属性:对象的特燃正性,可以描述的特性

事件:对象对外部动作进行的响应

过程:C#中没有过程的概念,你要问的应该是方法:

方法:特殊的子程序,用于完成一定的 *** 作

一个控件可以理解为同一类中的一个对象,不同的控件有不同属性、事件和方法


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8269500.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存