说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

DELPHI构件制作方法

HTML文档下载 WORD文档下载 PDF文档下载
DELPHI构件制作方法

Delphi作为RAD工具,以其快速编译和友好的可视化界面受到广泛欢迎。Delphi提供了很多现成构件,而且随着版本更新不断增加新构件。另外还可以买到第三方开发的特色构件,或从因特网下载免费构件。这些构件足以支持一般应用系统开发。但应用开发人员仍有必要自己制作构件。

采用构件形式可以把对象严密封装,并加上一层直观外壳,有利于软件调试和代码重用。开发群体以构件为功能单位分工协作,比较容易实现工程化管理,从软件规划设计到测试修改都可以减少意外差错,大大提高工作效率。成熟的构件还可以作为商品软件出售,带来附加效益,且有利于软件开发的社会化分工协作。Delphi的构件使用和构件制作采用同样的工作环境和相似的编程方法,只要弄清基本原理,制作构件无需学习多少新东西。

基本概念

制作构件的基本过程可以概括为:

1.编写构件单元(unit)。其中包含构件声明和构件实现代码。

2.按照与普通Delphi单元同样的方法编译和调试构件单元。

3.创建构件注册单元。其中用uses语句连接构件单元,并用Register过程完成构件的注册。

4.编写构件联机帮助信息,并编译成标准Windows帮助文件。

全部工作完成后,生成构件单元二进制文件(.DCU)、构件注册源文件(.PAS)和帮助信息文件(.HLP)及附加的关键词文件(.KWF)。用户拿到这些文件后,就可以安装使用了。在Delphi环境下调用菜单命令,启动安装过程(安装过程中需指定注册文件名),可以把构件注册到Delphi的VCL库中,并在构件工具条上生成一个新按钮。借助HelpInst安装工具可以把关键词文件并入Dephi帮助索引系统,用F1键实现联机帮助。

这样制作出的.DCU文件与一般Delphi单元没有根本区别,即使不安装到VCL库中也可以由其他单元直接调用。最大的区别在于:构件单元中某些属性和事件声明为published,从而在程序设计期对用户是可见的,用户可以通过对象编辑窗口(ObjectInspector)访问这些属性和事件。这是可视化程序设计的关键所在。

对象的继承与修改

制作构件第一件事就是选择适当的Delphi对象类型作为父对象,以派生新的对象。子对象可以继承父对象的全部非private部件,但不能摆脱不需要的部件。因此,所选父对象应尽可能多地包含子对象所需的属性、事件和方法,但不应包含子对象不需要的东西。

TComponent是所有Delphi构件的基点,但若直接从TComponent派生新构件,很多东西就需要自己从头做起。一般只有非可视构件才直接从TComponent派生。Delphi提供了若干专门用于制作控件(可视构件)的对象类型,都是从TControl和TWinControl派生而来。其派生关系如下:

TControl---TGraphicControl---TCustomLabel

TWinControl--TCustomControl---TCustomGrid---TButtonControl--

TCustomGroupBox---TScrollingWinControl--TCustomPanel---

TCustomComboBox---TCustomEdit---TCustomListBox

TControl的子类型用于非窗口式控件,TWinControl的子类型则用于窗口式控件。除非特殊需要,一般不直接从TControl和TWinControl派生新控件,而是从其子类型派生。这样可以充分利用原有的属性、事件和方法,减少很多工作量。

在这些构件类型中,非通用的属性、事件和方法都声明为protected。这样可以禁止构件用户访问,又能被子类型继承和修改。在新构件中,可以简单地把继承来的属性和事件重新声明为published,使构件用户能在设计期通过对象编辑窗口访问,也可以进而修改属性的默认值和读写方式,或是重载(override)事件处理子过程和其他构件方法,以修改其中的程序代码。重声明可以放宽访问权限,但不能相反,例如,不可能把published属性重声明为private或protected。

