我很恳请您就我在Delphi中遇到的以下问题提出建议try/except.
我有一个简单的应用程序 - 一个命名的MainForm fr_MAIN和一个TDataModule命名的DM.DM是不是自动创建的,但它在运行时创建fr_MAIN的Button2.OnClick事件:
procedure Tfr_MAIN.Button2Click(Sender: TObject);
begin
try
DM := TDM.Create(nil);
Showmessage('DM started!');
except
on E:Exception do
begin
Showmessage('DM not started!');
end;
end;
Run Code Online (Sandbox Code Playgroud)
DM在它的OnCreate事件中有一些代码:
procedure TDM.DataModuleCreate(Sender: TObject);
begin
raise Exception.Create('this is error!');
// DM code here ...
end;
Run Code Online (Sandbox Code Playgroud)
问题是当我点击时Button2,我收到'this is error!'异常消息,其余的DM code here没有运行 - 这是正确的!但后来我也收到了'DM started!'消息而不是'DM not started!'消息.
通过DM中断动作引发的异常,但不会在except窗体的块中被捕获!
为什么是这样?
Tom*_*erg 21
TDataModule1对其OnCreate事件中引发的异常进行了特殊处理.
这里处理异常:
procedure TDataModule.DoCreate;
begin
if Assigned(FOnCreate) then
try
FOnCreate(Self);
except
if not HandleCreateException then // <-- here
raise;
end;
end;
function TDataModule.HandleCreateException: Boolean;
begin
if Assigned(ApplicationHandleException) then
begin
ApplicationHandleException(Self); // <-- here
Result := True;
end
else
Result := False;
end;
Run Code Online (Sandbox Code Playgroud)
默认情况下,TApplication分配TApplication.HandleException()给ApplicationHandleException:
constructor TApplication.Create(AOwner: TComponent);
var
...
begin
inherited Create(AOwner);
...
if not Assigned(System.Classes.ApplicationHandleException) then
System.Classes.ApplicationHandleException := HandleException; // <-- here
if not Assigned(System.Classes.ApplicationShowException) then
System.Classes.ApplicationShowException := ShowException;
...
end;
Run Code Online (Sandbox Code Playgroud)
因此,TDataModule.DoCreate()捕获异常并将其传递给它TApplication.HandleException(),然后默认显示一个弹出对话框.从那时TDataModule.HandleCreateException()起返回True,捕获的异常不会重新引发.此异常现在被视为已处理,允许程序正常继续其Showmessage('DM started!');调用.
要在引发异常时避免弹出对话框,您可以分配一个TApplication.OnException事件处理程序:
Vcl.Forms.TApplication.OnException
使用OnException更改应用程序代码未处理异常时发生的默认行为.在HandleException方法中自动调用OnException事件处理程序.
但这个例外仍然会被抓住并被驳回TDataModule.DoCreate().如果你想避免这种情况,那么异常会在调用堆栈中传播,不要从TDataModule.OnCreate事件中引发异常.重写虚拟TDataModule.Create()构造函数并从那里引发异常.
1:同样的事情也发生在TCustomForm.
| 归档时间: |
|
| 查看次数: |
434 次 |
| 最近记录: |