【问题标题】:Why is an owned form destroyed after the owner form itself?为什么拥有的表单在所有者表单本身之后被销毁?
【发布时间】:2014-12-09 22:50:11
【问题描述】:

我有一个在运行时动态创建第二个表单的主表单。当调用 create 方法时,第二个窗体的所有者设置为主窗体。当我关闭应用程序时,主窗体的 FormDestroy 在第二个窗体的 FormDestroy 之前被调用。

通常我会建议所有者销毁所有拥有的表单,然后销毁自己。

为什么表单销毁顺序是这样的?

【问题讨论】:

    标签: forms delphi


    【解决方案1】:
    • 表单的OnDestroy 事件从其BeforeDestruction 方法触发。
    • 组件从其析构函数中销毁其拥有的组件。

    BeforeDestruction 方法在析构函数之前执行,因此是您观察到的行为。

    在这种情况下,拥有的组件在其所有者之前被销毁。想象一下,情况正好相反。如果所有者首先被销毁,则拥有的组件列表将被销毁,并且无法销毁拥有的组件。

    让您感到困惑的是,当所有者开始其销毁过程时,会发生许多事情,然后才能销毁任何拥有的组件。其中之一就是触发它自己的OnDestroy 事件。

    主窗体销毁的调用树看起来有点像这样:

    TMainForm.BeforeDestruction
      TCustomForm.BeforeDestruction
        TCustomForm.DoDestroy
          TMainForm.FormDestroy  --> this is your main form's OnDestroy event handler
    TMainForm.Destroy
    TForm.Destroy
    ....
    TComponent.Destroy
      DestroyComponents;         --> owned components are destroyed here
    ....
    

    当主窗体从其TComponent.Destroy 内部调用DestroyComponents 时,所有拥有的组件都已被销毁。然后主窗体完成销毁过程,然后它也被销毁了。

    【讨论】:

    • 我可以看到这种排序的另一个优点:在表单的事件处理程序中,所有表单的组件都肯定存在。同样,表单的OnCreate 事件仅在所有(预配置)拥有的组件创建后触发。在这两种情况下,它都有助于 RAD 在所有基本事件中提供一切。
    • 为了完整起见,DoDestroy()BeforeConstruction() 中调用如果OldCreateOrder 属性为假(通常是这样),否则DoDestroy() 被调用取而代之的是表单的 Destroy() 析构函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-16
    • 2012-01-30
    • 2015-08-16
    • 1970-01-01
    • 2015-04-24
    • 2020-08-15
    相关资源
    最近更新 更多