为了增加新功能,常常需要定义全新的属性、事件和方法。定义时,一般总是把对用户开放的属性和事件声明为published,把方法声明为public或protected。

构件属性

在构件中,属性和方法往往可以相互替代。对构件用户来说,属性比方法更直观简便。因此,只要可能,应尽量以属性取代方法。

属性类型包括简单类型(numeric,character,string)、枚举类型、集合类型、对象类型(例如font)和数组类型(例如TStrings类型中的Strings)。其定义方法如下:

type

private

FLayers:Integer;{内部存储用的变量}

functionGetLayers:Integer;{用来读属性值的方法}

procedureSetLayers(ALayers:Integer);{用来写属性值的方法}

published

propertyLayers:IntegerreadGetLayerswriteSetLayersdefault1;

end;

每个属性都需要相应的private变量用于内部存储。按照约定,变量名以F打头,后跟属性名(此处为Layers),读写方法名称分别为Get加属性名和Set加属性名。写方法总是带一个与属性类型相同的参数,用以传送属性值。此参数可以传值,也可以传递变量。如果不定义写方法(省略write部分),此属性便成为只读属性。读写方法应该在private部分声明,以使其对构件用户和构件的派生对象保持隐蔽。

读写方法除了取值和赋值之外,还可以附加其他操作代码,使属性读写产生附加效应。这正是属性可以取代方法的原因。如果不需要附加效应,可以不定义读写方法,采用直接访问格式来声明属性:

propertyLayers:IntegerreadFLayerswriteFLayersdefault1;

default命令符用来指定属性的默认值,同时需要在构件的构造函数中为属性设置初值。default命令的作用是在窗体文件存盘时提供参照:若属性当前值与default命令指定的值不同,则把当前值保存在文件中,否则便无需保存。如果省略default命令,属性当前值总是保存在窗体文件中。

事件与事件处理过程

创建构件时,事件也被当做属性来处理,区别仅在于事件必须定义为过程类型,使其成为一个隐蔽指针,指向某个潜在的过程。当构件用户为事件指定处理子程序后,事件便成为指向该子程序的指针。事件的定义方式如下:

type

private

FOnClick:TNotifyEvent;{声明事件变量以保存过程指针}

published

propertyOnClick:TNotifyEventreadFOnClickwriteFOnClick;

end;

此例正是Delphi标准控件中Click事件的定义方式。可以看出,除了OnClick被定义为过程类型外,其定义格式与一般属性的直接访问格式几乎完全相同。Delphi预定义了所有标准事件的过程类型及标准事件所引发的虚方法。其中,Click事件将引发如下虚方法:

procedureTControl.Click;

begin

ifAssigned(OnClick)thenOnClick(Self);

{以下是默认处理部分}

end;

其中,Assigned函数检验OnClick是否已分配了事件处理过程。如果返回值为True,则调用用户指定的事件处理过程。通过重载此虚方法,可以修改Click事件的处理方式。在重载的方法中,一般应先调用用户处理程序,然后再安排后续处理。在本例中,首行代码应当是inheritedClick。

需要注意的是,构件用户不一定会给事件指定处理程序,因此事件不能定义为函数类型,否则可能会指向返回值类型不定的空函数。如果需要事件处理过程返回某个值,可以借助var参数。调用用户程序之前应确保此参数包含有效返回值,以免用户未指定事件处理过程时出错。

如果Delphi标准事件不能满足需要,也可以自己定义事件。其核心思想是选择适当的Windows消息来引发构件中的事件过程。篇幅所限,不拟详述,请读者参阅有关资料。

方法处理要点

方法处理在创建构件时和使用构件时没有多大区别,但有些问题仍需要注意。

首先要注意的是,构件通常是在事件处理过程中调用,而构件作者又无法预测用户将在什么环境下如何调用构件。因此,构件中的方法应尽量避免占用系统资源,避免使Windows停止对用户操作的反应。

