VC 模式对话框和非模式对话框的创建,销毁和区别

[MFC] 创建模态对话框以及可能出现的问题 此外,该函数还会销毁窗口的菜单、定时器,移除剪贴板所有权,并打破剪贴板查看器链(如果该窗口位于查看器链的顶部)。该段代码中,我们静态声明了一个指针变量,首次运行时指向CFMoTiDlg类new的一段内存地址,当关闭一个模态窗口时, DestroyWindow()函数回收所有该类的资源,pfmt_dlg指针失效,因此,再次运行创建时,程序会直接崩溃。类对象fmt_dlg需要定义在函数外部,由于模态窗口在代码运行时不会阻塞,因此如果对象创建在内部则会被瞬间销毁。但是,每个对话框实例在创建后只能显示一次。 阅读详情
在WIN32中,模式对话框的创建一般是使用DialogBox来进行创建的。而非模式对话框则是利用CreateWindow来创建的。在MFC或是WTL中,模式对话框一般是使用DoModal,而非模式对话框的创建则是使用Create。模式对话框创建后,程序的其他窗口便不能进行操作,必须将该窗口关闭后,其他窗口才能进行操作。而非模式对话框则无需这样,它不强制要求用户立即反应,而是与其他窗口同时接受用户操作。
Create的Dialog一般是modalless,如果你的程序本身就是只有一个Dialog,就无所谓了,看不出modalless的效果。modalless本来就是让有机会切换到本程序的其他窗口。
非模态对话框的特点: 
与模态对话框不同,非模态对话框不垄断用户的输入,用户打开非模态对话框后,仍然可以与其它界面进行交互。 
非模态对话框的设计与模态对话框基本类似,也包括设计对话框模板和设计CDialog类的派生类两部分。但是,在对话框的创建和删除过程中,非模态对话框与模态对话框相比有下列不同之处: 
非模态对话框的模板必须具有Visible风格,否则对话框将不可见,而模态对话框则无需设置该项风格。更保险的办法是调用CWnd::ShowWindow(SW_SHOW)来显示对话框,而不管对话框是否具有Visible风格。 
非模态对话框对象是用new操作符在堆中动态创建的,而不是以成员变量的形式嵌入到别的对象中或以局部变量的形式构建在堆栈上。通常应在对话框的拥有者窗口类内声明一个指向对话框类的指针成员变量,通过该指针可访问对话框对象。 
通过调用CDialog::Create函数来启动对话框,而不是CDialog::DoModal,这是模态对话框的关键所在。由于Create函数不会启动新的消息循环,对话框与应用程序共用同一个消息循环,这样对话框就不会垄断用户的输入。Create在显示了对话框后就立即返回,而DoModal是在对话框被关闭后才返回的。众所周知,在MFC程序中,窗口对象的生存期应长于对应的窗口,也就是说,不能在未关闭屏幕上窗口的情况下先把对应的窗口对象删除掉。由于在Create返回后,不能确定对话框是否已关闭,这样也就无法确定对话框对象的生存期,因此只好在堆中构建对话框对象,而不能以局部变量的形式来构建之。 
必须调用CWnd::DestroyWindow而不是CDialog::EndDialog来关闭非模态对话框。调用CWnd::DestroyWindow是直接删除窗口的一般方法。由于缺省的CDialog::OnOK和CDialog::OnCancel函数均调用EndDialog,故程序员必须编写自己的OnOK和OnCancel函数并且在函数中调用DestroyWindow来关闭对话框。 
因为是用new操作符构建非模态对话框对象,因此必须在对话框关闭后,用delete操作符删除对话框对象。在屏幕上一个窗口被删除后,框架会调用CWnd::PostNcDestroy,这是一个虚拟函数,程序可以在该函数中完成删除窗口对象的工作,具体代码如下
void CModelessDialog::PostNcDestroy
{
delete this; //删除对象本身
}
这样,在删除屏幕上的对话框后,对话框对象将被自动删除。拥有者对象就不必显式的调用delete来删除对话框对象了。 
必须有一个标志表明非模态对话框是否是打开的。这样做的原因是用户有可能在打开一个模态对话框的情况下,又一次选择打开命令。程序根据标志来决定是打开一个新的对话框,还是仅仅把原来打开的对话框激活。通常可以用拥有者窗口中的指向对话框对象的指针作为这种标志,当对话框关闭时,给该指针赋NULL值,以表明对话框对象已不存在了。 
提示:在C++编程中,判断一个位于堆中的对象是否存在的常用方法是判断指向该对象的指针是否为空。这种机制要求程序员将指向该对象的指针初始化为NULL值,在创建对象时将返回的地址赋给该指针,而在删除对象时将该指针置成NULL值。  
根据上面的分析,我们很容易把Register程序中的登录数据对话框改成非模态对话框。这样做的好处在于如果用户在输入数据时发现编辑视图中有错误的数据,那么不必关闭对话框,就可以在编辑视图中进行修改。 
窗口对象的自动清除: 
一个MFC窗口对象包括两方面的内容:一是窗口对象封装的窗口,即存放在m_hWnd成员中的HWND(窗口句柄),二是窗口对象本身是一个C++对象。要删除一个MFC窗口对象,应
该先删除窗口对象封装的窗口,然后删除窗口对象本身。 
删除窗口最直接方法是调用CWnd::DestroyWindow或::DestroyWindow,前者封装了后者的功能。前者不仅会调用后者,而且会使成员m_hWnd保存的HWND无效(NULL)。如果DestroyWindow删除的是一个父窗口或拥有者窗口,则该函数会先自动删除所有的子窗口或被拥有者,然后再删除父窗口或拥有者。在一般情况下,在程序中不必直接调用DestroyWindow来删除窗口,因为MFC会自动调用DestroyWindow来删除窗口。例如,当用户退出应用程序时,会产生WM_CLOSE消息,该消息会导致MFC自动调用CWnd::DestroyWindow来删除主框架窗口,当用户在对话框内按了OK或Cancel按钮时,MFC会自动调用CWnd::DestroyWindow来删除对话框及其控件。 
窗口对象本身的删除则根据对象创建方式的不同,分为两种情况。在MFC编程中,会使用大量的窗口对象,有些窗口对象以变量的形式嵌入在别的对象内或以局部变量的形式创建在堆栈上,有些则用new操作符创建在堆中。对于一个以变量形式创建的窗口对象,程序员不必关心它的删除问题,因为该对象的生命期总是有限的,若该对象是某个对象的成员变量,它会随着父对象的消失而消失,若该对象是一个局部变量,那么它会在函数返回时被清除。 
对于一个在堆中动态创建的窗口对象,其生命期却是任意长的。初学者在学习C++编程时,对new操作符的使用往往不太踏实,因为用new在堆中创建对象,就不能忘记用delete删除对象。读者在学习MFC的例程时,可能会产生这样的疑问,为什么有些程序用new创建了一个窗口对象,却未显式的用delete来删除它呢?问题的答案就是有些MFC窗口对象具有自动清除的功能。 
如前面讲述非模态对话框时所提到的,当调用CWnd::DestroyWindow或::DestroyWindow删除一个窗口时,被删除窗口的PostNcDestroy成员函数会被调用。缺省的PostNcDestroy什么也不干,但有些MFC窗口类会覆盖该函数并在新版本的PostNcDestroy中调用delete this来删除对象,从而具有了自动清除的功能。此类窗口对象通常是用new操作符创建在堆中的,但程序员不必操心用delete操作符去删除它们,因为一旦调用DestroyWindow删除窗口,对应的窗口对象也会紧接着被删除。 
不具有自动清除功能的窗口类如下所示。这些窗口对象通常是以变量的形式创建的,无需自动清除功能。 
所有标准的Windows控件类。 
从CWnd类直接派生出来的子窗口对象(如用户定制的控件)。 
切分窗口类CSplitterWnd。 
缺省的控制条类(包括工具条、状态条和对话条)。 

        
模态对话框创建销毁过程 创建模态对画框的过程:见http://blog.csdn.net/xiaominggunchuqu/article/details/49895325   一个模态MFC 窗口的销毁过程: 假设自己通过new创建了一个窗口对象pWnd,然后pWnd->Create。则销毁窗口的调用次序: 1.      手工调用pWnd->DestroyWindow(); // 一般在对话框类中的 阅读详情

