当前位置: 首页 > 学习 > 电脑学习 > 程序设计 > Delphi > 基础教程 > 正文

Delphi 异常处理与程序调试(二)

http://www.zk168.com.cn  招考学习网 2006-4-7 9:40:24
-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--

12.1.2 对象异常类 

  所谓对象异常是指非部件的对象引发的异常。Delphi定义的对象异常包括流异常、打印异常、图形异常、字符串链表异常等。 

12.1.2.1 流异常类 

  流异常类包括EStreamError、EFCreateError、 EFOpenError、EFilerError、EReadError、EWriteError、EClassNotFound。它们的结构关系如下: 

EStreamError

|---------- EFCreateError

|---------- EFOpenError

|---------- EFilerError

|--------- EReadError

|--------- EWriteError

|--------- EClassNotFound

    图12.1 流异常结构图 

流异常在Classes库单元中定义。

  流异常引发的原因如表12.6。

表12.6  流异常类及其产生原因

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

异常类 引发原因

─────────────────────────────────

EStreamError 利用LoadFromStream方法读一个流发生错误

EFCreateError 创建文件时发生错误

EFOpenError 打开文件时发生错误

EFilerError 试图再次登录一个存在的对象

EReadError ReadBuffer方法不能读取特定数目的字节

EWriteError WriteBuffer方法不能写特定数目的字节

EClassNotFound 窗口上的部件被从窗口的类型定义中删除

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 

12.1.2.2 打印异常类 

  打印异常类EPrinter当打印发生错误时引发。它在printers库单元中定义。例如你的应用程序试图向一个不存在的打印机打印或由于某种原因打印工作无法送到打印机时,就会产生一个打印异常。 

12.1.2.3 图形异常类 

  图形异常类定义在Graphic 库单元中,包括EInvalidGraphic和EInvalidGraphicOperation两类。

  EInvalidGraphic当应用程序试图从一个并不包含合法的位图、图标、元文件或用户自定义图形类型的文件中装入图形时引发。例如下面的代码: 

  Image1.Picture.LoadFromFile('Readme.txt'); 

  由于Readme.txt并不包含一个合法的图形,因而将引发一个EInvalidGraphic异常。

  EInvalidGraphicOperation当试图对一个图形进行非法操作时引发。例如试图改变一个图标的大小。 

var

AnIcon: TIcon;

begin

AnIcon := TIcon.Create;

AnIcon.LoadFromFile('C:\WINDOWS\DIRECTRY.ICO');

AnIcon.Width := 100; { 引发一个图形异常}

...

12.1.2.4 字符串链表异常 

  字符串链表异常EStringListError、EListError在用户对字符串链表进行非法操作时引发。由于许多部件(如TListBox,TMemo,TTabSet,…)都有一个TStrings类的重要属性,因而字符串链表异常在部件操作编程中非常有用。

  EStringListError异常一般在字符串链表越界时产生。例如对如下初始化的列表框:  

ListBox1.Items.Add('First item');

ListBox1.Items.Add('Second item');

ListBox1.Items.Add('Third item');

  则以下操作都会引起EStringListError异常: 

ListBox1.Item[3] := ' Not Exist';

str := ListBox1.Item [3];

  EListError异常一般在如下两种情况下引发:

  1.当字符串链表的Duplicates属性设置为dupError时,应用程序试图加入一个重复的字符串;

  2.试图往一个排序的字符串链表中插入一个字符串。 

12.1.3 部件异常类 

12.1.3.1 通用部件异常类 

  通用部件异常类常用的有三个:EInvalidOperation、EComponentError、EOutOfResource。其中EInvalidOperation、EOutOfResource在Controls单元中定义;EComponentError在Classes单元中定义。

  1.非法操作异常EInvalidOperation

  EInvalidOperation 引发的原因可能有:

  ● 应用程序试图对一个Parent属性为nil的部件进行一些需要Windows句柄的操作

  ● 试图对一个窗口进行拖放操作

  ● 操作违反了部件属性间内置的相互关系等 

  例如,ScrollBar、Gauge等部件要求Max属性大于等于Min属性,因而下面的语句: 

  ScrollBar1.Max := ScrollBar1.Min-1;

  将引发一个EInvalidOperation异常。 

  2.部件异常EComponentError

引发该异常的原因可能有:

  ● 在Register过程之外试图登录一个部件(常用于自定义部件开发中)

  ● 应用程序在运行中改变了一个部件的名称并使该部件与另一个部件重名

  ● 一个部件的名称改变为一个ObjectPascal非法的标识符

  ● 动态生成一个部件与已存在的另一部件重名 

3.资源耗尽异常EOutOfResource

当应用程序试图创建一个Windows句柄而Windows 却没有多余的句柄分配时引发该异常。 

12.1.3.2 专用部件异常类 

  许多部件都定义了相应的部件异常类。但并不是有关部件的任何错误都会引发相应的异常类。许多情况下它们将引发一个运行时间异常或对象异常。

  下面列出几个典型的部件异常类。

  1.EMenuError

非法的菜单操作,例如试图删除一个不存在的菜单项。这一异常类在Menus库单元中定义。

  2.EInvalidGridOpertion

  非法的网格操作,比如试图引用一个不存在的网格单元。这一异常类在Grids库单元中定义。

  3.EDDEError

  DDE异常。比如应用程序找不到特定的服务器或会话,或者一个联接意外中止。这一异常类在DDEMan库单元中定义。

  4.EDatabaseError,EReportError

  数据库异常(EDatabaseError)和报表异常(EReportError) 在进行数据库和报表操作出现错误时引发。有关数据库的问题请读者参阅本书第二编。 