创建构件时应随时意识到,此构件不仅可以直接调用,而且可用来创建别的构件。即使是对用户隐蔽的方法也应具有完整的功能和清晰的接口。除了属性读写方法之外,内部方法一般应声明为protected虚方法,以便被派生对象继承和重载。属性读写方法则应采用private声明严密保护。派生对象如果需要读写父对象的属性值,应该访问属性本身,没有必要直接访问其读写方法。

构件测试

制作构件的核心工作是编写构件单元,包括根据构件功能要求设定对用户开放的属性、事件和方法,设定用以实现这些部件的变量、过程和函数等等。除了属性和事件有特殊格式之外,构件单元的设计方式与一般Delphi单元没有什么不同,只是单元中不能包含窗体。

在编写构件单元的过程中,可以借助一个测试窗体直接对其测试。以可视化方法在窗体上安排构件,本质上不过是自动生成调用构件的代码。即使构件未并入VCL库,无法使用可视化操作,也可以手工编写这些调用代码。这样测试,可以免去反复修改而导致的反复安装。

测试时,需先建立一个窗体单元,然后进行以下操作:

1.把被测构件单元名称加入窗体单元的uses语句中,并在public部分声明被测构件的对象实例。

2.在窗体单元的FormCreate子程序中调用被测构件的Create方法,以构造构件实例,其Owner参数设置为Self,即窗体本身。然后给Parent属性赋值,并适当设置其他属性值。Parent是容纳构件的父对象,如果是窗体本身,应设置为Self。

3.运行包含测试窗体的工程,找出构件程序中的错误。

注册构件

注册构件用的程序代码可以放在构件单元中,但在Delphi下注册构件时要求提供包含注册代码的源程序文件(.PAS文件),因此,比较好的方式是把构件核心代码编译成.DCU文件或.DLL动态链接库,在注册源文件中只放注册代码和外围程序。下面是注册代码实例:

type

TMyPanelΚclass(TCustomPanel)

TMyLabelΚclass(TCustomLabel)

procedureRegister;

implementation

procedureRegister;

begin

RegisterComponents(′Samples′,[TMyPanel,TMyLabel]);

end;

注册过程名必须是Register。过程体中调用Register Compnents,其中的两个参数分别指定Delphi构件工具条页名和要注册的构件类型。如果指定页不存在,Delphi将创建一个新页。

Delphi环境提供了一个构件生成器(componentexpert),可用来自动生成注册单元。

构件工具条上每个构件需要一个24×24点阵bitmap图标。图标可以借助Delphi的ImageEditor编辑生成,以.DCR资源文件的形式提供给构件用户,文件与注册单元文件相同。如果不提供此文件,Delphi将采用默认图标。

提供联机帮助

一个成熟的构件,无论是用于开发群体还是用做商品软件,都要有联机帮助信息才能正常使用。Delphi的帮助信息与Windows一般帮助信息结构基本上相同,其编写方法可参见有关资料。但Delphi包含一个特殊的帮助搜索引擎,能跨越多个帮助文件搜索关键词。因此,在构件帮助文件中不仅要有普通K型关键词脚注,还要包含Delphi所用的B型关键词脚注。脚注内容有如下约定:

在Delphi的对象编辑窗口和代码编辑窗口中,用F1键可以引发帮助搜索引擎,通过B型关键词调出有关帮助主题。为了实现这种帮助机制,需借助KeywordGenerate程序来生成关键词文件(.KWF),与帮助信息文件(.HLP)一起交给构件用户。用户借助HelpInst程序把关键词文件内容并入Delphi主帮助索引文件(.HDX)中。

构件联机帮助信息应当与Delphi标准构件帮助信息格式相同。编写帮助文件时最好遵循如下约定:

1.每个构件有一个单独的帮助主题(Topic),内容包含构件简介及用户可见的属性、事件和方法列表。

2.新增的及修改较大的属性、事件和方法均应有单独的帮助主题,其中应包含所属构件、用途、声明格式等内容。

3.每个帮助主题都应包含K型脚注,以便用F1键引发。