相关推荐

MFC创建模态对话框

模态对话框弹出后,程序可以在不关闭该对话框的情况下继续执行,在转入到应用程序其他部分的代码时可以不需要用户做出响应。在主框架类的头文件添加文件包含:#include ”DialogModalless.h”当选择“查看”菜单中的“模态对话框”菜单项时,弹出左面的对话框。选择左边树控件中的某个班级,在右边的列表控件显示该班级的学生。3.实现对话框的功能:添加控件关联变量 添加消息响应函数。2. 在构造函数中初始化: m_pModallessDlg=NULL;4. 添加菜单消息响应函数,显示对话框

qq_51704523的博客 2297

MFC 创建模态对话框销毁过程

今天项目中遇到的问题,记录下来,做个总结。 一个简单的目的是创建一个模态对话框并在对话框关闭后将其销毁。 这里的销毁包括:销毁对话框对象资源对话框对象指针; 首先说创建对话框: 一、模态对话框(model dialog box)   在程序运行的过程中,若出现了模态对话框,那么主窗口将无法发送消息,直到模态对话框退出才可以发送。 点击模态对话框中的OK按钮,模态对话框会被销毁。创...

passball 8194

RT-DETR改进策略【独家融合改进】| SPD-Conv+PPA 再次提升模型针对小目标的特征提取能力