12.1.4 小结 

  在这一节中重点介绍了Delphi提供的异常类体系。我们力求给读者一个清晰、全面的印象,使读者能在自己的程序开发中实际使用它们。为便于理解我们也提供了一些简单的说明性示例。虽然在具体的使用中读者还可能会碰到许多问题,但意识到应该用异常类来增强程序的健壮性却是程序设计水平走上新台阶的标志。 

12.2 异常保护 

  确保回收分配的资源是程序健壮性的一个关键。但缺省情况下异常发生时程序会在出错点自动退出当前模块,因此需要一种特殊的机制来确保即使在异常发生的情况下释放资源的语句仍能被执行。而Delphi的异常处理正提供了这种机制。 

12.2.1 需要保护的资源 

  一般说来需要保护的资源包括:

  ● 文件

  ● 内存

  ● Windows资源

  ● 对象 

  比如下面一段程序就会造成1K内存资源的丢失。 

var

APointer : Pointer ;

AInt , ADiv: Integer ;

begin

ADiv := 0;

GetMem ( APointer , 1024 );

AInt := 10 div ADiv ;

FreeMem ( Apointer , 1024 );

end; 

由于程序从异常发生点退出从而FreeMem永远没有执行的机会。 

12.2.2 产生一个资源保护块 

  Delphi提供了一个保留字finally,用于实现资源的保护: 

  {分配资源}

  try

{资源使用情况}

finally

{释放资源}

  end; 

try…finally…end就形成了一个资源保护块。finally后面的语句是在任何情况下,不论程序是否发生异常,都会执行的。

  对于(12.2.1)中的例子如下代码即可确保所分配内存资源的释放: 

var

APointer : Pointer ;

AInt , ADiv : Integer;

begin

ADiv := 0;

GetMem ( APointer , 1024 );

try

AInt := 10 div ADiv ;

finally

FreeMem ( Apointer , 1024 );

end;

end; 

下面的例子摘自(6.4)节,是在文件拷贝中实现文件资源的保护: 

procedure CopyFile(const FileName, DestName: TFileName);

var

CopyBuffer: Pointer;

TimeStamp, BytesCopied: Longint;

Source, Dest: Integer;

Destination: TFileName;

const

ChunkSize: Longint = 8192;

begin

Destination := ExpandFileName(DestName);

if HasAttr(Destination, faDirectory) then

Destination := Destination + '\' + ExtractFileName(FileName);

TimeStamp := FileAge(FileName);

GetMem(CopyBuffer, ChunkSize);

try

Source := FileOpen(FileName, fmShareDenyWrite);

if Source < 0 then

raise EFOpenError.Create(FmtLoadStr(SFOpenError, [FileName]));

try

Dest := FileCreate(Destination);

if Dest < 0 then

raise EFCreateError.Create(FmtLoadStr(SFCreateError, [Destination]));

try

repeat

BytesCopied := FileRead(Source, CopyBuffer^, ChunkSize);

if BytesCopied > 0 then

FileWrite(Dest, CopyBuffer^, BytesCopied);

until BytesCopied < ChunkSize;

finally

FileClose(Dest);

end;

finally

FileClose(Source);

end;

finally

FreeMem(CopyBuffer, ChunkSize);

end;

end;

程序的具体解释见 (6.4)节。

  在异常保护的情况下,当异常发生时,系统会自动弹出一个消息框用于显示异常的消息。退出当前模块后异常类自动清除。

-----------------------------------------------------------[交流]-[打印]-[发送]-[收藏]--
最新入库:
 
·实质、过程及意义——阿多尔诺“否定的辩证法”探微
·从Ontology的译名之争看哲学术语的翻译原则
·论马克思主义哲学经典的解释——解释学方法及其在马克
·中国哲学当前的核心与周边问题
·和合学与21世纪文化价值和科技
·中国文化的和合精神与21世纪
·宗教之间理当相互宽容
·上半个世纪的自由主义
·殷周至春秋时期神人关系之演进
·大学之道:构建以“三纲八目”为核心的道德修养体系
相关内容:
 
网友点评:
 
会员名称:
密码:匿名 ·注册·忘记密码?
评论内容:
(最多300个字符)
  查看评论
友情提醒:
 1.库中的资料大都来自互联网、网友上传、各类书籍,在录入的过程中难免会出现错误,恳请网
 友来信指正!
 2.如果网友在本库中未能找到所需要的材料,请登陆到我们的论坛《招考学习网》版块!
 3.考友想加入招考学习网的编辑部,请发信到XueXiWang#Gmail.com(#改为@)附带个人简历
 4.如需转载请注明出处及作者,谢谢合作!
 5.如果您有更好的建议或意见请EMAIL:XueXiWang#Gmail.com (#改为@)
 6.凡标题中有注有“[NO]”字样均不含答案且答案整理中.
 7.如本库中转载文章涉及版权等问题,请相关网站或作者在两周内发邮件通知(EMAIL:  XueXiWang#Gmail.com (#改为@))我们,我们接到通知后立即删除该文章及链接!
你问我答 更多>>