在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】:

据我了解,ZeroMemorySecureZeroMemory 之间的唯一区别是 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 中,除了 ZeroMemoryFillChar 和 #0)之外,没有任何需要使用此功能。 在 kernel32.dll 中的任何位置都找不到 RtlSecureZeroMemory、SecureZeroMemory、RtlZeroMemory 或 ZeroMemory。这些函数不会在任何 Win32 DLL 中导出。 @seveleven,我刚刚使用 dll 导出查看器工具检查了 kernel32.dll,并且确实 RtlSecureZeroMemory() 存在于 kernel32.dll 中。 但是,我还没有测试 MSDN 语句是否适用于 Delphi,“如果在这个例子中调用 ZeroMemory 而不是 SecureZeroMemory,编译器可以优化调用,因为 szPassword 缓冲区不是从在超出范围之前...”我知道,ZeroMemory() 在 Delphi 中被实现为 FillChar0,但是 MSDN 示例中的案例应该经过经验测试以确保它不适用于 Delphi 程序.【参考方案3】:

我目前没有可用的 Delphi 编译器,但我认为不需要 SecureZeroMemory

我确实记得在 Delphi 中,Win32 API 函数/宏 CopyMemoryMoveMemory相同(它们都被实现为 Move RTL 的指针“版本”功能)。因此,the MSDN CopyMemory reference page 说你必须使用MoveMemory 而不是CopyMemory 的评论是块重叠,是无关紧要的。 Delphi 的Move 总是做出正确的事情。

认为同样的事情适用于ZeroMemorySecureZeroMemory。第一个实现为FillChar 和#0,如果Deplhi 有一个SecureZeroMemory 函数,我认为它也只是一个#0 的FillChar。 (如果 FillChar 有时会被忽略,那么它确实应该记录在 Delphi 参考中,但事实并非如此。)

如有错误请指正!

【讨论】:

【参考方案4】:

Take a look at the MSDN help here.

Delphi 的编译器是否删除 ZeroMemory 作为优化结果的唯一问题, 虽然我对此表示怀疑。

【讨论】:

以上是关于在delphi中使用ApplicationEvents控件,如何调用ApplicationEvents1Exception?的主要内容,如果未能解决你的问题,请参考以下文章

怎么在delphi中读取Excel数据 转

在 Delphi 中使用框架的公认方法是啥?

怎么在delphi中读取Excel数据 转

delphi调用外部程序~~~~~~~~~~~~

delphi中使用HTTP控件,怎么使用POST的异步方式

delphi7中怎样使用Timer这个组件?