参考文章:
MFC 模态对话框和非模态对话框
MFC 创建非模态对话框和销毁过程
模态与非模态对话的创建
/*
1. 创建对话框对象
该步骤仅创建了一个对话框窗口的框架,dlg的成员中
并不包含窗口句柄,即还没有创建
*/
CDialog dlg;
// 2. 模态对话框
dlg.DoModel();
// 3. 非模态对话框
BOOL bRet = dlg.Create(IDD_DIALOG1, this);
if (bRet)
{
dlg.ShowWindow(SW_SHOW);
}
对话框的销毁
- 模态对话框:
点击关闭后,调用 OnCancel() ——> EndDialog(),该函数会退出模态对话框的消息循环,并依次调用一系列函数来销毁对话框资源。 - 非模态对话框
点击关闭后, 调用 OnCancel()
对两种对话框的理解(个人理解)
-
非模态对话框就是对 win32 的一般性封装,与MFC对各种win32对象的封装过程类似,如各种控件。
-
模态对话框是对非模态对话框的进一步封装,因为模态对话自己管理自己窗口资源的销毁。
-
OnOk 和 OnCancel 是 CDialog的虚函数,OnClose则是CWnd的虚函数;
-
DestroyWindow的作用就是销毁窗口,注意,只销毁“窗口”,但不销毁“窗口对象”
-
OnOk,OnCancel,OnClose(WM_CLOSE默认代码会调用OnClose),其中OnOk和OnCancel是CDialog的虚函数,OnClose则是CWnd的虚函数;因此关闭模态对话框的时候,先调用基类的 OnClose,然后调用 OnCancel;
-
当单击对话框上的默认OK按钮时,两种对话框都会消失。但对于模态对话框而言,此时对话框窗口对象被销毁了;而对非模态对话框来说,对话框窗口对象并未被销毁,只是隐藏起来而已。
在非模态对话框中单击OK按钮后,程序会调用基类CDialog的OnOK函数,这是一个虚函数,后者又会调用EndDialog函数,这个函数用于终止模态对话框,但对于非模态对话框,这个函数只是使对话框窗口不可见,并不销毁它,这是模态与非模态窗口销毁方式不同的根本原因。因此,对非模态对话框来说,如果有一个ID值为IDOK的按钮,就必须重写基类的OnOK虚函数,并在重写的函数中调用DestroyWindow函数,以完成销毁对话框的工作,同时注意不要再调用基类的OnOK函数。同理,如果非模态对话框中有一个ID值为IDCANCEL的按钮,也必须重写基类的OnCancel虚函数,并在重写的函数中调用DestroyWindow函数,销毁对话框,同时注意不要再调用基类的OnCancel函数了。
非模态对话框相对于模态对话框,他的创建和销毁过程和模态对话框有一定的区别