模态对话框与非模态对话框的销毁

转载来自: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对象并不是跟“窗口”绑定的,二是跟“窗口对象”绑定的。

原文地址:https://www.cnblogs.com/Galesaur-wcy/p/14246334.html