GitHub上线Trending功能,帮你轻松找到有潜力的开源项目 如私人秘书:谷歌搜索将变得更加个性化 微软将于10月17日正式发布Windows 8.1 Google推出在线教育C2C平台Helpouts 技术人员组团参加SDCC 2013的十个理由 继BAT之后 第四大巨头是谁 如果传统IT部门真的消亡,你该何去何从? 闪存突袭,混合储存是否已步入黄昏 Cloudera发布Hadoop开源组件Sentry:提供细粒度基于角色的安全控制 我从其他Shell脚本中学到了什么? 10个调试和排错的小建议 机器学习的时代来临,人类应该做点什么? 云端测试破1500万 Testin已为开发者省2亿 智能腕表inWatch:已发售近3600台 Bingo!微软证实Windows 8.1将捆绑安装Skype IBM宣布收购以色列网络安全公司Trusteer 约10亿美元 如何才能运作好一个开源项目? 为什么JavaScript有能力成为未来企业级编程语言? Red Hat CEO:拥抱开源 拥抱克隆 小米手机-HAXLR8on硬件黑客马拉松 开团了! 移动周报:雷军做红米的N个理由 Pangea Software CEO:08年App Store游戏降价大战的真相 揭秘MongoDB最新Java驱动:更好的JVM支持,指日可期的异步 不仅只有IE Mozilla将于发布Win8平台Metro版Firefox 360搜索发布新产品“我的搜索” 引入网民评价和网站名片功能 AppScale:Google App Engine的开源实现 近期十大优秀jQuery插件推荐 通过语音识别来编程 速度远超键盘 BrowserStack:多系统跨浏览器兼容性测试工具API发布 更加开放?Path向13家应用开发商开放API 重金力邀开发者 联想智能桌面应用开发大赛开幕 我胃口很大!!! VB能允许运行多大程序才不会出错? 哪里有D版,到哪里能买到D版的??? VB如何插入汇编程序代码?“=ASM:”吗?怎么用? 如何解决读英文书开头难的问题? 有没有打印Tdecisiongrid的孔件 日记 情归何处?? 谁知道哪里可以弄到这本书"Windows Graphics Programming: Win32 GDI and DirectDraw" 程序员杂志第7期的程序擂台目前为止只有一个人做对了 分数不高,还请各位DX们指点以下:如何用DELPHI控制excel的格式(比如第一列的宽度,第五行的高度),以及如何在WORD中生成表格,其中填入数据库的数据. 各位情感高手请解答(没有谈过恋爱的免谈) 一个list控件,style设为checkbox,要怎样才能使列表中各项的默认值是选中状态,也就是说各项一开始都是打了勾的 阿虎菜问7:请问C与C++中的内封函数应该差不多吧? s_cube(竹子), s_cube(竹子)~!! 我爱你,s_cube(竹子) s_cube(竹子) ~!在哪里 简单问题(1) 如何不运行编译? 有谁知道怎么从perl里调用一个c库里的函数????????? 请问在CB中如何隐藏WINDOWS的任务栏呢? 今天不爽,下班后打星际,大家一起来。 指点!在PB中怎样用程序作成一张动态的交叉表 编辑控件怎样才能显示那些怪字符? 有没有人喜欢郑智化 大家推荐好听的几首歌吧! 请教:怎么学c++? 高手点拨! 各位网络高手.如何在程序里讲ip地址转化为域名 有什么方法,可使表单内的组件背景变成透明的而文字不透明,请看例子: 编辑控件怎样才能显示那些怪字符???? swall(壹心) 你还在深圳特区吗? 如何设置Session的密码?请高手指点迷经^^^^^ 哪位可以解释一下下面的代码? perl 的人气太差。罢了罢了。找本perl自己搞定 MsSQL7.0 当日志文件大小未限制而变得很大时,怎样清日志文件,使其减小? 请教诸位牛兄牛姐牛夫人---有难度哦(着急出活!) 基本问题:如何将一个.txt中的内容读入到内存再从内存中读出并存为另一个文件?谢了先!!!! 高手帮帮忙!!!!!!!!!!!!!! 又有台风了。。。。 在zip包中加入ASP推荐的PAD File有用吗????? PB连接SQL数数库,为什么显示的表会不全 如何把一个文件file.dat里的数据写入软盘0磁道0磁头1扇区. 我要骂人! chris2001(牛虻),不是东西 华为工程师 谁知道 vb 的序列号?????? VS.NET 有开了个新铺子。为什么我的ejb/j2ee还没有开张。气愤。 老大们:我是菜鸟,有问题要问,不过不要笑我。一定给分的 再次发问:关于在SQL SERVER中的某张表上建立触发器...... 没有有这样的病毒,或者文件 各位老大,如果有asp、sql基础学jsp和php是不是比较容易一些呀?言者有分哦! dll中怎样调用主程序中的函数? 新手请教接口聚合!!!!!!!!! 把一根温度计浸入热水中,温度计的水银为什么先下将后上升 为什么,在焓湿图上,干球温度35度,湿球温度23度和干球温度30度,湿球温度23度的焓是一样的呢? 含水率98%的污泥怎样换算为含水率80%的污泥 怎么样正确使用水银温度计可以手拿另一头给宝宝试热吗?可以放在她的脖劲下试热吗? 如何使用干湿计测量空气的相对湿度 含水率反算公式,我只知道试验前重量和含水率,求试验后重量. 水银温度计在使用中有哪些缺陷 干球温度低的空气其焓值小于干球温度高的空气的焓值.请问这句话是正确的吗?如果不对,请问为什么呢? 绝干污泥量怎么计算的?一般绝干污泥的含水率多少?有机质含量等参数? 太空中能否使用水银温度计失重状态下能否使用水银温度计 在一定大气压力和空气湿度下,从湿空气焓湿图上所查得的湿球温度是否与露点温度是一个概念? 已知:剩余污泥总量为737kg/d,剩余污泥含水率按99%计算湿污泥量为183m3/d.请问计算公式是什么?我要算的是2788kg/d为多少湿污泥量? 水银温度计宝宝刚才把水银温度计放在嘴里咬碎了 我晕 不知道有没有吞到嘴里去 怎么办啊 急 焓值的计算公式 什么是熵,什么是焓,单位是什么? 用水银温度计是因为水银是. 焓变怎么计算书上写的都是化学式+化学式=化学式,后面写上焓变的值,那是怎么算的.请认真回答. PC的单位热流量是多少?质量焓是多少? 水银温度计怎么测都看不见有水银啊是新买回来的我之前买了几个都是看不见有水银怎么回事啊 怎样算化学的焓变值? 焓是什么,它的单位是什么? 水银温度计怎么看 焓变的计算式好像有两种计算式,一种是ΔH=E生成物总能量 - E反应物总能量另一种是ΔH=E反应物的键能 - E生成物的键能能不能具体解释下这两种计算式原理,为什么这样计算,说具体点 水头损失里面的水头是什么意思?水头损失是能量损失,水头是焓值?单位是什么 怎么看水银温度计 焓值 一个标准大气压下饱和液氮的焓值是多少? 焓值的计算公式? 焓变单位的含义 怎样看测试体温的水银温度计的水银有没有跑出来? 焓变!问题解题思路!求助,谢谢 焓变的单位中每摩尔的含义是什么 水银温度计怎么看求图 焓变怎么求像这样的方程式,2Fe(s) + 3Cl2(g) ==2FeCl3(s),然后求焓变,具体是怎么求出来的?公式怎么用?或者H2(g)+1/2O2(g)==H2O 最后是-241.8KJ/MOL-RXN...这个数字是怎么出来的? 焓变的单位为什么焓的单位要加一个每摩尔,H不是等于Q么 蒸馏装置中,温度计的水银球应位于什么地方?作用是什么? 已知湿球温度和干球温度,大气压强,如何求含湿量d?如题,应该在焓湿图上查得出的,我想知道怎么查,不要公式,因为不知道定压比热没法算.求解!我只记得查相对湿度为100%的那条线,但是按干球 焓与焓变二者之间的区别 水银温度计在装热水的杯子里爆了偶然,老婆把水银温度计放在有时炒菜时加水的杯子里,当时里面装的开水,结果温度计爆裂了,家里老人家觉得没什么就倒到下水道去了,然后只是用洗洁精清 什么是湿空气,含湿量和相对湿度的定义是什么? 焓变符号的含义 为什么水银温度计放在热水里,示数会先下降再上升?玻璃泡的变化会那么明显吗?有没有什么资料可以找给我看一下? 如何根据空气温度、相对湿度计算含湿量g/Nm3?例如:空气温度32度,相对湿度83%,如何计算g/Nm3?通常可知含湿量为25.22g/kg,请问如何折算成g/Nm3?谢谢了,Nm3是指标准立方米(1个大气压,20摄氏度), 键能跟焓变的符号怎么一样阿 ΔH=生成物能量-反应物能量ΔH=反应物键能总和-生成物键能总和 怎么回事 ΔH不是只表示焓变吗 而且怎么一个是生成物-反应物 一个是反应物-生成物 将一支灵敏温度计的玻璃泡浸入热水里,并立刻观察温度计细管里的水银面的高度变化,将会看到温度计中水银面下降,然后再上升.试说明其道理. 已知温度 露点 气压 求相对湿度 反应热通常用符号Q表示,与焓变△H有什么区别? 将一支灵敏温度计的玻璃泡浸入热水中,为什么细管内的水银面先下降再上升? 关于干球温度计,湿球温度计的问题我有一个疑问,假如湿度越大,那湿球温度计所沾上的水分就越多,那么蒸发的水分就越多,吸热,制冷就越多,湿球温度计的示数就越小,干湿度差就越大,那就相 通常焓变与熵变在化学反应中的符号是相同的,请问这是为什么? 两只内径不同,下面玻璃泡内水银量相同的合格的温度计,同时插入一杯热水中,过一会儿则看到( )答案是(D)为什么呢?A.两只温度计水银柱上升的高度相同,示数相同 B.内径细的温度计水 如何根据空调冷凝器的空气进口干球温度计算出空调的冷凝温度手头上现有一台冷凝器的换热器,各个尺寸参数都已经知道了.现在要对该换热器做实验,按照国家标准,空气进口干球温度取35度, 七水硫酸镁的标准摩尔生成焓是多少?计算方法是什么? 温度计接触热水,水银为何先下降后上升 高中有机化学里各个需要温度计的实验中温度计水银球的位置分别在哪里还有没有?还有没有啊? 有关标准摩尔生成焓标准摩尔生成焓规定由最稳定的单质生成时的焓变有些单质 如氧化银(ag2o) 不能由氧与银直接得到而臭氧可以与银反应 但不是最稳定的氧化银的标准摩尔生成焓怎么测 当将水银温度计放入热水中时,会看见水银柱先是下降再上升,为什么? 有一种测量空气湿度的温度计 所示 它是由两支相同的温度计组成的 其中一只温度计正处于空气中另一只温度计乙的玻璃泡浸在潮湿的海绵中 将其放在室内 其中 的示数小 这是因为 .两示数 焓变公式是什么?关于ΔH的所有公式.我都忘没了···.比如温度是300度时候,H300怎么求?还有H''和H'都是什么意思啊?我全忘了····,我高中东西忘没了·· 用温度计插入热水中测量热水的温度时,为什么开始时水银柱略微下降,然后在上升?分析是什么原因? 空气干球温度为27℃,湿球温度为19.5℃,空气湿度为多少?怎么计算? 求助饱和蒸汽焓的计算公式,详细的计算公式
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn