模态对话框创建:

MyDialog mydlg;
mydlg.DoModal()

当前只能运行此模态对话框,且停止主窗口的运行,直到模态对话框退出,才允许主窗口运行。

模态对话框的关闭顺序:

OnClose:按关闭符号X后,响应WM_CLOSE消息

OnKillFocus:窗口即将失去输入焦点,响应WM_KILLFOCUS消息

OnDestroy:窗口即将被销毁时,响应WM_DESTROY消息

OnNcDestroy:窗口被销毁或,响应WM_NCDESTROY消息

PostNcDestroy:由onNcDesyroy调用,是Cwnd虚函数

非模态对话框通常是通过new创建的:

MyDialog *mydlg = new MyDialog;
mydlg->Create(IDD_DIALOG1,this);
mydlg->ShowWindow(SW_SHOW);

非模态对话框关闭顺序:
OnClose:按关闭符号X后,响应WM_CLOSE消息

OnDestroy:窗口即将被销毁时,响应WM_DESTROY消息

OnNcDestroy:窗口被销毁或,响应WM_NCDESTROY消息

PostNcDestroy:由onNcDesyroy调用,Cwnd函数

为了销毁对话框指针,可以在对话框类中重载PostNcDestroy,添加delete this。

void MyDialog::PostNcDestroy()
{
CDialogEx::PostNcDestroy();
delete this;
}

注意:

Onclose函数结束后实际上又调用了Oncannel,Oncannel中调用的是EndDialog(),该函数用于关闭模态对话框。其工作原理为:enddialog是用来结束domodal的循环使用的,domodal内部结束后有destroywindow的调用。但是对于非模态对话框,因其没有domodal循环,故就不会自动调用destroywindow函数,也就没有后续的ondestroy等操作,所以非模态对话框要重载oncannel函数,直接执行destroywindow。

void MyDialog::OnCancel()
{
DestroyWindow();
}

关闭非模态对话框的注意事项MSDN上也有说明[1]:

When you implementa modeless dialog box, always override the OnCancel member function and call DestroyWindow from within it. Don't call thebase class CDialog::OnCancel, because it calls EndDialog, which will make the dialog box invisible but willnot destroy it. You should also override PostNcDestroy for modeless dialog boxes inorder to delete this, since modeless dialog boxes areusually allocated with new. Modal dialog boxes are usuallyconstructed on the frame and do not need PostNcDestroy cleanup
除了点击关闭符号关闭对话框外,MFC还可以通过OnOK(),OnCancle()关闭对话框,二者分别对应默认对话框界面上的”确定”和”取消”按钮,两个函数都是CDialog类的virtual成员函数,两个函数有一个共同点,就是都会调用EndDialog。
因此,若要通过OnOK或OnCancle关闭非模态对话框,则仍需要对其进行重载,使其调用DestroyWindow。
现在实现一个应用:
在一个基于对话框的MFC程序中,点击按钮,弹出另一个子对话框,在弹出的子对话框中输入一串字符串,点击按钮,子对话框关闭,主对话框上显示输入的字符串。
右击资源视图中Dialog标签,选择插入Dialog,双击插入的对话框,进入MFC添加类向导,添加一个与该对话框绑定的对话框类:

我们将添加的dialog编辑成如下形式。编辑框接收输入,点击button1,将从编辑框中取输入,销毁dialog,并将结果传递给父对话框。

主对话框也编辑成相同形式,编辑框用于显示输出,点击button1将产生一个子对话框。

下面分别实现弹出模态和非模态对话框。

(1)模态对话框
父对话框按钮响应:

void CModalTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
Mydialog mydlg;
if(IDOK==mydlg.DoModal())
{
outstr=mydlg.instr;
}
GetDlgItem(IDC_EDITOUTPUT)->SetWindowText(outstr);
}

子对话框的按钮响应:

