在delphi中使用ApplicationEvents控件,如何调用ApplicationEvents1Exception?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在delphi中使用ApplicationEvents控件,如何调用ApplicationEvents1Exception?相关的知识,希望对你有一定的参考价值。
我在编辑框中输入非数字,程序报错,并且“请在编辑框中输入数字”也弹出了,但是在ListBox中没有添加“应用程序发生了一个异常”。
因为异常已经在Button1Click中经由函数中的Try..Except处理了。所以ApplicationEvents自然无法拦截。你可以在except中将这个异常再度抛出。或者是直接在except中。将这个异常直接添加到ListBox1。例如:
procedure TForm1.Button1Click(Sender: TObject);var
i: Integer;
begin
try
i := StrToInt(Edit1.Text) - 5;
ShowMessage('您输入的值减5后的值是: ' + IntToStr(i));
except
on e: EConvertError do
begin
ShowMessage('请在输入框中输入数字!');
//再度抛出一个EConvertError异常,以便于让TApplicationEvents拦截
raise EConvertError.Create(e.Message);
end;
end;
end;
procedure TForm1.ApplicationEvents1Exception(Sender: TObject; E: Exception);
begin
ShowMessage('调用了此过程');
ListBox1.Items.Add('此程序发生了一个异常,异常信息为: ' + E.Message);
end;追问
我试了一下,异常信息是能添加到ListBox中。我输入aa,然后点击button,会弹出
然后我点ok后又弹出
点OK又弹出
点OK又弹出
再点OK,然后异常信息添加到ListBox中了。我觉得既然异常处理了,是不是异常窗口就不应该弹出了?(备注:我是一个小菜鸟。)
Delphi在调试的时候出现异常的话会弹出异常的信息。不管你是否添加了Try..Except。这个我也没有很好的办法。
参考技术A 用e:exception中的e.属性。 参考技术B Application.OnException := ApplicationEvents1.OnException;在 Delphi 中使用 SecureZeroMemory
【中文标题】在 Delphi 中使用 SecureZeroMemory【英文标题】:Using SecureZeroMemory in Delphi 【发布时间】:2010-10-27 07:43:54 【问题描述】:我知道 C 中有一个 SecureZeroMemory
函数。
函数实现在<WinnNT.h>
中定义为RtlSecureZeroMemory
函数。
QNS:SecureZeroMemory
如何在Delphi中使用? Delphi 是否发布了包含该功能的库?我正在使用 Delphi 7。Windows.pas
只有ZeroMemory
,但没有SecureZeroMemory
。
【问题讨论】:
我现在没有 Delphi 编译器和 RTL,但如果我没记错的话,Windows.pas 的ZeroMemory
实际上不是 Windows 的函数API,而是 Delphi 的 FillChar
函数的包装器。
是的,没错。该函数只是一个包装器。
【参考方案1】:
据我了解,ZeroMemory
和 SecureZeroMemory
之间的唯一区别是 SecureZeroMemory
是作为内联函数实现的,以确保它不会被编译器优化。
我不认为 Delphi 执行相同级别的编译器优化,因此不应优化 ZeroMemory
调用。
【讨论】:
我认为你的逻辑颠倒了。ZeroMemory
是内联的,可以优化出来。 SecureZeroMemory
本质上是DLL中的Win32函数,编译时无法优化调用。
@MSalters 我可以知道 SecureZeroMemory 是在哪个 Win32 DLL 中找到的吗?
SecureZeroMemory 不是任何 Win32 DLL 中的公开函数。 @glob 是正确的,SecureZeroMemory 是内联的,如 MSDN 中所述。【参考方案2】:
由于根据MSDN,SecureZeroMemory()实际上定义为RtlSecureZeroMemory()
,你可以声明SecureZeroMemory()
如下:
procedure SecureZeroMemory(_ptr: Pointer; cnt: Longint); external 'kernel32.dll' name 'RtlSecureZeroMemory';
SecureZeroMemory()
只是RtlSecureZeroMemory()
的别名。
【讨论】:
我不知道[Rtl]SecureZeroMemory
是一个导出的DLL函数。但我想您已经尝试过您的代码,因此它是。尽管如此,根据我的回答,我认为在 Delphi 中,除了 ZeroMemory
(FillChar
和 #0)之外,没有任何需要使用此功能。
在 kernel32.dll 中的任何位置都找不到 RtlSecureZeroMemory、SecureZeroMemory、RtlZeroMemory 或 ZeroMemory。这些函数不会在任何 Win32 DLL 中导出。
@seveleven,我刚刚使用 dll 导出查看器工具检查了 kernel32.dll
,并且确实 RtlSecureZeroMemory() 存在于 kernel32.dll
中。
但是,我还没有测试 MSDN 语句是否适用于 Delphi,“如果在这个例子中调用 ZeroMemory 而不是 SecureZeroMemory,编译器可以优化调用,因为 szPassword 缓冲区不是从在超出范围之前...”我知道,ZeroMemory()
在 Delphi 中被实现为 FillChar
和 0
,但是 MSDN 示例中的案例应该经过经验测试以确保它不适用于 Delphi 程序.【参考方案3】:
我目前没有可用的 Delphi 编译器,但我认为不需要 SecureZeroMemory
。
我确实记得在 Delphi 中,Win32 API 函数/宏 CopyMemory
和 MoveMemory
是相同(它们都被实现为 Move
RTL 的指针“版本”功能)。因此,the MSDN CopyMemory
reference page 说你必须使用MoveMemory
而不是CopyMemory
的评论是块重叠,是无关紧要的。 Delphi 的Move
总是做出正确的事情。
我认为同样的事情适用于ZeroMemory
和SecureZeroMemory
。第一个实现为FillChar
和#0,如果Deplhi 有一个SecureZeroMemory
函数,我认为它也只是一个#0 的FillChar
。 (如果 FillChar
有时会被忽略,那么它确实应该记录在 Delphi 参考中,但事实并非如此。)
如有错误请指正!
【讨论】:
【参考方案4】:Take a look at the MSDN help here.
Delphi 的编译器是否删除 ZeroMemory 作为优化结果的唯一问题, 虽然我对此表示怀疑。
【讨论】:
以上是关于在delphi中使用ApplicationEvents控件,如何调用ApplicationEvents1Exception?的主要内容,如果未能解决你的问题,请参考以下文章