模态对话框与非模态对话的销毁方法与区别

前几天发现自己的程序中使用非模态对话框,Debug版本有警告提示如下:

Warning: calling DestroyWindow in CWnd::~CWnd OnDestroy or PostNcDestroy in derived class will not be called

由于是Warnning,就没有太在意,后来随意上网一找发现,这个问题还是很严重的问题。

最后,发现有些基本问题我还没有搞清楚。同时在这个过程中,也学习了不少新东西,网上关于这个问题的资料很多,感觉真正把问题讲清楚的不多。今天我就来个总结,同时,也把网上有些人的疑问给解答下,更重要的是自己以后忘记了,可以回来参考。

先说下模式对话框调用的原则。(就是一定要先关了这个对话框才能操作后面窗口的对话框)

在模式对话框下,用CDialog::OnOK()或CDialog::OnCancel()以及CDialog::OnClose()关闭对话框。

一定要注意之前的CDialog::(当然,你可以重载你自己对话框的这个虚函数,但是,后面必须调用基类的CDialog::)

具体我们再参照深入浅出的风格,来个解刨。

CDialog::Close()默认调用CDialog::OnCancel() , CDialog::OnCancel()调用CDialog::EndDialog(IDCANCEL);

CDialog::EndDialog调用CDialog::DestroyWindows(),CDialog::DestroyWindows调用CDialog::OnDestroy() ;

CDialog::OnOK()默认先CDialog::UpdateData(),然后再调用CDialog::EndDialog(IDOK).

CDialog::EndDialog调用CDialog::DestroyWindows(), CDialog::DestroyWindows调用CDialog::OnDestroy()

看来上面你可能就知道了如下的等式

CDialog::Close() == CDialog::OnCancel() == CDialog::EndDialog(IDCANCEL)一样。

CDialog::OnOK() == CDialog::EndDialog(IDOK).

而CDialog::EndDialog(IDOK)跟CDialog::EndDialog(IDCANCEL)的区别就是,少了一个CDialog::UpdateData(),也就是CDialog::EndDialog(IDOK),在关闭对话框后,会把对话框上控件关联的变量的值更新为用户最后输入的值。而CDialog::EndDialog(IDCANCEL)就不会更新这个值。

希望自己把模式对话框的关闭讲清楚了。

下面说说非模态对话框。

调用原则是:

在无模式对话框,重载你自己的OnOK(),就是CMyDialog::OnOK()调用CDialog::DestroyWindows()。注意:不是默认的CDialog::OnOK()来关闭对话框。

重载CMyDialog::OnCancel()调用CDialog::DestroyWindows()。注意:不是调用默认的CDialog::OnCancel(),来关闭对话框。

听起来很简单,但是下面提到一个很具体的编程问题。

一般,我们用非模态对话框都是全局的,也就是通过new来创建,是在heap上的,而不是在stack上的。

这样我们当然还要通过delete 来销毁对象,不然可是有内存泄漏的。那么我们什么时候delete这个对象呢?

在msdn上面我们可以看到微软提供的方法是,

我们要重载PostNcDestroy(),即我们要实现CMyDialog::PostNcDestroy(),内容如下

CMyDialog::PostNcDestroy() { CDialog::PostNcDestroy(); delete this; }

这样的话,我们的类就会Auto-Cleanup了。

msdn的建议,英文的,当初我看了2遍没看懂。现在在回头去看,才发现比较简单。但让现在你看了这篇blog后就不用看这个了。

http://msdn.microsoft.com/en-us/library/5zba4hah.aspx

http://renjwjx.blog.51cto.com/811549/191320/

时间: 2024-08-04 22:21:38

模态对话框与非模态对话的销毁方法与区别的相关文章

Mfc在模态对话框上非模态创建listbox焦点问题

问题描述 Mfc在模态对话框上非模态创建listbox焦点问题 在模态对话框上创建一个Gridctrl中每一个Row里会有一个item里additem了一个非模太的listbox控件,在响应item左键单击后会show出这个listbox在listbox的show函数里setfocys一直不起作用,发现焦点一直在最最外层的Dlg里,怎么能够把焦点设置到listbox上 解决方案 看看是不是忘记设置tabstop了.手工按tab有反应么?setfocus的handle参数是否正确. 解决方案二:

模态对话框和非模态对话框11111111