void Mydialog::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
GetDlgItem(IDC_EDITINPUT)->GetWindowText(instr);//取输入字符串
CDialogEx::OnOK();//关闭对话框并返回IDOK
}

一个MFC窗口对象包括两方面的内容:一是窗口对象封装的窗口,即存放在m_hWnd成员中的HWND(窗口句柄),二是窗口对象本身是一个C++对象。要删除一个MFC窗口对象,应该先删除窗口对象封装的窗口,然后删除窗口对象本身。当Domodal返回时,模态对话框窗口已经销毁,但对话框类仍然存在,股可以直接从mydlg中取输入变量。mydlg属于局部变量,OnBnClickedButton1执行完后,自动销毁。

(2)非模态对话框

父对话框按钮响应:

void CModelessTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
Mydialog *mydlg = new Mydialog;
mydlg->Create(IDD_DIALOG1, this);
mydlg->ShowWindow(SW_SHOW);
}

子对话框按钮响应:

void Mydialog::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
CString *instr=new CString;
GetDlgItem(IDC_EDITINPUT)->GetWindowText(*instr);
HWND parhwnd=GetParent()->m_hWnd;//取得父窗口句柄
::PostMessage(parhwnd,WM_UPDATE,(WPARAM)instr,);//向父窗口发消息
OnCancel();
}

为了将字符串从子对话框向父对话框传递,我们使用了Postmessage发送自定义消息WM_UPDATE。因为父对话框Create了一个非模态对话框后就立即返回了,并不能像对模态对话框那样等待其结束直接取结果。

在子对话框中使用了OnCancle关闭对话框,故需要对其进行重载:

void Mydialog::OnCancel()
{
// TODO: 在此添加专用代码和/或调用基类 //CDialogEx::OnCancel();
DestroyWindow();
}

另外还需重载PostNcDestroy:

void Mydialog::PostNcDestroy()
{
// TODO: 在此添加专用代码和/或调用基类 CDialogEx::PostNcDestroy();
delete this;
}

可以通过MFC类向导找到要重载的虚函数:

在父对话框类中定义消息响应函数,将子对话框发来的消息参数转为字符串显示:

//消息响应函数
LRESULT CModelessTestDlg::Onupdate(WPARAM wParam, LPARAM lParam)
{
CString * outstr =(CString*)(wParam);
GetDlgItem(IDC_EDITOUTPUT)->SetWindowText(*outstr);
delete outstr;
return true;
}

源码:MFC模态非模态对话框

参考:

[1]https://msdn.microsoft.com/en-us/library/132s802t.aspx

[2]http://blog.csdn.net/hanyujianke/article/details/8507064

[3]http://blog.csdn.net/xiaominggunchuqu/article/details/49895325

