一、由程序员用new的方法创建的窗体事件驱动链
在程序中无数次地见到过以下代码:
|
TfrmConstant *pForm=new TfrmConstant(this); //创建一个窗体
pForm->Show();
……
delete pForm; |
我们经常需要动态创建一个Form,再显示它,然后在合适的地方销毁它。
请注意上面代码中的this参数,它被传送给TfrmConstant窗体的构造函数,这一构造函数有一个唯一的形参——Owner。这个参数决定了由谁负责销毁它。
在BCB的帮助文件中对Owner参数的描述如下:
Owner描述了谁负责销毁这个组件。
使用Owner参数来存取component所有者的接口。当一个组件拥有另一个组件时,当父组件内存被释放时,子组件所占的内存资源也被释放。这就是说,当一个窗体被销毁时,窗体上的所有组件也会被删除。
缺省情况下,一个窗体拥有放在其上的所有组件,同样地,Application对象则拥有所有的Form对象。这样,当程序结束时,Application对象会释放所有Form占用的资源。
下面是我对Owner参数的实验记录
实验一:主窗体(Form1)new一个普通窗体(Form2),Owner=this Form1中的代码示例:
p2=new TForm2(this);
p2->Show();
创建:
先创建完主窗体后,只调用普通窗体Form2的构造函数,不管显不显示,事件驱动链与以前的实验一样。
关闭:
主窗体:OnCloseQueryàOnCloseàOnHide()àOnDestory()à主窗体析构函数àForm2析构函数
关闭次序是先主窗体再普通窗体,如果创建了多个普通窗体,根据创建的先后顺序按后创建先销毁的原则逐个销毁窗体:
普通窗体是显示还是隐藏对事件驱动链无影响
实验二:主窗体(Form1) new一个普通窗体Form2,Owner=Application
创建:
同实验一
关闭:
首先是Form1:OnCloseQuery()àOnClose()àForm2析构函数(如果有多个,按照后进先出的次序调用) àForm1:OnHide()àOnDestory()àForm1析构函数.
实验三:主窗体(Form1) new一个继承窗体(Form2继承自Form1),Owner=this
创建:
创建主窗体Form1,事件链同单窗体的创建;
接着在代码中开始new Form2:
Form2 OnCreate()àForm1的构造函数àForm2 的构造函数à创建结束
我们看到要先调用父类的构造函数
关闭:
1.Form2未显示:
Form1: OnCloseQuery()àOnClose()àOnHid()eàOnDestory()àForm1的析构函数
àForm2的析构函数à Form1的析构函数à Form2 OnDestory()
注意:并无Form1的OnDestory,同样地:Form1的析构函数被执行了两次
2.Form2显示情况下::
Form1: OnCloseQuery()àOnClose()àOnHide()àOnDestory()àForm1的析构函数
Form2 OnHide()à Form2的析构函数à Form1的析构函数à Form2 OnDestory
仅多了一个Form2 OnHide()过程
实验四:主窗体new一个继承窗体(Form2继承自Form1),Owner=Application:
创建(Form2不显示情况):
Form2 OnCreate()àForm1的构造函数à Form2的构造函数
关闭(Form2不显示情况)
Form1 OnCloseQuery()àOnClose()àForm2的析构函数à Form1的析构函数à Form2 OnDestory()àMainForm HideàMainForm的析构函数à MainForm 的析构函数
创建(Form2显示情况):
Form2 OnCreate()àForm1的构造函数à Form2的构造函数à Form2 OnShow()à ……à Form2:OnResize()
多了一个显示的事件
关闭(Form2显示情况)
Form1: OnCloseQuery()àOnClose()à Form2 :OnHide()àForm2的析构函数à Form1的析构函数à Form2 OnDestory()
àForm1 OnHide()àForm1 OnDestoryà MainForm1析构函数