有关delphi 重启服务语言重启验证的问题?

您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
Delphi培训课程.doc27页
本文档一共被下载:
次 ,您可免费全文在线阅读后下载本文档
文档加载中...广告还剩秒
需要金币:238 &&
你可能关注的文档:
··········
··········
delphi基础
【例】改变窗体的标题,颜色,尺寸
  delphi 程序设计特点:可视化,开发方便
【例】写代码,改变标题,颜色,尺寸
  对象成为处处用到的基本元素。对象含有属性和事件。delphi以pascal语法为基础。
一、delphi是什么?
Delphi 是borland 公司研发的面向对象的,可视化的,快速的应用开发工具。
  ◇对象是对相对独立的客观存在或相对独立的逻辑存在的计算机表示。
  ◇面向对象是与面向过程相比较而言的。
对象的三个主要特征:封装、继承和多态。
面向对象的优点:易管理,可重用。
可视化的体现:
所见即所得的界面设计;delphi组件是可视化的对象。
快速的原因:
可视化;丰富的函数,类库,组件,数据库组件;开发工具和向导;编译速度最快,语法的高度最一致。
二、delphi不是什么?
1 不是专门的数据库开发工具。
◇研发的的背景和目的:windows初步流行,主要开发工具VC和VB各有所长;数据库开发的需求急剧增加。Delphi
VC功能+VB界面+快速数据库开发。
◇delphi中没有专门为数据库操作保留的关键字。
◇有很强数据库能力的原因是使用Delphi后续开发的数据库组件。
 【图解】delphi语言及开发包提供的资源的关系。delphi的语言基础是object pascal,在其上构建的函数库,类库,控件库,甚至是IDE本身都不是语言的固有组成部分,而是用delphi语言写成的第一批工具,这扩展了delphi的能力,也验证了delphi的强大功能。
2 不是专门的界面开发工具。IDE本身是delphi程序且提供源代码;delphi可脱离IDE环境
而独立运行。
  3 Delphi 可用于各种通用目的。通信,图形处理,数值计算,自动控制等。