MFC中的模态对话框与非模态对话框的更多相关文章

  1. MFC中模态对话框和非模态对话框的差别

    在MFC中有模态对话框和非模态对话框,那这两种有什么差别呢. 又都是用于什么场合呢. 首先,要弄清楚2种对话框是怎样创建的. 然后要弄清楚2种对话框有什么差别,可能从表面上看,模态会堵塞主对话框.可原 ...

  2. MFC编程入门之十二(对话框:非模态对话框的创建及显示)

    上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 非模态对话框显示后,程序其他窗口仍然能正常运行,可以响应用户输入,还可以相互切换.上一讲中创建的Tip模态对话框 ...

  3. VS2010/MFC对话框:非模态对话框的创建及显示

    非模态对话框的创建及显示 上一节讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切 ...

  4. VS2010/MFC编程入门之十二(对话框:非模态对话框的创建及显示)

    上一节鸡啄米讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 鸡啄米已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换.鸡啄米会将 ...

  5. c#中的模态对话框和非模态对话框

    模态对话框弹出窗口阻止调用窗口的所有消息响应.只有在弹出窗口结束后调用窗口才能继续.在模态窗口“关闭”后,可以读取模态窗口中信息,包括窗口的返回状态,窗口子控件的值. 非模态对话框可以在弹出窗口和调用 ...

  6. MFC 模态对话框、非模态对话框

    modal dialogs与modeless dialogs,modal dialogs会让原窗体不被选中,modeless dialogs原窗体依然可以选中. 1.模态对话框的显示 DlgModal ...

  7. VC++模态对话框和非模态对话框

    MFC中有两种类型的对话框:模态对话框和非模态对话框.  模态对话框是指当其显示时,程序会暂停执行,直到关闭这个模态对话框后,才能继续执行程序中其他任务.非模态对话框是指当其显示时,允许转而执行程序中 ...

  8. 【VS开发】模态对话框和非模态对话框

    MFC中对话框有两种形式,一个是模态对话框(model dialog box),一个是非模态对话框(modeless dialog box). 一.模态对话框(model dialog box) 在程 ...

  9. VS2010-MFC(对话框:非模态对话框的创建及显示)

    转自:http://www.jizhuomi.com/software/162.html 前面已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换.本节会将上一讲中 ...

  10. QT笔记之模态对话框及非模态对话框

    模态对话框(Modal Dialog)与非模态对话框(Modeless Dialog)的概念不是Qt所独有的,在各种不同的平台下都存在.又有叫法是称为模式对话框,无模式对话框等.所谓模态对话框就是在其 ...

随机推荐

  1. ckplayer 中的style.swf 中的 style.xml 中的修改方法

    style.swf ---- > style.zip ---- > 解压成文件夹 ---- > 打开style.xml ---- > 修改 最重要的是修改保存style.xml ...

  2. 渗透模型 Percolation Models(一个物理模型的广泛应用)

    转自:http://mooc.guokr.com/note/15357/ http://mooc.guokr.com/user/0298406005/note/ 模型思想: 有水流下来,是否会渗入地面 ...

  3. MYSQL进阶学习笔记十四:MySQL 应用程序优化!(视频序号:进阶_32)

    知识点十五:MySQL 的应用程序优化(32) 一.访问数据库采用连接池 把连接当做对象或设备,统一放在‘连接池’里.凡是需要访问数据库的地方都从连接池里取连接 二.采用缓存减少对于MySQL的访问: ...

  4. python 特殊方法之new

    object.__new__(cls[, ...]) Called to create a new instance of class cls. __new__() is a static metho ...

  5. python pickle/cPickle模块

    序列化(picking): 把变量从内存中变成可存储或传输的过程称为序列化,序列化之后,就可以把序列化的对象写入磁盘,或者传输给其他设备; 反序列化(unpickling):相应的,把变量的内容从序列 ...

  6. Mac的环境变量

    在终端输入: vim ~/.bash_profile 按i切换到INSERT模式.然后把路径按照下面的格式写进去.然后输入:wq保存退出. export PATH=${PATH}:/Users/Dru ...

  7. js 判断滚动条是不是在浏览器底部

    http://jingyan.baidu.com/album/86f4a73e91da7837d65269d5.html?picindex=2

  8. C++可移植性和跨平台初探

    概述 今天聊聊C++的可移植性问题.如果你平时使用C++进行开发,并且你对C++的可移植性问题不是非常清楚,那么我建议你看看这个系列.即使你目前没有跨平台开发的需要,了解可移植性方面的知识对你还是很有 ...

  9. 小程序rpx

    rpx是微信小程序解决自适应屏幕尺寸的尺寸单位.微信小程序规定屏幕的宽度是750rpx, 微信小程序也支持rem尺寸单位,rem规定屏幕的宽度是20rem vw vh适配 vw和vh是css3中的新单 ...

  10. iOS中判断基础字符(大小写、数字等的判断)

    函数:isdigit 用法:#include 功能:判断字符c是否为数字 说明:当c为数字0-9时,返回非零值,否则返回零. 函数:islower 用法:#include 功能:判断字符c是否为小写英 ...