首页 > 代码库 > MFC模态对话框与非模态对话框的区别总结
MFC模态对话框与非模态对话框的区别总结
非模态与模态对话框最主要的区别是非模态对话框不垄断用户的输入,用户打开非模态对话框后,仍然可以与其它界面进行交互。但是打开模态对话框就必须关闭后才能进行在其它界面进行操作。
2、非模态对话框是通过调用CDialog::Create函数来启动,而模态对话框是通过调用CDialog::DoModal函数启动。由于Create函数不会启动新的消息循环,对话框与应用程序共用同一个消息循环,这样对话框就不会垄断用户的输入。Create在显示了对话框后就立即返回,而DoModal是在对话框被关闭后才返回的。
众所周知,在MFC程序中,窗口对象的生存期应长于对应的窗口,也就是说,不能在未关闭屏幕上窗口的情况下先把对应的窗口对象删除掉。由于在Create返回后,不能确定对话框是否已关闭,这样也就无法确定对话框对象的生存期,因此只好在堆中构建对话框对象,而不能以局部变量的形式来构建之。
3、非模态对话框的模板必须具有Visible风格,否则对话框将不可见,而模态对话框则无需设置该项风格。更保险的办法是调用CWnd::ShowWindow(SW_SHOW)来显示对话框,而不管对话框是否具有Visible风格。
void CModelessDialog::PostNcDestroy
{
delete this; //删除对象本身
}
这样,在删除屏幕上的对话框后,对话框对象将被自动删除。拥有者对象就不必显式的调用delete来删除对话框对象了。
6、必须有一个标志表明非模态对话框是否是打开的。这样做的原因是用户有可能在打开一个模态对话框的情况下,又一次选择打开命令。程序根据标志来决定是打开一个新的对话框,还是仅仅把原来打开的对话框激活。通常可以用拥有者窗口中的指向对话框对象的指针作为这种标志,当对话框关闭时,给该指针赋NULL值,以表明对话框对象已不存在了。
根据上面的分析,简单的介绍下怎么代码怎么写
CDemoView::CDemoView()
{
// TODO: add construction code here
m_pDemoDlg=NULL; //指针初始化为NULL
}
void CDemoView::OnEditDemo()
{
// TODO: Add your command handler code here
if(m_pDemoDlg)
m_pDemoDlg->SetActiveWindow(); //激活对话框
else
{
//创建非模态对话框
m_pDemoDlg=new CDemoDialog(this);
m_pDemoDlg->Create(IDD_Demo,this);
}
}
void CDemoDialog::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this; //删除对话框对象
}
void CDemoDialog::OnCancel()
{
// TODO: Add extra cleanup here
((CDemoView*)m_pParent)->m_pDemoDlg=NULL;
DestroyWindow(); //删除对话框
}
彩蛋~~~~~~
不具有自动清除功能的窗口类如下所示。这些窗口对象通常是以变量的形式创建的,无需自动清除功能。
所有标准的Windows控件类。
从CWnd类直接派生出来的子窗口对象(如用户定制的控件)。
切分窗口类CSplitterWnd。
缺省的控制条类(包括工具条、状态条和对话条)。
模态对话框类。
具有自动清除功能的窗口类如下所示,这些窗口对象通常是在堆中创建的。
主框架窗口类(直接或间接从CFrameWnd类派生)。
视图类(直接或间接从CView类派生)。
具体的区别有:
2、非模态对话框是通过调用CDialog::Create函数来启动,而模态对话框是通过调用CDialog::DoModal函数启动。由于Create函数不会启动新的消息循环,对话框与应用程序共用同一个消息循环,这样对话框就不会垄断用户的输入。Create在显示了对话框后就立即返回,而DoModal是在对话框被关闭后才返回的。
众所周知,在MFC程序中,窗口对象的生存期应长于对应的窗口,也就是说,不能在未关闭屏幕上窗口的情况下先把对应的窗口对象删除掉。由于在Create返回后,不能确定对话框是否已关闭,这样也就无法确定对话框对象的生存期,因此只好在堆中构建对话框对象,而不能以局部变量的形式来构建之。
3、非模态对话框的模板必须具有Visible风格,否则对话框将不可见,而模态对话框则无需设置该项风格。更保险的办法是调用CWnd::ShowWindow(SW_SHOW)来显示对话框,而不管对话框是否具有Visible风格。
4、非模态对话框必须调用CWnd::DestroyWindow而不是CDialog::EndDialog来关闭。调用CWnd::DestroyWindow是直接删除窗口的一般方法。由于缺省的CDialog::OnOK和CDialog::OnCancel函数均调用EndDialog,故程序员必须编写自己的OnOK和OnCancel函数并且在函数中调用DestroyWindow来关闭对话框。
5、非模态对话框要用delete操作符删除对话框对象。因为是用new操作符构建非模态对话框对象,所以必须在对话框关闭后,用delete操作符删除对话框对象。在屏幕上一个窗口被删除后,框架会调用CWnd::PostNcDestroy,这是一个虚拟函数,程序可以在该函数中完成删除窗口对象的工作,具体代码如下:void CModelessDialog::PostNcDestroy
{
delete this; //删除对象本身
}
这样,在删除屏幕上的对话框后,对话框对象将被自动删除。拥有者对象就不必显式的调用delete来删除对话框对象了。
6、必须有一个标志表明非模态对话框是否是打开的。这样做的原因是用户有可能在打开一个模态对话框的情况下,又一次选择打开命令。程序根据标志来决定是打开一个新的对话框,还是仅仅把原来打开的对话框激活。通常可以用拥有者窗口中的指向对话框对象的指针作为这种标志,当对话框关闭时,给该指针赋NULL值,以表明对话框对象已不存在了。
根据上面的分析,简单的介绍下怎么代码怎么写
CDemoView::CDemoView()
{
// TODO: add construction code here
m_pDemoDlg=NULL; //指针初始化为NULL
}
void CDemoView::OnEditDemo()
{
// TODO: Add your command handler code here
if(m_pDemoDlg)
m_pDemoDlg->SetActiveWindow(); //激活对话框
else
{
//创建非模态对话框
m_pDemoDlg=new CDemoDialog(this);
m_pDemoDlg->Create(IDD_Demo,this);
}
}
void CDemoDialog::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
delete this; //删除对话框对象
}
void CDemoDialog::OnCancel()
{
// TODO: Add extra cleanup here
((CDemoView*)m_pParent)->m_pDemoDlg=NULL;
DestroyWindow(); //删除对话框
}
彩蛋~~~~~~
一个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来删除对话框及其控件。
不具有自动清除功能的窗口类如下所示。这些窗口对象通常是以变量的形式创建的,无需自动清除功能。
所有标准的Windows控件类。
从CWnd类直接派生出来的子窗口对象(如用户定制的控件)。
切分窗口类CSplitterWnd。
缺省的控制条类(包括工具条、状态条和对话条)。
模态对话框类。
具有自动清除功能的窗口类如下所示,这些窗口对象通常是在堆中创建的。
主框架窗口类(直接或间接从CFrameWnd类派生)。
视图类(直接或间接从CView类派生)。
MFC模态对话框与非模态对话框的区别总结
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。