我在Delphi中设置了一个全局异常处理程序。在某些严重的异常上会显示一条错误消息(后跟Halt())。当显示错误消息时,Delphi正在处理消息队列,处理计时器事件,这会导致进一步的错误。
我想要的是显示一个不处理计时器事件的错误对话框。这怎么可能在Delphi中?
编辑:我使用Dialogs.MessageDlg(...)来显示消息。
答案 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;