我有一个用 Delphi 2007 编写的 MDI 应用程序。
如果用户在执行代码时退出其中的表单,则会导致异常,因为代码正在尝试更新组件或使用已随表单释放的对象。
无论如何我可以判断代码是否在退出事件中执行,或者是否有处理这种情况的标准方法?
更新更多信息
异常通常发生在以下情况。
子 mdi 表单上的一个按钮被按下,这将激活表单中的一个功能,该功能将进入数据库并检索数据,然后它将重新格式化并将其显示在表单上的可视组件中(可用 TListView )。
如果代码需要很长时间执行(例如,如果有很多数据要处理),用户将失去兴趣并单击关闭按钮(代码的速度正在努力避免这种情况)。
即使它所属的表单已被释放,函数内部的代码仍在执行(代码位于表单的私有部分),现在当它尝试更新它们不再存在的可视组件时(因为它们被释放了表单),它会引发异常。
发生这种情况时,子表单中的代码可以在循环中使用,循环记录并相应地更新列表视图,循环包含看起来像这样的代码
inc(i);
if (i mod 25) = 0 then
begin
StatusPnl.Caption := 'Loading ' + intToStr(i) + ', Please wait';
application.ProcessMessages;
end;
其他代码示例
fromClose 事件看起来像这样
//Snip
if (Not (Owner = nil)) then
with (Owner as IMainForm)do
begin
//Snip
DoFormFree(Self,Self.Name);
end
else
//Snip
DoFormFree 是主 mdi 父窗体中的一个函数,看起来像这样
//Snip
(G_FormList.Objects[x] as TBaseForm).Release;
G_FormList.Objects[i] := nil;
G_FormList.Delete(i);
//Snip
由于各种原因,所有表单都存储在一个列表中,并且所有子表单都扩展了 TBaseForm 类。
理想情况下,我想要一种方法来判断表单中的代码是否正在执行,并防止用户关闭表单,或者在代码完成之前隐藏它,因为在某些情况下,它可能会生成报告并更新为状态面板发生异常,在这种情况下,报告将不完整。
因为所有表单都是 TbaseFrom 的子类,所以某种全局方式这样做是理想的,所以我可以将代码添加到基本表单并让它适用于所有下降的表单。