Delphi表单所有者在组件的FormClose中跳过ShowMessage / Dialog调用

时间:2010-01-21 15:30:15

标签: delphi delphi-2010

我的Delphi 2010应用程序有许多由mainform创建和拥有的非模态表单。其中一个表单有一个formclose过程,弹出一个对话框,询问用户是否要保存更改。如果用户关闭了mainform,则会调用“拥有”表单的FormClose过程,但是不显示该对话框,并且用户没有机会保存。

有什么建议吗?我可以看到在调试器中调用过程,但它似乎只是跳过对话框。同样的事情发生在showmessage上。所有者是否以某种方式覆盖了这些对话框的实际显示?

由于

生锈

3 个答案:

答案 0 :(得分:2)

这种事情应该放在OnCloseQuery事件中。在处理程序中将CanClose设置为false以中止关闭(这或多或少是标准的:在这些情况下,是,否和取消是通常的答案,取消中止关闭过程)。

答案 1 :(得分:2)

当主窗体关闭时,应用程序终止,释放主窗体,从而释放它所拥有的窗体。拥有的表单没有关闭,只是被释放,因此他们的OnClose事件通常不会被触发。

如果您看到ShowMessage从拥有的表单的OnClose事件中调用,但对话框未显示,则可能是因为应用程序已终止且不再处理消息。这意味着拥有的表单的OnClose事件由您自己的代码中的某个地方触发,但为时已晚。

重现此行为的一种方法是将WM_CLOSE消息从主窗体的OnClose事件发布到拥有的表单。然后,当应用程序已经终止任何尝试调用ShowMessage或任何模态形式不再有效时,由所拥有的表单处理该消息。

我同意迈克尔的观点,OnCloseQuery更适合向用户显示提示。不幸的是,由于所拥有的表格没有被关闭,所以这一点无济于事。您必须手动调用他们的OnCloseQuery事件,例如:

procedure TFormMain.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
var
  I: Integer;
begin
  CanClose := False;
  for I := 0 to ComponentCount - 1 do
    if Components[I] is TCustomForm then
      if not TCustomForm(Components[I]).CloseQuery then
        Exit;
  CanClose := True; // or another check if the main form can be closed, too
end;

答案 2 :(得分:0)

我最近遇到了这些问题。我发现只需添加代码:

if not Visible then
  Show;
BringToFront;
在显示保存更改对话框之前

结束所有混乱。如果父窗体不可见,则会显示父窗体,并以zorder向上移动到堆的前面,然后在其上方显示对话框。