博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
模态对话框的销毁过程与非模态对话的几种销毁方法
阅读量:4047 次
发布时间:2019-05-25

本文共 2304 字,大约阅读时间需要 7 分钟。

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

 

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

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

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

出现上面Warning,原因是,调用窗口类析构的时候,窗口对象还没有销毁。具体表现在,当在一个窗口中生成另外一个窗口CTestDlg 时:

CTestDlg *pDlg = new CTestDlg();

pDlg->Create(IDD_DIALOG_TEST,this);
pDlg
->ShowWindow(TREU):
// 结束时
delete pDlg;
pDlg 
= NULL;

这样的写法就会出现上面的warning,正确的做法如下:

// 结束时

if(pDlg)
{
  pDlg
->DestoryWindow();
  pDlg 
= NULL;
}
//在后生成的窗口类中加如下代码
void CTestDlg::PostNcDestroy()
{
    
// TODO: 在此添加专用代码和/或调用基类
    delete this;//这个一定要,MSDN上有这个说明
    CDialog::PostNcDestroy();
}

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

 

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

模式对话框下,用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://fpfci.baihongyu.com/

你可能感兴趣的文章
只见他满身尘土的openeim
查看>>
故事从一只平凡的openeim002
查看>>
真是哑巴吃黄连的openeim001
查看>>
MainActivity 会异步加载图片到相应的ImageView上
查看>>
妈妈十分生气的shooow
查看>>
怎么写一个温泉管理系统
查看>>
令人神清气爽的shooow
查看>>
指导教师的shooow
查看>>
leetcode面试题01.06.字符串压缩,超出时间限制,样例通过31/32
查看>>
机器学习实战、第二章KNN算法详解、AttributeError: ‘dict‘ object has no attribute ‘iteritems‘
查看>>
leetcode 535 TinyURL 的加密与解密 暴力 年轻人不讲武德—shooter7的博客
查看>>
课程设计(毕业设计)—基于机器学习KNN算法手写数字识别系统—计算机专业课程设计(毕业设计)
查看>>
leetcode1792第232场周赛第三题,以及二维数组根据某一列进行排序——优先队列
查看>>
学生网上选课管理系统的设计与实现—计算机类专业课程设计(毕业设计)
查看>>
新建动态web工程项目红叉报错,以及Could not publish server configuration for Tomcat v9.0 Server at localhost.
查看>>
机器学习SVM的车牌识别系统—计算机专业课程设计(毕业设计)
查看>>
leetcode 80. 删除有序数组中的重复项 II
查看>>
课程设计(毕业设计)—学生宿舍管理系统—计算机类专业
查看>>
毕业设计(课程设计)—SpringBoot网上订餐系统的设计与实现—计算机类专业课程设计(毕业设计)
查看>>
毕业设计(课程设计)—个人博客系统(微博)的设计与实现—计算机类专业课程设计(毕业设计)
查看>>