码迷,mamicode.com
首页 > 编程语言 > 详细

MFC模态对话框与非模态对话框的区别

时间:2014-12-30 17:07:16      阅读:189      评论:0      收藏:0      [点我收藏+]

标签:

对话框主要分为两个类型:模式对话框和非模式对话框。

1、模式对话框的特点是:
a)在关闭模式对话框前,无法操作背景窗口,除非自身就是主窗口;
b)使用CDialog::DoModal函数弹出模式对话框,该函数执行过程是阻塞函数;
c)因此在栈内或者堆内申请对话框类的对象都可以的,申请栈内变量开发和运行效率高一些。

2、非模式对话框的特点是:
a)在非模式对话框运行时可以操作背景窗口;
b)使用CDialog::Create函数和CWnd::ShowWindow弹出模式对话框,该函数执行过程是非阻塞函数;
c)不能在栈内申请对话框类的临时对象,需要申请堆内变量或者使用全局变量、成员变量等生命期较长的对象。
d)调用EndDialog函数后只是窗口被隐藏了,并非真实被关闭掉了,WM_DESTROY消息不会回调;
e)如果要真实关闭非模式对话框,需要调用CWnd::DestroyWindow函数;

 

两者的区别:
一. 非模态对话框的模板必须具有Visible风格(Visible=True),否则对话框将不可见,而模态对话框则无需设置该项风格。
在实际编程中更加保险的办法是调用CWnd::ShowWindow(SW_SHOW)来显示对话框,而不管对话框是否具有Visible风格。
二. 非模态对话框对象是用new操作符来动态创建的,而不是以成员变量的形式嵌入到别的对象中或以局部变量的形式构建的。
通常应在对话框的拥有者窗口类内声明一个指向对话框类的指针成员变量,通过该指针可访问对话框对象。
三. 通过调用CDialog::Create函数来启动对话框,而不是CDialog::DoModal,这是两者之间区别的关键所在。
由于Create函数不会启动新的消息循环,对话框与应用程序共用同一个消息循环,这样对话框就不会垄断用户输入。
Create在显示了对话框后就立即返回,而DoModal是在对话框被关闭后才返回的。由于在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值,以表明对话框对象已不存在了。
例如:
创建模态对话框
CTestDlg dlg;
dlg.DoModal();
创建非模态对话框
CTestDlg * dlg = new CTestDlg;
dlg->Create(IDD_TEST_DLG);
dlg->ShowWindow(SW_SHOW);

 

必须有一个标志表明非模态对话框是否打开的。这样做的原因是用户有可能在打开一个模态对话框的情况下,又一次选择打开命令。
如下面制作记事本的查找对话框:

 BOOL isCreate;//标记是否已经打开一个查找对话框
 CFindDlg* pfindDlg;

void CNotePadDlg::OnEditFind() 
{
	
	if(isCreate == FALSE)
	{  
		pfindDlg = new CFindDlg;
		pfindDlg->Create(IDD_FIND_DIALOG);
		isCreate = TRUE;
		pfindDlg->ShowWindow(SW_SHOW);
	}
}


这样当你连续点击打开查找对话框的时候,不会连续生成几个对话框!

 

必须调用CWnd::DestroyWindow而不是CDialog::EndDialog来关闭非模态对话框。调用CWnd::DestroyWindow是直接删除窗口的一般方法。
由于缺省的CDialog::OnOK和CDialog::OnCancel函数均调用EndDialog,故程序员必须编写自己的OnOK和OnCancel函数并且在函数中调用
DestroyWindow来关闭对话框。

非模式对话框,如果我们调用了EndDialog函数来关闭对话框,它并没有被销毁,知识隐藏起来了,当我们再次点击查找,查找对话框出现的时候

它并没有重新生成,而是把原先生成的显示出来,对于非模式对话框;EndDialog函数相当于是隐藏对话框的效果HideDialog。

 

 

 

 

 

 

 

MFC模态对话框与非模态对话框的区别

标签:

原文地址:http://blog.csdn.net/djb100316878/article/details/42268183

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!