三、学习基本语法前的
正在加载中,请稍后...Delphi 元件撰写常问问题
译者: 陈宽达 原作者 :John M. Miano
第一部分 简介
第二部份 ""合环境
第三部分 在元件中使用其它元件
第四部分 Bound Controls
第五部分 VCL
第六部分 其它资讯
第七部分 元件的储存与载入
第八部分 工具程式
第九部分 基本程式设计技巧
第十部分 进阶程式设计技巧
第十一部分 元件虚拟方法
第十二部分 Windows API
第十三部分 控制项边框
第十四部分 控制项式样
第十五部分 视窗讯息
第一部分 简介
1.1 此份文件的目的为何?
这份文件的目的是为了解答有关撰写 Delphi元件时常见或文件上找不到的问题。我曾
经花了一段很长的时间来了解探索 TDataLink 类别,这让我觉得应该将撰写元件时常
遇到的问题及经验心得写下来,分享给大家。不过我并不能保证写在这份文件里头的
解答完全正确。如果你对其中的任何问题有更好的解决方法,或认为有什麽资讯适合放在这份文件里
的话,请告知作者。有任何错误或缺漏也欢迎指正。
除了再加上更多的问题及解答外,我试著再补充两个部分:
进阶程式设计师喜爱的工具:这也许跟元件设计没有直接的关系但至少它们跟
Delphi有关系。
值得参考的文件刊物:由於空间的关系,这份文件不能放置太多的范例程式,因
此参考其它文件是十分需要的。这不是一份教材式的文件,我不会做太多条理式
的说明,但会试著将最具有参考价值的文献列出。
如果你有任何意见或建"",欢迎来信告诉我。
第二部份 ""合环境
<FONT COLOR="#.1 在""合环境中如何找出元件所产生的问题?
我发现唯一能找出问题的方法只有:
在 Delphi ""合环境的 Tools|Options 对话框的 Library
页中将『Compile with debug info』选项打勾。
选 Component|Rebuild Library 重新编译元件库。
从 Turbo Debugger 中执行 Delphi。
选File|Change Dir移至包含元件程式码的目录下。
如果你的元件发生GPF时就可以检视堆叠然後得知到底是哪些发生问题了。
<FONT COLOR="#.2 如何检视 Delphi 所产生的组合语言码?
Glen Boyd 的回答:
开启登录编辑程式(REGEDIT.EXE),接著到『HKEY_CURRENT_USER\Software\Borland\Delphi\2.0\Debugging』下新增一个字串机
码『EnableCPU』,将它的字串值设为『1』。此後Delphi""合环境的View选单下就会
多一个『CPU』选项,它会开启一个视窗来检视目前程式指令的记忆体及组合语言。你
可以在侦错时利用单步追踪或其它方法来观察它。
<FONT COLOR="#.3 我可以在执行时期动态建立元件,但在设计时期就会发生错误。为什麽?
你的元件必须继承自TComponent类别或其衍生类别。
你的元件建构函式及灭构函式宣告必须看起来像这样:
constructor
Create(AOwner: TComponent); override;
destructor
D override
所有在published区段宣告的栏位型态必须是ordinal、single、double、extended
、comp、currency、string、small set(译注:指元素编号不超过0..31这个范围
的集合;平常的集合可容许的范围为0..255)、method pointer或class其中一种。
如果你宣告了其它型态的栏位,Delphi编译器并不会检查出错误。然而当你使用这
个元件时依然会得到一个GPF。
如果你想让TMyComponent元件可以在设计时期操作,注意下面的宣告会引发十分严重
type TComplex
RealPart: D
ComplexPart: D
class TMyComponent
= Class(TComponent)
property P1:
TComplex read
<FONT COLOR="#.4 如何撰写一个无法放置到表格上的元件?
Ray Lischner 的回答:
如果你不想让使用者将元件拉曳至表格上的话,使用
RegisterNoIcon 及 RegisterClass 程序来注册元件。
<FONT COLOR="#.5 在程式码编辑器中快速切换程式区段最简单的方法是什麽?
Ray Konopka 的回答:
在探索 VCL 原始程式码时,强烈建""你最好熟悉程式码编辑器里的书签功能。使用方法
很简单:Ctrl-Shift-N,N 是从 0 至 9 的数字,用来设定一个书签。此後就可以使用
Ctrl-N 来跳跃至书签处。(译注:使用这项功能真的可以节省你许多来回卷动程式及
找寻函式的时间,别迟疑了,快学吧!)
<FONT COLOR="#.6 如何使我的元件在按下滑鼠右键时出现快速功能选单?
你必须要建立一个元件编辑器。元件编辑器决定了元件在设计时期时对滑鼠键的反应及动作,你可以为元件定义它自己的快速功能选单。
建立元件编辑器的步骤大致如下:
从 TComponentEditor 类别继承一个新的类别。
改写类别的 GetVerbCount、GetVerb及 ExecuteVerb方法。
在 Register 程序中使用 RegisterComponentEditor
程序来注册此元件编辑器。
有关元件编辑器这个主题在『Developing Delphi Components』这本书中有详尽的解
说及资讯。
<FONT COLOR="#.7 为什麽元件在设计时期会出现『I/O
103』的错误?
你可能在元件中使用了Writeln这个程序。
<FONT COLOR="#.8 为什麽元件编辑器不会将元件属性的变动储存起来?
我发现有时自制的元件编辑器不会将元件属性储存起来。设计时期一切正常,但是储
存起来再重新读入後就有问题了。
原因是你很可能忘了在元件编辑器中呼叫此方法:
Designer.M
如此一来Delphi才会知道你的元件编辑器更改过属性值了。
第三部分在元件中使用其它元件
<FONT COLOR="#.1 如何在元件中加入卷轴元件并让它在设计时期能动作?
你的卷轴元件类别必须处理 CM_DESIGNHITTEST 元件讯息才行。
TMyScrollBar = class
(TScrollBar)
CMDesignHitTest
Message: TCMDesignHitTest); message
CM_DESIGNHITTEST;
TMyScrollBar.CMDesignHitTest( var
Message: TCMDesignHitTest);
Message.Result := 1;
你的元件必须以以下方法建立卷轴:
TMyScrollBar.Create(nil);
TMyScrollBar.Create(Self);
<FONT COLOR="#.2 如何建立Windows95式样的卷轴?
你必须设定卷轴的页面大小。你可以用以下的程式码来做:
SetPageSize(ScrollBar: TScrollB PageSize: Integer);
ScrollInfo: TScrollI
ScrollInfo.cbSize := Sizeof (ScrollInfo);
ScrollInfo.fMask := SIF_PAGE;
ScrollInfo.nPage := PageS
SetScrollInfo (ScrollBar.Handle, SB_CTL, ScrollInfo,
要取得目前页面大小可用如下方法:
function GetpageSize
(ScrollBar: TScrollBar): I
ScrollInfo: TScrollI
if HandleAllocated
ScrollInfo.cbSize := SizeOf (ScrollInfo);
ScrollInfo.fMask := SIF_PAGE;
GetScrollInfo (ScrollBar.Handle, SB_CTL, ScrollInfo);
Result := ScrollInfo.nP
第四部分 Bound Controls
<FONT COLOR="#.1 哪里可以找得到有关 TDataLink
类别的说明文件?
我可以大胆地说全世界有关 TDataLink 的说明文件只有一份,就在这儿:
属性 (Property) 介绍
property Active: Boolean(唯读)
当此 DataLink 连结至一个已开启的 DataSource 时会传回
True。当 Active 状态改变时会 触发ActiveChanged方法。
property ActiveRecord: Integer(可读写)
用来设定或取得 DataLink 缓冲区中目前所指向的记录代码,代码的范围是
0 .. BufferCount - 1。使用它来设定记录代码时必须小心不要超过这个范围,否则
可能导致不可预期的错误。
property BufferCount: Integer(可读写)
DataLink 拥有一个资料缓冲区。而 BufferCount 属性即用来设定或取得缓冲区大小,
缓冲区大小决定了一个dataset同时可以显视的资料记录笔数。对大部分的资料感知元
件来说,BufferCount 的值是 1;但对 TDataGrid 来说,BufferCount 代表它的可
视列数目。
property DataSet: TDataSet(唯读)
传回此 DataLink 所连结的 DataSet。其实就是 DataSource.DataSet。
property DataSource: TDataSource(可读写)
传回此DataLink所连结的DataSource。
property DataSourceFixed: Boolean(可读写)
这个属性可用来防止 DataSource 属性被更改。如果此属性设为
True,当我们试著改变 DataSource 属性时会引发一个例外。
property Editing: Boolean(唯读)
如果 DataLink 正处於编辑状态则传回 True。
property ReadOnly: Boolean(可读写)
设定 DataLink 是否为唯读状态。这个属性并不会影响所连结的
DataSet。在唯读状态下这个 DataLink 无法进入编辑状态。
property RecordCount: Integer(唯读)
传回DataSet的资料记录数目。
方法 (Method) 介绍
function Edit: B
让所连结的DataSet进入编辑状态。传回值: 成功传回
True ,失败传回 False
procedure UpdateR
我们不直接呼叫这个方法,它是提供其它程式来呼叫的。这个方法只有设定一个旗帜
然後呼叫 UpdateData 方法。
虚拟方法 ( Virtual Method )
要让 TDataLink 物件与元件沟通必须改写下列这些方法:
procedure ActiveChanged
当连结的 DataSource 开启状态改变时会呼叫此方法。使用
Active 属性可以得知目前是否为开启状态。
procedure CheckBrowseMode
资料库有任何改变之後都会先呼叫这个方法。
procedure DataSetC
当下列任一事件发生时都会呼叫此方法:
移至DataSet的开头
移至DataSet的结尾
在DataSet中插入或新增资料
删除DataSet的资料
取消DataSet的编辑
如果不想改写这个方法只要在其中呼叫:
RecordChanged(nil);
procedure DataSetScrolled(Distance: Integer)
每当目前记录变更时会呼叫此方法。Distance 参数代表缓冲区欲卷动的行数。
(其值范围皆在 -1 .. 1 之间)。使用 ActiveRecord 属性可以取得缓冲区中目前所指向的记录。我们无法强制让
DataLink 的缓冲区卷动。
procedure FocusControl(Field: TFieldRef)
与TField.FocusControl方法相同。
procedure EditingChanged
当 DataLink 的编辑状态改变时会呼叫此方法。使用
Editing 属性可以得知DataLink 是否 正处於编辑状态。
procedure LayoutChanged
当 DataSet 的 Layout 改变时会呼叫此方法(例如新增一个column)。
procedure RecordChanged(Field: TField)
当下列任一事件发生时都会呼叫此方法:
目前记录进入编辑状态
目前记录内容更动
procedure UpdateData
在一笔记录被更新以前会呼叫此方法。你可以呼叫 Abort
程序来防止资料库更新。
<FONT COLOR="#.2 如何得知一个 dataset
中有几笔记录?
TDateSet 的 RecNo 属性可以传回资料记录的数目,但很不幸地它只适用於
dBase 及 Paradox 的资料表格。若想得知目前资料记录的编号,可以从 TDataLink
类别衍生一个新的类别,然後进行下 列步骤:
改写 DataSetScrolled 方法以取得目前记录是否被卷动。
改写 DataSetChanged 方法来确认目前记录是否跳至最前面或最後面了。
接著你可以将这个新类别的物件连结到TDataSource物件上然後就可以随时得知目前的
记录编号了。
第五部分 VCL
<FONT COLOR="#.1 使用""合环境除错时如何追踪检视
VCL元件的程式码?
将你想要追踪的 VCL 原始程式单元拷贝至存放专案的目录中并重新编译元件库,此後你就可以在那些
VCL单元中追踪检视程式码了。
<FONT COLOR="#.2 我的元件参考到其它元件,如何得到参考元件被消灭的讯息?
Max Nilson 的回答:
TComponent 类别提供了 Notification 方法。当一个元件被移除时我们可以利用这个方
法得到消息以进行适当的反应。你可以参考『Component Writer's Guide』内有关
Notification 及FreeNotification 这两个方法的说明。
当你的元件参考到另一个元件,例如,你的元件中有一个
TDataSource 型态的属性。那 你必须改写此元件的 Notification 方法,在其中检查被移除的元件是否就是本身所参
考的元件。预设情况下,当元件被移除时,所有其它在同一个表格上的元件才会收到
消息,如果参考元件位於另一个表格上时,你的元件无法得知这件事情。Delphi
2.0 推出了TDataModule,参考元件位於另一个表格上的机会大幅增加,所以你应该利用
FreeNotification 方法来确定当参考元件移除时,你一定可以得到消息。
如果你不改写 Notification 方法来处理参考元件被移除的讯息,这会让
Delphi""合环境陷入十分不稳定的状态。它可能不会立刻当掉,但你也不能再正常地继续其它工作
下面是一个范例,当你的元件参考其它元件时,千万记得要做以下的处理:
TMyComponent = class
(TComponent)
FDataSource: TDataS
SetDataSource(Value: TDataSource);
Notification(AComponent: TC Operation: TOperation); override;
property DataSource:
TDataSource read
FDataSource write
TMyComponent.SetDataSource(Value: TDataSource);
if Value &&
FDataSource then
FDataSource := V
// 告诉参考元件说,当它被移除时记得通知我一声。
if FDataSource && nil then FDataSource.FreeNotification(Self)
TMyComponent.Notification(AComponent: TC Operation:TOperation);
Notification(AComponent, Operation);
// 如果被移除的正是参考元件,把FDataSource栏位清除。
if (Operation
= opRemove) and
(AComponent = FDataSource) then
FDataSource := nil
<FONT COLOR="#.3 什麽是元件讯息?
元件讯息是什麽?它十分类似Windows的视窗讯息,只有一点不同:元件讯息只适用於
VCL 元件;而视窗讯息可以用在系统内所有具有 window handle 的控制项或视窗。如果
你有一个具有 Font 属性的元件(例如TLabel元件),当我们更改它的 Font 属性时并没
有送出视窗讯息(译注:TLabel 元件不是视窗控制项,根本也没有视窗 Handle可以让
我们传送视窗讯息),但是控制项仍然知道字型改变了所以要重画自己,为什麽?因
为我们有元件讯息。
元件讯息不可以由虚拟方法来处理,这可能是设计 VCL
时的考量,大概是因为不想让虚 拟方法表格(Virtual Method Table)过於庞大的原因。
『Secrets of Delphi 2.0』这本书对於所有的元件讯息有十分详尽的解说。
接下来我们列出一些比较常见的元件讯息及它们的作用。
标示著『Notification Only』 的讯息表示送出这个讯息只是为了通知元件某件消息而己,并不传入任何参数而且也
不需要传回值。
CM_ACTIVATE (Notification Only)
当表格成为焦点视窗时会传给本身这个讯息。
CM_CTL3DCHANGED (Notification Only)
当控制项的Ctl3D属性更改时会传给本身这个讯息。
CM_DESIGNHITTEST 参数:TCMDesignHitTest 传回值:0或1
在设计时期当滑鼠移到元件上头时,""合环境会送给此元件这个讯息。此讯息的目的
用来决定元件在设计时期是否要处理滑鼠讯息。如果传回值是 1,""合环境就让元件
自行处理滑鼠讯息;若传回值是 0,则""合环境会帮你处理滑鼠讯息。如果传回值永
远是 1,那麽元件的快速功能选单则永远不会出现;如果元件不处理这个讯息或永远
传回 0,那此元件在设计时期将无法对滑鼠讯息做任何反应。
CM_FONTCHANGED (Notification Only)
控制项的字型改变後送给本身此讯息。
CM_FONTCHANGE (Notification Only)
当控制项收到WM_FONTCHANGE视窗讯息时会送给本身这个讯息。
CM_PARENTCTL3DCHANGED (Notification Only)
当元件父控制项的Ctl3D属性改变或设定新的父控制项时会收到此讯息。
CM_PARENTCOLORCHANGED (Notification Only)
当元件父控制项的 Color 属性改变或设定新的父控制项时会收到此讯息。
CM_PARENTFONTCHANGED (Notification Only)
当元件父控制项的Font属性改变或设定新的父控制项时会收到此讯息。
CM_PARENTSHOWHINTCHANGED (Notification Only)
当元件父控制项的ShowHint属性改变或设定新的父控制项时会收到此讯息。
CM_WININICHANGE 参数:TWMWinIniChange 传回值:无
当控制项收到WM_WININICHANGE视窗讯息时会送给本身这个讯息。
<FONT COLOR="#.4 我的元件得到输入焦点後仍不能接受键盘讯息,为什麽?
如果你的元件有 DragMode 属性而且将它设成 dmAutomatic
时,很有可能让你的元件以为它正被拖曳但实际上并没有的情况。在 Controls 单元中有一个区域变数
DragControl 指 向目前正被拖曳的元件。你遇到的情况很可能就是明明没有拖曳的动作但是DragControl
变数却指向你的元件。在 TWinControl 的 WndProc 方法中,当 DragControl 变数指向元件
本身时,会忽略所有键盘讯息,这就是原因了!
第六部分 其它资讯
<FONT COLOR="#.1 有哪些书介绍或讲解如何撰写元件?
有关撰写元件的『标准』参考书籍:
『Developing Delphi Components』 作者:Ray Konopka
出版:Coriolis Group
下面这本书并不专注於元件写作,但里面提到许多元件撰写者不可不知的资讯:
『Secrets of Delphi 2』 作者:Ray Lischner 出版:Waite
另外一本元件撰写的好书,它有许多在『Developing
Delphi Components』里找不到的资讯:
『Programming Delphi Custom Components』 作者:Fred
Bulback 出版:M&T Books
<FONT COLOR="#.2 有哪些Web站台可以取得撰写元件的资讯?
全世界最大的 Delphi Web 站台『』
(译注:亚洲地区使用者可以就近到位於日本的
我在下面这些站台中找到许多元件的原始程式码:
(译注:『』""理元件也十分用心! )
(译注:台湾地区目前维持最好的 Delphi 站台是『』及其 )
你也可以使用一些搜寻引擎来寻找有关 Delphi 的站台:
搜寻引擎也别错过罗!)
第七部分 元件的储存与载入
<FONT COLOR="#.1 如何将包含其它物件的物件一起存入
我试过许多方法,包括改写元件的 DefineProperties及
WriteComponents方法,但都还是失败了。所以我只能说要解决这个问题的话只有使用
Delphi 原本的方法一途。
将包含其它物件的物件一起储存起来的步骤大致如下:
确定你要储存的所有物件都是从 TComponent 类别衍生下来的。
将所有需要储存的变数宣告在 published 区段。
在元件的 Register 程序中呼叫 RegisterComponents程序来注册所有你要储存起来的类别。
每个拥有子控制项的类别必须改写 GetChildren 方法以储存每个子控制项。(在
Delphi 1.0 中你必须改写 WriteComponents 方法并且为每个子控制项呼叫 WriteComponent方法)。
将物件载入的方法用了点小技巧。你必须改写元件的
GetChildOwner 及 GetChildParent 方法,否则 Delphi会将所有物件的拥有者都设定为元件所在的表格。(在Delphi
1.0 中你必须改写ReadState方法)。
<FONT COLOR="#.2 如何得知元件是否正从资料流中读出?
当元件正从资料流中读出时,它的 ComponentState
属性会包含csLoading 旗帜。
constructor
TMyClass.Create(AOwner: TComponent);
if csLoading
in ponentState
<FONT COLOR="#.3 如何确定元件的属性是否被正确地储存?
有许多很简单的方法可以验证属性是否被正确地储存在档案里:
在""合环境中用滑鼠右键点选表格然後选择『View
as Text』。然而万一 DFM 档 有任何错误的话,你将什麽也看不到。
开个 DOS 视窗,利用 Delphi 所附的『Convert』程式将
DFM 档转成文字格式。
Stefan Hoffmeister 指出复制或剪下元件後,到任何一个文书编辑器(如记事本)中
贴上,你就可以看到此元件的文字表示。你甚至可以编辑这些文字表示後再将它贴回
Delphi""合环境的表格上。
第八部分 Delphi 的工具
<FONT COLOR="#.1 有没有Delphi版本的 YACC
有。 这位仁兄写了 Turbo Pascal 版本的 YACC 及 LEX,也可以让 Delphi
下取得 tply30a1.zip 及 tply30a2.zip 这两个档案,其中还包含这两个工具的原始程式哦!
<FONT COLOR="#.2 如何秀出 JPEG 格式图形档?
将 Independent JPEG Group 所发展的免费 JPEG 程式库改写成
Pascal 版本。你可以从下取得:
Independent JPEG Group 的免费 JPEG 函式库 rev
6a 之 Pascal 版本 (1.0 版)。
第九部分 基本程式设计技巧
<FONT COLOR="#.1 如何建立不定数目的物件阵列?
最简单的方法是使用 TList 类别。我发现从 TList
衍生一个新类别很有用处。接下来的程式码示范如何为一个特定型态撰写一个特别的
TList 类别,并且加进基本的错误检查。
TListOfMyObject = class
function GetItems(Index:
Ordinal): TMyO
property Items[Index:
Ordinal]: TMyObject read
Add(AObject: TMyObject);
function TListOfMyObject.GetItems
(Index: Ordinal): TMyO
if Index &=
Count then
raise Exception.CreateFmt('Index(%d)
outside range 1..%d', [Index, Count-1]);
Result := inherited
Items[Index];
TListOfMyObject.Add (AObject: TmyObject);
Add(AObject);
<FONT COLOR="#.2 Delphi 2.0的 WinCrt单元到哪去了?
Delphi 2.0并没有 WinCrt单元。 先别伤心,这是因为我们可以用其它方法来取代它。在
Project|Options 的 Linker 页次中将『Generate console application』选项打开,你就可以像以前使用
WinCrt 单元一样地写程式了!
<FONT COLOR="#.3 自制元件时该从哪个类别继承?
VCL 中有一些『自订』类别,而且有许多控制项是直接由这些『自订』类别继承下来
的。例如 TMemo 直接继承自 TCustomMemo类别。这些自订类别写好了所有该控制项所拥
有的功能,只是没有将属性公开出来而己。大部分情形下,你应该从那些自订类别继
承而不是控制项类别。
如果你要从头撰写自己的元件,那麽从 TCustomControl
类别继承是个不错的主意。撰 写出来的元件会具有 Window Handle 且可以接受输入焦点。
另外根据你的需要也可以从这些类别继承:
TGraphicControl:视觉元件,但是没有window handle,也不能接受输入焦点。
TComponent:不可视元件,你没办法在执行时期看到它。
TWinControl:将已存在的视窗元件包装起来,如Windows标准控制项或VBX元件。
第十部分 进阶程式设计技巧
<FONT COLOR="#.1 Delphi 有与 C++ 一样的
I/O Stream 类别吗?
答案可以说有也可以说没有。Delphi允许你建立自己的『文字档驱动程式』,它可以
让你使用Delphi 标准的 I/O 函式库来处理非标准的 I/O,如处理 UNIX 格式的文字档或处
理 Socket 所取得的资料。虽然没有像 C++ 的 I/O Stream 类别那麽强大但应该也足够一般用途使用了。
建立『文字档驱动程式』的方法在『Object Pascal
Language Guide』中有明述。此 外你也可以参考 VCL 的 Printer 单元。
Delphi有 TStream 类别,不过是设计用来将物件写入资料流的,不像
C++ 的 I/O Stream 类别那麽具有弹性。
<FONT COLOR="#.2 如何取得列举型态变数的文字表示?
使用 TypInfo单元中的 GetEnumName 函式:
TMyType = (Value1, Value2);
TypeValue: TMyT
Writeln (GetEnumName(TypeInfo(TMyType), Ord(TypeValue));
TypInfo单元中还有许多与型别资讯有关的函式。
『Secrets of Delphi 2.0』这本书有许多关於TypInfo单元的资讯,值得参考。
第十一部分 元件虚拟方法
<FONT COLOR="#.1 如何得知元件的window
handle是何时建立的?
控制项的 window handle 是在 CreateWnd 方法中建立的。如果你想要在建立
window handle 後接著做某些动作那麽你应该改写 CreateWnd 方法:
TMyClass.CreateW
// 现在还没取得 window handle
inherited CreateW
// 呼叫 inherited 以取得 window handle
// 在这里撰写你想要执行的动作
<FONT COLOR="#.2 如何得知是否表格上所有元件都已载入完成?
Loaded 方法是在载入完成後接著被呼叫的。
TMyClass.L
// 将ComponentState中的 csLoading 状态清除
// 在这里撰写你想要执行的动作
<FONT COLOR="#.3 在哪里绘制元件最适合?
你应该拦截 WM_PAINT 视窗讯息然後利用 Canvas 来绘制元件。然而
VCL 己经帮你拦 截好了,你只须改写元件的 Paint 方法即可。
TMyClass.P
// 如果你的元件是己存在的元件继承下来的,那麽必须在这里呼叫
inherited Paint
// 在这里撰写你想要执行的动作
<FONT COLOR="#.4 如何改变元件的视窗式样?
CreateParams方法用来设定元件的视窗式样及其它必须传递至
CreateWindowEx API 的 参数。要改变元件的视窗式样,例如增加或拿掉元件的垂直卷轴只要改写
CreateParams 方法:
TMyControl.CreateParams(var Params: TCreateParams);
CreateParams(Params);
if IWantAScrollBar
Params.Style := Params.Style or
WS_VSCROLL
Params.Style := Params.Style and
not WS_VSCROLL;
第十二部分 Windows API
<FONT COLOR="#.1 元件卷动时闪动的很厉害,如何克服这种情况?
要卷动元件本身最简单的方法就是改变它的座标然後重画元件,但是这方法会导致元件闪动的很厉害。
比较好的方法是呼叫 ScrollWindow 或 ScrollWindowEx
Windows API。
闪动的另一个原因可能来自於 WM_PAINT 及 WM_ERASEBKGND。你可以试著拦截
WM_ERASEBKGND 及 WM_PAINT 讯息然後自己处理绘图动作,包括绘制背景的动作,或
许可以改善闪动的情况。
<FONT COLOR="#.2 如何重新启动Windows?
使用 ExitWindowsEx Windows API。
<FONT COLOR="#.3 如何快速大量地更改元件资料?
在进行大量资料更改前後,利用 WM_SETREDRAW 讯息来控制你的元件暂时不要重画,
这不但可以使资料设定速度增快也防止元件闪烁的情况。
第十三部分 控制项边框
<FONT COLOR="#.1 为什麽我的元件的 Ctl3D
属性设为 True 之後,它依然没有 3D 的边框呢?
如果 ControlStyle 属性内没有包含 csFramed 旗帜那麽
Ctl3D 属性就会没有作用。在元件 的建构函式内加上:
ControlStyle := ControlStyle + [csFramed];
<FONT COLOR="#.2 如何实作 BorderStyle
在控制项设定有没有边框之後要重新建立 window handle:
FBorderStyle: TBorderS
SetBorderStyle(Style: TBorderStyle);
property BorderStyle:
TBorderStyle read
FBorderStyle write
SetBorderS
CreateParams(var
Params: TCreateParams); override;
TMyControl.CreateParams(var
Params: TCreateParams);
CreateParams(Params);
if FBorderStyle
= bsSingle then
Params.Style := Params.Style or
Params.Style := Params.Style and
not WS_BORDER;
TMyControl.SetBorderStyle(Style: TBorderStyle);
if Style &&
FBorderStyle then
FBorderStyle := S
// 重新建立window handle
第十四部分 控制项式样
<FONT COLOR="#.1 当元件重绘时如何防止闪动的情况?
如果元件的 ComponentStyle 属性没有包含 csOpaque
旗帜的话,呼叫 Invalidate方法时 会导致元件的背景先被擦掉再重绘。如果你在
Paint 方法中绘制背景,那你应该在元件的建构函式中加上:
ComponentStyle := ComponentStyle + [csOpaque];
Max Nilson的回答:
引起闪动另一个原因可能是 WM_ERASEBKGND 讯息的处理。当
VCL 控制项收到一个 WM_ERASEBKGND 讯息时,它会将元件的背景擦掉然後设定成预设的颜色。如果你的元
件衍生自 TWinControl,而且元件的颜色与背景颜色不同(例如图形),每次重画以
前都会将元件先清成背景颜色再重绘,这就是造成闪动的原因了!
解决的方法不难,你必须告诉 Windows 你要自行解决『所有的』绘图动作。不过有一
个前提是,你一定要确定你的 Paint 方法将""个元件都画过,如果你漏了什麽地方忘
了画,那个部分的资料会由乱数组成,你能想见这情况吗?使用这个方法可以加速你
的元件绘制动作(稍微快一点点),因为少了一个填满背景颜色的动作。
TMyComponent = class
(TWinControl)
WMEraseBkgnd(var Message: TWMEraseBkgnd); message
WM_ERASEBKGND;
TBMyComponent.WMEraseBkgnd(var
Message: TWMEraseBkgnd);
// 不要重绘背景,这会造成元件闪动
Message.Result := 0
第十五部分 视窗讯息
<FONT COLOR="#.1 为什麽我的元件得不到方向键的讯息?
你必须拦截 WM_GETDLGCODE 才能处理方向键的讯息,在
WM_GETDLGCODE 的讯息处理 者中传回 DLGC_WANTARROWS。如果你不这样做,那方向键的功用就只能用来移动视窗
焦点而己。
Max Nilson 的回答:
想要你的元件能够处理方向键,你必须要拦截 CM_WANTSPECIALKEY
元件讯息。 CM_WANTSPECIALKEY 元件讯息提供你比拦截 WM_GETDLGCODE 视窗讯息更容易且灵活的
判断方法来决定是否需要某些特殊键的讯息。当控制项收到任何一个特殊键时就会送
出CM_WANTSPECIALKEY 元件讯息给控制项。
特殊键包括:VK_TAB、VK_LEFT、VK_RIGHT、VK_UP、VK_DOWN、VK_RETURN、VK_EXECUTE
、VK_ESCAPE 及 VK_CANCEL。如果讯息传回值是非零值,这个键就会被送至 KeyPress
方法以供处理,否则这个键的讯息会被送至元件的父控制项,以预设方式来处理。
一个简单的范例:
TMyComponent = class
(TWinControl)
CMWantSpecialKey(var Message: TCMWantSpecialKey); message
CM_WANTSPECIALKEY;
TMyComponent.CMWantSpecialKey(var
Message: TCMWantSpecialKey); begin
inherited;
// 我们只想处理向左方向键,其它的特殊键都给 Windows
if Message.CharCode
= VK_LEFT then
Message.Result := 1;
CM_WANTSPECIALKEY 元件讯息比 WM_GETDLGCODE 讯息更具有弹性的地方在这儿。我们
甚至可以根据是按下的是哪个特殊键才决定是否处理这个键。例如,你的控制项有三张影像,你可以让使用者利用左右方向键来回检视它们,如果翻到最後一张影像再按
向右键时,焦点就让它离开元件,剩下的全部都让 Delphi 来处理。
<FONT COLOR="#.2 有没有与 Visual Basic『DoEvents』同样功能的函式?
有。Application.ProcessMessages方法。

我要回帖

更多关于 delphi 验证码识别 的文章

 

随机推荐