- 浏览: 2057494 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (1409)
- asp/asp.net学习 (241)
- oracle (10)
- delphi (295)
- java (27)
- pb (1)
- 每日点滴 (49)
- 学习方法 (40)
- 思想方面 (104)
- C语言 (5)
- C++ (1)
- 代码重构经验 (5)
- 软件工程 (3)
- 数据库 (99)
- 英语学习 (3)
- mysql (1)
- 该关注的网站或者网页 (42)
- 总结 (7)
- 要去做的事情 (33)
- 算法 (1)
- 网络方面 (29)
- 随感 (96)
- 操作系统 (36)
- UML (12)
- 常用工具的使用 (55)
- 脚本 (7)
- 汇编 (62)
- 数据结构 (2)
- 财务 (38)
- 语文作文 (16)
- 法律 (1)
- 股票 (88)
最新评论
-
devwang_com:
可以,学习了~~
列出文件夹下所有文件夹的树形结构--Dos命令 tree的使用 -
hvang1988:
不管用啊 frxrprt1.PreviewForm.Pare ...
fastReport预览时嵌入到别的窗体 -
00915132:
我也有这个疑问,非常 感 谢
left join加上where条件的困惑 --SQL优化 -
zhuyoulong:
学习了,高效读书
软件架构师要读的书 -
nTalgar:
非常感谢分享!
Application.ProcessMessages用法:
摘自:http://media.ccidnet.com/media/swm/150/15805.htm
【摘要】应用程序中的异常几乎是不可避免的,本文探讨了delphi的异常处理机制和异常处理的几种方法,并结合一些实例介绍如何根据应用程序的需要开发自己的异常处理程序。
一、 异常及异常处理机制
异常可以理解为一种特殊的事件,当这种特殊的事件发生时,程序正常的执行流程将被打断。异常处理机制能够确保在发生异常的情况下,应用程序不会中止运行,并且能以一致的风格进行处理。许多刚刚涉及delphi的程序员感觉异常处理机制高深莫测,是高级程序员的“专利”,总有尽可能绕开它的想法,因而不得不小心翼翼地检查每一次函数调用的返回值,或者通过额外的代码捕获可能的错误,即使这样,也只能保证程序代码不出错,而无法保证包括操作系统、设备驱动程序、数据库驱动程序、delphi自身的元件库和运行时间库在内的软硬件设备不出错。问题就在于,通过检查函数的返回值或设置错误陷阱只能捕获可预见的错误,如果出现没有预见到的错误,或者函数调用本身就已失败,程序正常的流程就会被打乱。由此可见,异常几乎是不可避免的。其实,object pascal提供了多种异常处理方法,使异常的处理变得轻而易举,可以将你从为你的应用程序执行的每个任务编写单独的错误处理程序的繁琐工作中解放出来。
二、 处理异常的方法
1. try...except 结构
try...except 结构是这样工作的:try后面到except之前的语句通常是希望正常执行的代码,在执行过程中如果触发了异常,程序就跳入except部分。在except部分做出的处理可以有以下三种类型:
(a) 不需要确切知道异常的类型,只需要做笼统的处理时,可以弹出一个警告信息框,或者释放已分配的资源,或者退出程序。程序示例如下:
例1 procedure tform1.button1click(sender :tobject)
var
num: integer;
begin
try
num:=strtoint(edit1.text);
edit2.text:=inttostr(num*num);
except
showmessage(edit1.text+'无法转成整数!');
end;
end;
该例中,点击button1后,程序试图将编辑框edit1中的内容转换为整型数,整数平方之后再转换成字符串类型数据,在编辑框edit2中显示。如果edit1.text是7.89,传递给strtoint将产生econverterror异常,因为7.89不是一个有效整数。异常产生后,将显示一条警告信息,并退出该过程。
(b) 利用异常处理句柄处理某个特定的异常
例如,在例1中可以针对econverterror异常做出如下的处理:
例2 procedure tform1.button1click(sender :tobject)
var
num: integer;
begin
try
num:=strtoint(edit1.text);
edit2.text:=inttostr(num*num);
except
on econverterror do showmessage(edit1.text+'无法转成整数!');
end;
end;
(c) 利用异常处理句柄处理多种异常
通常,执行的代码不只产生一种异常,这就需要在except部分进行更具体的测试,根据产生的异常类型分别做出处理。现将例2稍加改动如下:
例3 procedure tform1.button1click(sender :tobject)
var
num: integer;
begin
try
num:=strtoint(edit1.text);
edit2.text:=inttostr(30 div num);
except
on econverterror do showmessage(edit1.text+'无法转成整数!');
on edivbyzero do
begin
showmessage('除数不能为零!');
edit2.text:='0';
end;
end;
end;
在例3中,try部分的第一条语句可能产生econverterror 异常;当 num为零时,try 部分的第二条语句还会产生被零除的异常(即产生edivbyzero 异常)。由于产生异常原因不同,需要分别进行不同的处理。例3中的except 部分的代码也可以写成以下的形式,这两种异常处理的结果是一样的。
except
on e:exception do
begin
if e is econverterro then showmessage(edit1.text+'无法转成整数!');
if e is edivbyzero then
begin
showmessage('除数不能为零!');
edit2.text:='0';
end;
end;
2. try...finally 结构
try...finally 结构最大的用处是在异常发生的情况下,确保释放应用程序已经分配的资源,或者完成一些必须的操作,比如:剪贴板clipboard 在打开之后必须调用close 方法将剪贴板关闭;数据感知组件更新禁止之后必须调用enablecontrols方法才能使更新显示有效等。try...finally 结构之所以能做到这一点,是因为不管异常是否发生,程序都要执行finally 部分。请看下面的例子:
例4 procedure tform1.button1click(sender :tobject)
var
icon : ticon;
begin
try
icon:=ticon.create;
icon.loadfromfile('spin.ico');
imagelist1.replaceicon(0,icon);
finally
icon.free;
end;
end;
在例4中,try 部分代码是从磁盘获取一个图标,用来代替imagelist1 中的0号图标。如果图标文件spin.ico 不存在或者被损坏,将会产生efopenerror 异常,中断 try 部分代码的执行,但是程序会执行finally 部分的代码,使得icon 占用的资源得以释放。当然,如果没有发生任何异常,finally 部分也将被执行。可以说,finally 部分是 try...finally 结构的“必经之路”。
3. try...except 与try...finally 的嵌套结构
try...finally 结构确实有它独到的功能,但是try...finally结构中没有 try...except 结构中的异常处理句柄,也就无法知道当前确切的异常类型,并且不论异常是否发生,程序都执行 finally 部分,这就决定了 try...finally 结构无法对发生的异常进行特别的处理。如果在应用程序中,既需要完成一些必要的操作,又要对发生的异常进行处理,那么最好使用这两种结构的嵌套。请看下例:
例5 procedure tform1.button1click(sender :tobject)
var
icon : ticon;
begin
try
try
icon:=ticon.create;
icon.loadfromfile('spin.ico');
imagelist1.replaceicon(0,icon);
finally
icon.free;
end;
except
on efopenerror do showmessage('无法打开图标文件spin.ico');
end;
end;
在例5中,无论异常发生与否,都将执行finally 部分释放图标占用的资源。一旦异常发生,则产生警告信息。上例是在 try...except 结构的 try 部分嵌套 try...finally 结构,也可以在 try...finally 结构的 try 部分嵌套 try...except 结构,前者是先执行必须的操作,再进行异常的处理,而后者是先进行异常的处理,再执行必须的操作。在多数情况下,两者的区别并不大。除此之外,try...except 结构和try...finally 结构还可以各自嵌套。在复杂的应用程序中,except 部分或finally部分的异常处理代码本身又有可能触发异常,这就需要采用嵌套结构编写更深一层的异常处理代码,这里就不再详细举例了。
4. 定义自己的异常类
我们的探讨将进入更深的一层——定义自己的异常类。虽然在简单的应用程序中,程序员并无太大必要定义自己的异常类,但是它对编写个性化的异常处理程序仍然是有帮助的。例7中的过程是对数据集 table1 中的字段name进行合法性检查,如果name 没有值或为空字符串,则产生异常,这其中就定义了一个 exception 的派生类emyexception。
例6
type emyexception=class(exception); {定义自己的异常类emyexception}
procedure tform1.table1namevalidate(sender : tfield);
begin
if ( sender.isnull ) or ( sender.asstring='') then
raise emyexception.create('必须填写名称');
end;
三、个性化的异常处理句柄
delphi会自动处理大部分的异常,但全英文信息提示会让应用程序的最终用户感觉并不友好。那么如何编写自己的异常处理代码呢? 在forms单元中声明的tapplication 类中的onexception 事件为编写自己的异常处理代码提供了可能。事实上,用于onexception 事件的事件句柄就是应用程序默认的异常处理句柄。请看下面的例子。
在 project resource 中,首先创建一个新类 tmyclass, tmyclass 中有一个myexceptionhandler 方法,可以根据应用程序的需要来编写,这里体现了个性化的异常处理。由myexceptionhandler事件来响应application 的 onexception事件,这样在程序发生异常时,首先调用的就是自己编写的异常处理事件myexceptionhandler事件。工程文件如下:
例7
program exceptprj;
uses
forms, windows, sysutils, classes, dialogs, db, dbtables,
example in 'example.pas' {form1};
{创建一个tobject的派生类tmyclass}
type
tmyclass=class(tobject)
public
procedure myexceptionhandler(sender: tobject; einstance: exception);
end;
{编写自己的异常处理句柄}
procedure tmyclass.myexceptionhandler(sender: tobject; einstance: exception);
var
errorfile:textfile;
filename,content:string;
findflag:boolean;
begin
{截获出现的新的异常,并存入文件errorinfo.txt.}
filename:=applicationpath+'errorinfo.txt'; { applicationpath 是在主form中定义的全局变量,记录应用程序所在的目录}
{打开文件}
assignfile(errorfile,filename);
if not fileexists(filename) then
rewrite(errorfile)
else
reset(errorfile);
{检查出现的异常是否曾经记录在文件errorinfo.txt中}
findflag:=false;
while not seekeof(errorfile) do
begin
readln(errorfile,content);
if pos(einstance.classname+':'+einstance.message,content)<>0 then
begin
findflag:=true;
break;
end;
end;
{如果是一个未被记录过的异常,则将它记录在文件中}
if not findflag then
begin
showmessage('出现新的错误!');
append(errorfile);
writeln(errorfile,einstance.classname+':'+einstance.message);
end;
{关闭文件}
closefile(errorfile);
{对出现的异常显示中文提示}
if einstance is edivbyzero then
application.messagebox('除数不能为零!','错误',mb_ok+mb_iconstop)
else if einstance is eaccessviolation then
application.messagebox('访问了无效的内存区域!','错误',mb_ok+mb_iconstop)
else if (einstance is edatabaseerror) then
application.messagebox('数据库操作出现错误!','错误',mb_ok+mb_iconstop)
else if (einstance is efopenerror) then
application.messagebox('文件不能打开!','错误',mb_ok+mb_iconstop)
else if (einstance is econverterror) then
application.messagebox('非法的类型转换!','错误',mb_ok+mb_iconstop)
else
messagedlg(einstance.classname+':'+einstance.message,mtinformation,[mbok],0)
end;
{$r *.res}
var
myobject: tmyclass; {声明tmyclass类的一个变量}
begin
application.initialize;
application.createform(tform1, form1);
applicationpath:=extractfilepath(application.exename);
myobject:=tmyclass.create; {创建tmyclass类的一个实例}
application.onexception:=myobject.myexceptionhandler; {响应onexception事件}
application.run;
end.
例7中的myexceptionhandler 事件是我们在开发铁路车站行车工作细则管理系统时编制的,由于篇幅所限,在此仅将这一事件的整体框架呈现给大家,希望通过这个例子来说明开发异常处理句柄的方法。
到此为止,我们对delphi异常处理的几种方法由浅入深地进行了归纳,并对应于各种方法列举了实例,希望对异常处理怀有“胆怯”心理的编程朋友有所帮助。当然,在遇到具体问题的时候,还需要您选择最适合的异常处理方法。
发表评论
-
form打开时的关闭代码
2011-10-25 20:29 1571摘自:http://topic.csdn.n ... -
TUpdateSQL更新问题 提示Update Failed
2011-08-29 20:26 1238摘自:http://topic.csdn.net/u/200 ... -
图解如何用Eurekalog跟踪程序错误
2011-08-12 07:28 940图解如何用Eurekalog跟踪程序错误 摘自:h ... -
VirtualBox 复制VDI 并能创建新的虚拟机
2011-07-21 11:14 2738摘自:http://www.nonabyte.net/how- ... -
delphi exe程序以及DLL程序如何在模块内部获得各自的路径
2011-07-11 16:38 1304delphi Exe程序以及DLL程序如何在模块内部获得各自的 ... -
Delphi文本文件读写
2011-07-11 14:55 1239Delphi文本文件读写 (2008-10-31 1 ... -
Delphi自定义的消息的使用
2011-05-31 14:12 2315阅:已验证,可通过; 摘自:http://blog.1 ... -
怎么查看OutputDebugString输出的信息?debugview
2011-05-25 16:02 3834网上很多说用debugview查看,我自己写了一个程序,里面用 ... -
Delphi里查看该变量的内存值
2011-05-25 13:32 1121Delphi里查看该变量的内存值:Run==>Evalu ... -
注册表操作 写入autorun启动项,键值为本程序的全路径
2011-05-20 15:40 1824procedure TForm4.Button2Click ... -
报说包frx7和frxdb7都包含了某个单元的错误
2011-05-11 09:59 10211. 问题描述:在安装FastReport3的时候,安装到- ... -
Delphi中使用ListView和TreeView的Item中的Data可能被忽略的内存泄漏
2011-05-03 14:34 1461摘自:http://blog.csdn.net/g ... -
WM_USER的说明 用户消息ID
2011-04-28 10:46 1686WM_USER 摘自:http://baike.bai ... -
ToolButton不能改变大小
2011-04-28 10:38 3461问题描述:ToolButton不能改变大小? 问 ... -
Delphi里TOOLBAR 上的button的caption为什么显示不出来啊
2011-04-20 17:55 1767Delphi里TOOLBAR 上的button的caption ... -
delphi指针简单入门
2011-04-11 21:42 1154摘自:http://topic.csdn.net/t/2003 ... -
Delphi中paramstr的用法 应用程序间传递数据
2011-04-01 14:33 2103Delphi中paramstr的用法 应用程序间传递数据 ... -
Delphi中的THashedStringList对象 --大数据量时
2011-04-01 13:54 5146Delphi中的THashedStringLi ... -
inherited Create(AOwner); 和直接写inherited有区别吗
2011-03-26 15:44 1323摘自:http://zhidao.baidu.com/que ... -
delphi中的Create,Send,Sender,Self
2011-03-26 14:08 1463摘自:http://www.cnblogs.com/keyco ...
相关推荐
通过以上步骤,我们可以实现在不修改原始代码的情况下,动态地为方法添加异常处理逻辑。这不仅可以提高代码的整洁度,还能方便地在整个应用程序中统一异常处理策略。 在提供的"ExinScada.Aop"压缩包中,可能包含了...
异常截获是指在程序中设置特定的处理程序,以便在出现错误或异常时能够捕获并处理它们,而不是让程序崩溃。这篇文档将详细探讨如何在VC++中实现应用程序的异常截获。 首先,我们需要了解C++的异常处理基础。C++的...
这意味着,如果要在所有进程中截获事件,需要在系统全局范围(例如,从服务或后台进程中)安装钩子。 9. **安全与兼容性问题**: 全局钩子可能影响其他应用程序的性能,因此应当谨慎使用。此外,系统权限和反作弊...
测绘资料-百度地图截获器(矢量版)1.0Bete(刘俊环版权所有).zip 这个压缩包文件主要包含了用于测绘领域的工具——百度地图截获器的一个版本,具体为矢量版的1.0Beta。这个工具是由刘俊环个人开发并拥有版权,它...
标题“iPhone异常截获”指的是在iOS开发过程中,如何捕获和处理运行时出现的异常情况,这通常涉及到编程错误或者不可预见的用户行为。在iOS应用开发中,尤其是使用Objective-C或Swift语言时,正确地处理异常是保证...
总之,“利用WM_SYSMSGFILTER钩子截获系统所有的消息(改良版1)”是一个涉及Windows编程底层机制的项目,它要求开发者对Windows消息机制有深入的理解,并能够熟练运用Visual C++进行系统级别的编程。通过这种方式,...
### 雷达信号截获与分析 #### 一、引言 《雷达信号截获与分析》一书由雷达信号领域著名专家、IEEE会员Richard G. Wiley博士撰写,是国防电子信息技术丛书中的一本重要著作。该书系统地介绍了雷达电子对抗中的关键...
开发者可以通过`catch`语句捕获特定类型的异常,或者使用`catch...else`来捕获所有未被特定`catch`块处理的异常。此外,易语言还提供了`finally`关键字,用于在无论是否发生异常的情况下都需要执行的清理代码,如...
本资源"vc++通过钩子截获exe收到的所有消息.zip"提供了一个使用Visual C++实现的示例,展示了如何通过钩子函数来截获并处理一个可执行文件(exe)接收到的所有消息。 首先,让我们了解一下钩子(Hook)的基本概念。...
封包截获器通过操作系统提供的网络接口(如WinPCap或Libpcap)来捕获这些数据包,不改变其原有的流向,只是默默地观察和记录。这种“嗅探”技术是网络分析、安全检测和性能优化的基础。 易语言,作为一种中文编程...
例如,`tcpdump -i eth0 host 192.168.1.1` 将捕获与指定IP地址(192.168.1.1)通信的所有数据包。 在网络安全方面,IP数据包截获有助于检测潜在的入侵和攻击。例如,通过对网络流量的实时监控,可以发现异常的连接...
总的来说,网络数据截获在Java中实现并不复杂,关键在于理解网络协议和数据包结构,并选择合适的库来实现。通过这个技术,开发者可以深入洞察网络行为,从而提升应用性能,排查网络问题,甚至增强系统安全性。
在某些情况下,我们可能需要去截获Linux操作系统的一些异常处理,比如截获page fault异常处理。 可以修改内核的情况下: 如果我们能够修改内核,那么截获page fault异常处理会非常简单。以linux 3.8.0内核为...
UDP则是一种无连接的、不可靠的协议,它不保证数据包的顺序或完整性,但具有更高的传输速度。在Delphi中,我们可以使用UDPServer和TUDPClient组件来处理UDP通信。UDPServer监听特定端口,接收到数据后触发事件;...
windows防火墙与网络封包截获技术 请烦劳再下载part2部分,由于上传文件不能大于10M。。。。 第一章 windows网络协议架构 第二章 编程环境VC构建 第三章 用传输层过滤驱动程序截获网络封包 第四章 用...
在这个问题中,“密码截获”是一个典型的算法挑战,常见于国际大学生程序设计竞赛(ACM,International Collegiate Programming Contest)中。ACM比赛旨在锻炼学生的算法设计、编程和问题解决能力。这类问题通常涉及...
windows防火墙与网络封包截获技术 请烦劳再下载part1部分,由于上传文件不能大于10M。。。。 第一章 windows网络协议架构 第二章 编程环境VC构建 第三章 用传输层过滤驱动程序截获网络封包 第四章 用...
MediaBox 截获视频流 开始: 1、解压以上工具,接着打开名字为“MediaBox”的软件,这是一个截获视频流的... ” 再加刚才那个视频格式,当然有些后面已经有视频格式的就可以不加。这样就得到一个完整的电视直播源。
API截获技术的优势在于它不需要修改源代码、重新编译和连接,也不需要替换任何动态连接库,从而实现了对应用程序和操作系统环境的透明监控。此外,该技术还可以实现分线程实时显示日志信息,使用户能够即时了解软件...