SPD-Conv是一种新的 CNN 构建模块,用于替代传统 CNN 架构中使用的步长卷积(strided convolution)池化(pooling)层,它由空间到深度(Space-to-depth,SPD)层步长卷积(non - strided convolution)层组成。

Limiiiing的博客 1114

(搬运)mfc模态对话框关闭避免内存泄露

以下是一段在CView类里调用模态对话框的实例 void CYourView::OnOpenDlg(void) { /*假设IDD_TEST_DLG为已经定义的对话框资源的ID号*/ CTestDlg *dlg=new CTestDlg; dlg->Create(IDD_TEST_DLG,NULL); dlg->ShowWindow(SW_SHOW); /*不要调用 delete dlg;*/ } 在上面的代码中我们新生成了一个对话框对象,而且在退出函数时并没有销毁该对象。因

qq_52182554的博客 686

[转]VC 模式对话框模式对话框创建销毁区别

只看懂了一小部分......不过刚刚好够 用.... 转自 http://blog.csdn.net/mycaibo/article/details/6002149   VC 模式对话框模式对话框创建销毁区别 分类: 读书笔记2010-11-11 11:19 192人阅读 评论(0) 收藏 举报 在WIN32中,模式对话框创建一般是

扯蛋的青春与蛋痛的生活 1895

模态模态对话框创建销毁过程

一、显示对话框: 1.显示模式对话框: CDialogDemo dlg; dlg.DoModal(); 2.显示模式对话框: CDialogDemo *dlg=new CDialogDemo(this); dlg->Create(IDD_GENERAL_CONTROL); dlg->ShowWindow(SW_SHOW); 二、关闭对话框: 1.CDialog::OnOK(); 2.CDialog::DestoryWindow(); 3.CDialog::EndDia...

GJ_007的博客 1079

MFC模态对话框销毁(转)

模态对话框相对于模态对话框,他的创建销毁过程模态对话框有一定的区别,先看一下MSDN的原文:When   you   implement   a   modeless   dialog   box,   always   override   the   OnCancel   member   function   and   call   DestroyWindow   from   wi

学无紫晶 3902

MFC程序中消息以及函数的处理顺序简介!

MFC应用程序中处理消息的顺序1.AfxWndProc()      该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc2.AfxCallWndProc()  该函数负责保存消息(保存的内容主要是消息标识符消息参数)供应用程序以后使用,                    然后调用WindowProc()函数3.WindowProc()     

vcforever的专栏 6690

MFC下的模态模态对话框

以前学VC的时候觉得模态模态很简单,两个的创建方式不同,一个是Create一个是DoModel,然后如果是模态的就很霸道,不让你去点后面的父窗口,如果是模态就可以点击后面的父窗口,但是在实际的应用发现一点很需要注意的地方: 我们如果便写过window SDK,可以知道,其实窗口的创建不关事父窗口还是子窗口,不管是模态还是模态,其最基本的的调用的都是CreateWindow或者Cre

嵌入式相关 4081

模态对话框创建销毁

模态对话框创建销毁 1、创建模态对话框 一般使用new来创建一个模态对话框; CDlg  *dlgMDlg; dlgMDlg = new  CDlg;   dlgMDlg .Create(IDD_DIALOG_MODELESS, NULL);//NULL可以改变为其他参数 dlgMDlg .ShowWindow(SW_SHOW); //模态对话框必须使用该函数才可以显示。

xingziweiyi的专栏 761

GEE初学:谷歌地球引擎GEE入门指南(最新注册全流程)

本教程详细介绍了谷歌地球引擎(GEE)的注册与基础操作流程。主要内容包括:1)商业账号注册步骤,需提供学术机构凭证研究目的;2)Google Cloud项目创建与API激活;3)Shapefile文件上传方法及资源ID获取;4)JavaScript脚本编写与地图可视化实现。教程通过代码示例展示了两种多边形显示方式(填充轮廓模式),并强调了GEE的云端处理优势,包括免费访问40多年卫星数据、无需本地高性能硬件等特点。整个流程从账号注册到首个地图可视化完成约需10-15分钟,适合遥感分析初学者快速入门。

此星光明博客 1956

用示波器测试CAN信号的步骤.docx

用示波器测试CAN信号的步骤.docx

上一篇: VC 模式对话框和非模式对话框的创建,销毁和区别
下一篇: VC 模式对话框和非模式对话框的创建,销毁和区别
mycaibo
博客等级 码龄20年 32粉丝 41原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值