非模态对话框

您所在的位置:网站首页 非模态对话框是指 非模态对话框

非模态对话框

2024-07-04 13:44| 来源: 网络整理| 查看: 265

 必须有一个标志表明非模态对话框是否是打开的。这样做的原因是用户有可能在打开一个模态对话框的情况下,又一次选择打开命令。程序根据标志来决定是打开一个新的对话框,还是仅仅把原来打开的对话框激活。通常可以用拥有者窗口中的指向对话框对象的指针作为这种标志,当对话框关闭时,给该指针赋NULL值,以表明对话框对象已不存在了。 

根据上面的分析,我们很容易把Register程序中的登录数据对话框改成非模态对话框。这样做的好处在于如果用户在输入数据时发现编辑视图中有错误的数据,那么不必关闭对话框,就可以在编辑视图中进行修改。 

  请读者按下面几步操作: 

  在登录数据对话框模板的属性对话框的More Styles页中选择Visible项。 

  在RegisterView.h头文件的CRegisterView类的定义中加入public:CRegisterDialog* m_pRegisterDlg; 

  在RegisterView.h头文件的头部加入对CRegisterDialog类的声明class CRegisterDialog;加入该行的原因是在CRegisterView类中有一个CRegisterDialog类型的指针,因此必须保证CRegisterDialog类的声明出现在CRegisterView之前,否则编译时将会出错。解决这个问题有两种办法,一种办法是保证在#include “RegisterView.h”语句之前有#include “RegisterDialog.h”语句,这种办法造成了一种依赖关系,增加了编译负担,不是很好;另一种办法是在CRegisterView类的声明之前加上一个对CRegisterDialog的声明来暂时“蒙蔽”编译器,这样在有#include “RegisterView.h”语句的模块中,除非要用到CRegisterDialog类,否则不用加入#include “RegisterDialog.h”语句。 

  在RegisterDialog.cpp文件的头部的#include语句区的末尾添加下面两行#include "RegisterDoc.h"#include "RegisterView.h" 

  利用ClassWizard为CRegisterDialog类加入OnCancel和PostNcDestroy成员函数。加入的方法是进入ClassWizard后选择Message Maps页,并在Class name栏中选择CRegisterDialog。然后,在Object IDs栏中选择IDCANCEL后,在Messages栏中双击BN_CLICKED,这就创建了OnCancel。要创建PostNcDestroy,先在Object IDs栏中选择CRegisterDialog,再在Messages栏中双击PostNcDestroy即可。

CRegisterView类的部分代码 

 CRegisterView::CRegisterView() 

 { 

 // TODO: add construction code here 

   

 m_pRegisterDlg=NULL; //指针初始化为NULL 

 } 

   

 void CRegisterView::OnEditRegister()  

 { 

 // TODO: Add your command handler code here 

   

   

 if(m_pRegisterDlg) 

 m_pRegisterDlg->SetActiveWindow(); //激活对话框 

 else 

 { 

 //创建非模态对话框 

 m_pRegisterDlg=new CRegisterDialog(this); 

 m_pRegisterDlg->Create(IDD_REGISTER,this); 

 } 

 }CRegisterDialog的部分代码 

 void CRegisterDialog::PostNcDestroy()  

 { 

 // TODO: Add your specialized code here and/or call the base class 

 delete this; //删除对话框对象 

 } 

 void CRegisterDialog::OnCancel()  

 { 

 // TODO: Add extra cleanup here 

 ((CRegisterView*)m_pParent)->m_pRegisterDlg=NULL; 

 DestroyWindow(); //删除对话框  

 } 

CRegisterView::OnEditRegister函数判断登录数据对话框是否已打开,若是,就激活对话框,否则,就创建该对话框。该函数中主要调用了下列函数: 

  调用CWnd::SetActiveWindow激活对话框,该函数的声明为CWnd* SetActiveWindow( );该函数使本窗口成为活动窗口,并返回原来活动的窗口。 

  调用CDialog::Create来显示对话框,该函数的声明为BOOL Create( UINT nIDTemplate, CWnd* pParentWnd = NULL );参数nIDTemplate是对话框模板的ID。pParentWnd指定了对话框的父窗口或拥有者。 

  当用户在登录数据对话框中点击“取消”按钮后,CRegisterDialog::OnCancel将被调用,在该函数中调用CWnd::DestroyWindow来关闭对话框,并且将CRegisterView的成员m_pRegisterDlg置为NULL以表明对话框被关闭了。调用DestroyWindow导致了对CRegisterDialog::PostNcDestroy的调用,在该函数中用delete操作符删除了CRegisterDialog对象本身。 

  编译并运行Register,现在登录数据对话框已经变成一个非模态对话框了。

2 窗口对象的自动清除 

  一个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。 

  缺省的控制条类(包括工具条、状态条和对话条)。 

  模态对话框类。 

  具有自动清除功能的窗口类如下所示,这些窗口对象通常是在堆中创建的。 

 主框架窗口类(直接或间接从CFrameWnd类派生)。 

 视图类(直接或间接从CView类派生)。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3