转载来自:https://blog.csdn.net/dyzhen/article/details/6836672
本文中用到的术语:
窗口:指的是窗口
窗口对象:指的是与窗口关联的C++对象
注:本文说的非模态对话框指的是在堆中创建的(new出来的)。
1.模态对话框之所以能垄断输入,是因为它拥有自己的消息循环,而非模态对话框与父窗口共用一个消息循环
2.对一个对话框来说,窗口的销毁必须在窗口对象的销毁之前
3.关于DestroyWindow
(1)DestroyWindow是CWnd的虚函数,而不是CDialog层次的。(CDialog派生自CWnd)
(2)DestroyWindow的作用就是销毁窗口,注意,只销毁“窗口”,但不销毁“窗口对象”
(3)DestroyWindow既然销毁了窗口,为了让用户在这之后有个工作的机会,它会给窗口对象发送WM_DESTROY和WM_NCDESTROY两个消息,用户便可以在这两个消息的响应函数中加入自己需要处理的内容
(4)WM_DESTROY与DestroyWindow无关,DestroyWindow也不是WM_DESTROY的消息响应函数
(5)WM_DESTROY只是一个窗口被销毁后系统发出的一个消息而已,它跟销毁“窗口”没有任何关系
4.模态对话框的销毁
(1)模态对话框的”窗口对象“的销毁通常是不需要特殊处理的,因为它通常都是分配在栈上的(比如局部变量或成员变量),系统会自动处理释放
(2)模态对话框的”窗口“的销毁
a. 模态对话框”窗口”的销毁通过三种途径:OnOk,OnCancel,OnClose(WM_CLOSE默认代码会调用OnClose),其中OnOk和OnCancel是CDialog的虚函数,OnClose则是CWnd的虚函数
b.OnOk或OnCancel内部调用了CDialog::EndDialog函数,EndDialog内部调用了DestroyWindow,而OnClose内部则直接调用了DestroyWindow,即它们都最终通过DestroyWindow实现了“窗口”的销毁
5.非模态对话框的销毁
(1)非模态对话框的“窗口”的销毁
a.根据前面的描述,销毁一个“窗口”必定是靠DestroyWindow,也必定是通过OnOk或OnCancel或OnClose函数
b.与模态对话框不同的是,对于OnOk或OnCancel,OnClose,都必须显式调用DestroyWindow,而且,不能调用默认的CDialog::OnOk或CDialog::OnCancel或CDialog::OnClose,至于原因,反正MSDN上是这么说的Do not call the base-class method, because it callsEndDialog, which makes the dialog box invisible but does not destroy it.;
(2)非模态对话框的“窗口对象”的销毁
a. 根据前面所述,销毁“窗口”的时候要使用DestroyWindow,而DestroyWindow会发送WM_NCDESTROY消息,所以就可以在WM_NCDESTROY消息响应函数PostNcDestroy中调用delete this,从而销毁自己。
b.另外,如果不delete,则对话框关联的GDI对象也不会释放,由此看出,GDI对象并不是跟“窗口”绑定的,二是跟“窗口对象”绑定的。