如何忽略Delphis MessageDlg中的计时器事件

时间:2013-11-22 11:31:29

标签: delphi delphi-2006

我在Delphi中设置了一个全局异常处理程序。在某些严重的异常上会显示一条错误消息(后跟Halt())。当显示错误消息时,Delphi正在处理消息队列,处理计时器事件,这会导致进一步的错误。

我想要的是显示一个不处理计时器事件的错误对话框。这怎么可能在Delphi中?

编辑:我使用Dialogs.MessageDlg(...)来显示消息。

3 个答案:

答案 0 :(得分:4)

您可以使用TApplication.OnMessage过滤排队的消息,例如WM_TIMER

procedure TMainForm.ApplicationMessage(var Msg: TMsg; var Handled: Boolean);
begin
  if ShowingFatalErrorDialog then
    if Msg.Message = WM_TIMER then
      Handled := True;
end;

将该事件处理程序直接分配给Application.OnMessage或使用TApplicationEvents对象。

显然你必须提供ShowingFatalErrorDialog的实现,但我相信你很明白如何这样做。

答案 1 :(得分:2)

尝试这样的事情:

    ...
  private
    FAboutToTerminate: Boolean;
  end;

...

type
  ESevereError = class(Exception);

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  Tag := Tag + 1;
  if Tag > 2 then
    raise ESevereError.Create('Error');
end;

procedure TForm1.ApplicationEvents1Exception(Sender: TObject;
  E: Exception);
begin
  if (E is ESevereError) and (not FAboutToTerminate) then
  begin
    FAboutToTerminate := True;
    Application.ShowException(E);
    Application.Terminate;
  end;
end;

答案 2 :(得分:1)

仅供参考:我将使用以下代码,这是两个答案的混合。

procedure SaveShowErrorMessage(...)
begin
    with TFatalErrorAppEvents.Create(nil) do  //avoid timer and further exceptions
    try
      Dialogs.MessageDlg(...);
    finally
      Free;
    end;
end;

使用TFatalErrorAppEvents如下:

type
    TFatalErrorAppEvents = class(TApplicationEvents)
    protected
        procedure KillTimerMessages(var Msg: tagMSG; var Handled: Boolean);
        procedure IgnoreAllExceptions(Sender: TObject; E: Exception);
    public
        constructor Create(AOwner: TComponent); override;
    end;


constructor TFatalErrorAppEvents.Create(AOwner: TComponent);
begin
    inherited;
    OnMessage := KillTimerMessages;
    OnException := IgnoreAllExceptions;
end;

procedure TFatalErrorAppEvents.IgnoreAllExceptions(Sender: TObject; E: Exception);
begin
    //in case of an Exception do nothing here to ignore the exception 
end;

procedure TFatalErrorAppEvents.KillTimerMessages(var Msg: tagMSG; var Handled: Boolean);
begin
    if (Msg.message = WM_TIMER) then
      Handled := True;
end;