【发布时间】:2014-12-09 22:50:11
【问题描述】:
我有一个在运行时动态创建第二个表单的主表单。当调用 create 方法时,第二个窗体的所有者设置为主窗体。当我关闭应用程序时,主窗体的 FormDestroy 在第二个窗体的 FormDestroy 之前被调用。
通常我会建议所有者销毁所有拥有的表单,然后销毁自己。
为什么表单销毁顺序是这样的?
【问题讨论】:
我有一个在运行时动态创建第二个表单的主表单。当调用 create 方法时,第二个窗体的所有者设置为主窗体。当我关闭应用程序时,主窗体的 FormDestroy 在第二个窗体的 FormDestroy 之前被调用。
通常我会建议所有者销毁所有拥有的表单,然后销毁自己。
为什么表单销毁顺序是这样的?
【问题讨论】:
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() 析构函数。