问题描述 模态对话框和非模态对话框11111111 我之前用(dlg.domodal==idok)创建的模态对话框,后来我想把他改成费模态的 但是我应该是用什么语句 使我单击非模态对话框上的"确定"来获取对话框中的内容呢 解决方案 楼主,你是不是想问如何在主对话框中收到点击了非模态对话框的确定 解决方案二: 楼主,你是不是想问如何在主对话框中收到点击了非模态对话框的确定 解决方案三: 点击确定按钮,向主对话框发送一个自定义消息. 在主对话框相应该消息. 解决方案四: 模态对话框的处理方

MFC创建模态对话框和非模态对话框的方法_C 语言

在MFC中对话框有两种形式,一个是模态对话框(model dialog box),一个是非模态对话框(modeless dialog box).本文对此分别简述其创建方法. 一.模态对话框(model dialog box) 在程序运行的过程中,若出现了模态对话框,那么主窗口将无法发送消息,直到模态对话框退出才可以发送. 点击模态对话框中的OK按钮,模态对话框会被销毁. 创建一个模态对话框的代码如下所示: //创建一个模态对话框 CTestDialog td; td.DoModal(); 其中C

MFC调用模态对话框和非模态对话框的方式

1.调用模态的对话框void ADlg:: Button(){BDlg bdlg;bdlg.DoModal();}2.调用非模态的对话框在 Adlg.h 包含 Bdlg.h头文件中定义BDlg* m_pdblg; 在Adlg.cpp中在构造函数中初始化m_pdblg = NULL;在析构函数中if(m_pdblg != NULL){delete m_pdblg;} 在单击按钮中void ADlg:: Button(){m_pdblg = new BDlg;m_pdblg->Create(IDD_

vc非模态对话框-VC 非模态对话框为何总是置顶显示

问题描述 VC 非模态对话框为何总是置顶显示 小弟遇到一个问题,不知道谁能帮忙解决一下,先谢谢啦~ 我的单文档程序,点击按钮后生成一个非模态对话框,可是对话框一直是显示在前端,当我鼠标点在单文档程序上进行操作时,对话框一直挡在前面,这点让我不能理解啊,因为活动窗口是主窗口了啊,怎么让主窗口可以显示在对话框之上呢??不知道哪位大神能指点一下的 解决方案 你可以手动让他不在最顶端,判断是否获得焦点,如果没有,最小化一下就可以了

JS 模态对话框和非模态对话框操作技巧汇总_基础知识

模态窗口 javascript 技巧汇总(传值.打开.刷新) 1.要弹出的页面中,一定要保证<head></head>标签间有<base target="_self">,否则会弹出的模态窗口上,点击按钮时,会再次弹出一个新页面. 2.被弹出页面的按钮的事件处理中,应该有Response.Write(new Function().ClosePage());语句,用以关闭当前的模态窗口. 3.因为幽默的缓存原因,如果你在模态窗口中修改了数据,你会发现,父

Chrome中模态对话框showModalDialog返回值问题的解决方法_javascript技巧

没有找到太好的解决办法,暂时处理方法是,在弹出窗口中同时给 window.opener.ReturnValue 赋返回值.这样在关闭窗口后,通过下面的代码取得返回值: 复制代码 代码如下: var val = window.showModalDialog(...); if(!val) val= window.ReturnValue; 这样在IE.FF.及Chrome中,都可以得到返回值了.

VC MFC非模态对话框的实现方法_C 语言

众所周知的,MFC中非模态对话框在显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换.本文就来给大家讲解一下非模态对话框的实现方法: 一.非模态对话框的对话框资源和对话框类 实际上,模态对话框和非模态对话框在创建对话框资源和生成对话框类上是没有区别的,因此,在创建模态对话框时所创建的IDD_TIP_DIALOG对话框资源和CTipDlg类都不需要修改. 二.创建及显示非模态对话框的步骤 需要修改的是,对话框类实例的创建和显示,也就是之前在CAdditionDlg::OnBnCli

Silverlight中模态对话框的通用模拟

Silverlight 给我们带来了如同 Winform 一样便捷的开发方式,然而在桌面应用程序中一个非常重要 的元素--模态对话框,却不具备. 而 ScottGu 的 Silverlight 教程中提供了一种简单的方法,可以模拟出类似模态对话框的显示. 其原理跟我们在 HTML 中实现模拟的模态对话框的方法类似,无非是动态创建一个半透明的层盖住整 个页面背景,让背后的元素无法操作,然后在其上显示对话框内容即可.不过,在这篇教程中创建的子窗 体必须在调用者页面的 XAML 中手工声明,假如我们需