【问题标题】:Delphi - Secondary form's OnClose handler is not calledDelphi - 不调用辅助窗体的 OnClose 处理程序
【发布时间】:2014-01-21 16:44:18
【问题描述】:

我有一个主窗体和另一个“辅助”窗体。如果我先关闭第二个,它的OnClose 处理程序会被调用。不幸的是,如果我先关闭主窗体,应用程序将终止,并且不会调用辅助窗体的 OnClose。这是一个问题,因为我想在每个表单关闭之前保存它们的位置和大小。我该如何解决这个问题?

【问题讨论】:

    标签: forms delphi


    【解决方案1】:

    处理这个问题的一个好地方是主窗体的OnCloseQuery 事件。

    procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
    var i : integer;
    begin
      CanClose := true;
      if Application.MainForm = self then begin
        CanClose := MessageDlg('Close the application?', mtConfirmation,
                                              [mbYes, mbNo], 0) = mrYes;
        if CanClose then
          for i := 0 to Screen.FormCount - 1 do
            if Screen.Forms[i] <> self then Screen.Forms[i].Close;
      end;
    end;
    

    上面建议的第一个检查仅在您有多个正在使用的主窗体实例时才有用。对self 进行第二次检查是必要的,以防止再次进入。

    【讨论】:

    • 谢谢,我选择了这种方法,因为我也必须保存Visible 属性。在OnDestroy 中始终是False,但在调用主窗体的OnCloseQuery 处理程序时它具有正确的值。
    • 不保证 OnCloseQuery 会被调用。详情:groups.google.com/forum/#!msg/…
    • @NAZCA 不,如果程序调用Application.Terminate,它将不会被调用——大概如果你这样做是因为你确实希望应用程序立即终止。在 Windows 关闭期间处理强制终止是完全不同的问题,应单独处理。请参阅:stackoverflow.com/q/10745151/327083
    【解决方案2】:

    您可以使用 OnDestroy 而不是 OnClose 来保存它。而且您可能应该在关闭后销毁您的辅助表单(在打开之前创建):

    Form2 := TForm2.Create(Application);
    Form2.Open;
    

    在 Form2.OnClose 中:

    Action := caFree;
    

    您还需要删除 .dpr 中自动创建辅助表单的行:

    Application.CreateForm(TForm2, Form2);
    

    也许禁用这个自动创建。在 D7 中:工具>>环境选项>>设计器>>禁用“自动创建...”

    执行所有这些操作将为您节省一些内存。当您希望用户在返回主窗体之前关闭辅助窗体时,还可以考虑使用 ShowModal 而不是 Show。

    【讨论】:

    • 谢谢,OnDestroy 总是会被调用。唯一的问题是我也想保存可见性,但VisibleOnDestroy 中始终是False :(
    • 不保证会调用 OnDestroy。详情:groups.google.com/forum/#!msg/…
    猜你喜欢
    • 2011-05-13
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2010-10-12
    • 2016-05-02
    相关资源
    最近更新 更多