模式对话框和非模式对话框

下是在百度空间中再录的内容:

WIN32中,模式对话框的创建一般是使用DialogBox来进行创建的。而非模式对话框则是利用CreateWindow来创建的。在MFC或是WTL中,模式对话框一般是使用DoModal,而非模式对话框的创建则是使用Create

模式对话框创建后,程序的其他窗口便不能进行操作,必须将该窗口关闭后,其他窗口才能进行操作。而非模式对话框则无需这样,它不强制要求用户立即反应,而是与其他窗口同时接受用户操作。

二、           消息响应的区别

在消息响应方面,模式对话框和非模式对话框之间又有着很大的区别。模式对话框工作的时候,它有内部的消息泵机制,控件之间的交互不用我们人为的去控制,系统会帮助我们去处理。非模式对话框则像普通窗口一样,则由WinMain中书写的消息循环驱动。但由于是对话框,它对一些消息有特殊的处理。因此,在消息循环中,需要先对对话框提供截获消息的机会。

While (GetMessage(&msg, NULL, 0, 0))

{

if (hDlgModeless == 0 || !IsDialogMessage(hDlgModeless, &msg))

{

    TranslateMessage(&msg);

    DispatchMessage( &msg);

}

}

如果当前取得的消息是对话框的消息,IsDialogMessage 将它交由对话消息处理函数处理,并返回TRUE。不需要再派发了。

注意:这个方法并不是很好用,因为当对话框过多的时候,处理起来就比较麻烦了。另一种处理的方法是利用子类化控件的方法,来处理控件间的交互。

三、           销毁的区别

模式对话框的销毁是使用EndDialog,而非模式对话框的销毁是使用DestroyWindow.。所以我们在销毁对话框的时候,也要对其进行区别。

非模式对话框,用户关闭对话框时,对话框消息处理函数将收到WM_CLOSE消息,接到后调用DestroyWindow以销毁非模式对话框。

模式对话框,则一般响应IDOKIDCANCEL。在PPC上,我们对于OK键和X键的处理要注意这点。

四、           其他

非模态对话框的模板必须具有Visible风格,否则对话框将不可见,而模态对话框则无需设置该项风格。更保险的办法是调用ShowWindow(hDialog, SW_SHOW)来显示对话框,而不管对话框是否具有Visible风格。 

非模态对话框对象是用new操作符在堆中动态创建的,而不是以成员变量的形式嵌入到别的对象中或以局部变量的形式构建在堆栈上。通常应在对话框的拥有者窗口类内声明一个指向对话框类的指针成员变量,通过该指针可访问对话框对象。

通过调用Create函数来启动对话框,而不是DoModal,这是模态对话框的关键所在。由于Create函数不会启动新的消息循环,对话框与应用程序共用同一个消息循环,这样对话框就不会垄断用户的输入。Create在显示了对话框后就立即返回,而DoModal是在对话框被关闭后才返回的。众所周知,在MFC程序中,窗口对象的生存期应长于对应的窗口,也就是说,不能在未关闭屏幕上窗口的情况下先把对应的窗口对象删除掉。由于在Create返回后,不能确定对话框是否已关闭,这样也就无法确定对话框对象的生存期,因此只好在堆中构建对话框对象,而不能以局部变量的形式来构建之。

因为是用new操作符构建非模态对话框对象,因此必须在对话框关闭后,用delete操作符删除对话框对象。

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

注意:在C++编程中,判断一个位于堆中的对象是否存在的常用方法是判断指向该对象的指针是否为空。这种机制要求程序员将指向该对象的指针初始化为NULL值,在创建对象时将返回的地址赋给该指针,而在删除对象时将该指针置成NULL值。

DoModal

  

VC++下使用DoModal

  CPropertySheet::DoModal

  virtual int DoModal();

   返回值:
   如果函数成功则返回IDOK或IDCANCEL;否则返回0或-1。如果此属性表是作为一个向导(参见SetWizardMode)建立的,DoModal返回ID_WIZFINISH或IDCANCEL。
   说明:
   此成员函数用来显示一个模态对话框。其返回值对应于用来关闭对话框的控件的ID。此函数返回后,Windows响应这个对话框,所有的属性页都会被销毁。而这些对象本身仍然存在。通常,你将在DoModal返回IDOK之后从CPropertyPage对象检取数据。
   要显示一个非模态对话框,请调用Create来代替此函数。
   注意:
   在一个属性页被第一次从它相应的对话框资源创建时,它有可能引发一个第一次机会(first-chance)异常。这是在创建此页之前属性页将对话框资源的风格改变成了所需的风格的结果。因为资源通常来说是只读的,所以这导致了一个异常。这个异常由系统处理,系统会自动拷贝修改后的资源。这样,第一次机会(first-chance)异常就被忽略了。
   由于这个异常必须由操作系统来处理,所以不要用一个C++ try/catch块来隐藏调用CPropertySheet::DoModal,因为在一个C++ try/catch块中catch会处理所有的异常,比如,catch(...)。它将处理那些属于操作系统的异常,这将导致不可预料的行为发生。但是,通过指定异常类型或结构化异常处理来处理C++异常就是安全的,在结构化异常处理中,访问非法异常被传递给操作系统。
   请参阅:
   CDialog::DoModal, CPropertySheet::Create

CPrintDialog类成员

  CPrintDialog::DoModal

  virtual int DoModal();

   返回值:  

 返回IDOK或IDCANCEL。如果返回的是IDCANCEL,则要调用WindowsCommDlgExtendedError函数来确定是否发生了一个错误。IDOK和IDCANCEL都是常量,它表明用户选择的是OK按钮还是Cancel按钮。

   说明:
   此函数用来显示Windows的通用打印对话框,并允许用户选择各个打印选项,例如备份的数目、页范围和备份是否需要整理。
   如果你想要提供设置m_pd结构的成员来初始化各个打印对话框选项,则应当在打印DoModal之前,但在对话框对象构造之后进行。
   在调用了DoModal之后,你就可以调用其它的成员函数来检取各个设置或用户在对话框中输入的信息了。
   请参阅:
   CPrintDialog::CPrintDialog, CDialog::DoModal
 

 

CPageSetupDialog成员

 

  CPageSetupDialog::DoModal
   virtual int DoModal();
  返回值:
   返回IDOK或IDCANCEL。如果返回的是IDCANCEL,则调用Windows CommDlgExtendedError函数来确定是否发生了一个错误。
   IDOK和IDCANCEL都是常量,它们用来表明用户选择的是OK按钮还是Cancel按钮。
  说明:
   此函数用来显示Windows通用OLE Page Setup对话框,并允许用户选择不同的打印设置选项,比如打印边距、页面大小、页面方向,和打印机目标。另外,用户页可以访问如网络位置和所选打印机的属性等打印机设置选项。
   如果你希望通过设置m_psd结构的成员来初始化不同的Page Setup对话框选项,你必须在调用DoModal之前和构造此对话框之后进行。在调用DoModal之后,调用其它的成员函数来获取用户在对话框中输入的设置和信息。
   如果你想传送用户输入的当前设置,请调用CWinApp::SelectPrinter。这个函数读取来自CPageSetupDialog对象的信息并初始化和选择一个具有适当属性的新打印机DC。
   AfxGetApp()->SelectPrinter(dlg.m_psd.hDevNames, dlg.m_psd.hDevMode );
   请参阅:CPageSetupDialog::m_psd
 

编辑本段COleUpdateDialog成员

  COleUpdateDialog::DoModal
 
  virtual int DoModal();
 
  返回值:
 
  对话框的完成状态。是下列值之一: · IDOK 如果对话框成功返回。
 
  · IDCANCEL 如果当前文档中不存在需要更新的链接项或嵌入项。
 
  · IDABORT 如果发生了一个错误。如果返回的是IDABORT,调用COleDialog::GetLastError成员函数来获取更多有关所发生的错误类型的信息。可能发生的错误的列表,参见“OLE 2.01用户接口库”中的OleUIEditLinks函数。
 
  说明:
 
  此函数以更新方式显示Edit Links对话框。除非用户选择了Cancel按钮,所有的链接项和/或嵌入项都会被更新。
 
  请参阅:
 
  COleDialog::GetLastError, COleLinksDialog::DoModal
 

编辑本段COlePropertiesDialog

  COlePropertiesDialog::DoModal
 
  virtual int DoModal();
 
  返回值:
 
  如果成功则返回IDOK或IDCANCEL;否则返回0。IDOK和IDCANCEL都是常量,它们指示用户是选择了OK按钮还是Cancel按钮。
 
  如果返回的是IDCANCEL,你可以调用函数Windows CommDlgExtendedError来确定是否发生了一个错误。
 
  说明:
 
  这个成员函数用来显示Windows通用OLE Object Properties对话框,并允许用户查看或改变文档项的各个属性。
 
  请参阅:
 
  COlePropertiesDialog::OnApplyScale, COlePropertiesDialog::m_psh
 

编辑本段COlePasteSpecialDialog

  COlePasteSpecialDialog::DoModal
 
  virtual int DoModal();
 
  返回值:
 
  对话框完成的状态。它可以是下列值之一: · IDOK 如果成功显示了对话框。
 
  · IDCANCEL 如果用户取消了对话框。
 
  · IDABORT 如果返回的是IDABORT,则要调用COleDialog::GetLastError成员函数来获取有关所发生的错误类型的进一步信息。可能发生的错误的列表,请参见“OLE 2.01用户接口库”中的OleUIPasteSpecial函数。
 
  说明:
 
  此函数用来显示OLE Paste Special 对话框。
 
  如果你想通过设置m_ps结构的成员函数来初始化不同的对话框控件,则你必须在调用DoModal之前,但在构造了对话框对象之后进行。
 
  如果DoModal返回IDOK,则你可以调用其它成员函数来获取各个设置或由用户在对话框中输入的信息。
 
  请参阅:
 
  COleDataObject, COleDialog::GetLastError, CDialog::DoModal, COlePasteSpecialDialog::COlePasteSpecialDialog, COlePasteSpecialDialog::GetDrawAspect, COlePasteSpecialDialog::GetIconicMetafile, COlePasteSpecialDialog::GetPasteIndex, COlePasteSpecialDialog::GetSelectionType
 

编辑本段COleLinksDialog成员

  COleLinksDialog::DoModal
 
  virtual int DoModal();
 
  返回值:
 
  对话框的完成状态。它可以是下面的值: · IDOK 如果对话框被成功显示则返回此值。
 
  · IDCANCEL 如果用户取消了对话框则返回此值。
 
  · IDABORT 如果发生了错误则返回此值。如果返回的是IDABORT,则调用成员函数COleDialog::GetLastError来获取有关所发生错误的类型的进一步信息。可能发生的错误的列表,请参见“OLE 2.01用户接口库”中的OleUIEditLinks函数。
 
  说明:
 
  此函数用来显示OLE Edit Links对话框。
 
  如果你要通过设置m_el结构的成员来初始化不同的对话框控件,你必须要在调用DoModal之前,对话框对象被销毁之后进行。
 
  请参阅:
 
  COleDialog::GetLastError, CDialog::DoModal, COleLinksDialog::m_el
 

编辑本段COleInsertDialog成员

  COleInsertDialog::DoModal
 
  virtual int DoModal( );
 
  int DoModal( DWORD dwFlags );
 
  返回值:
 
  返回对话框的完成状态。可以是下列值之一: · IDOK 如果对话框被成功显示。
 
  · IDCANCEL 如果用户取消了对话框。
 
  · IDABORT 如果发生了一个错误。如果返回的是IDABORT,调用COleDialog::GetLastError成员函数来获取更多有关所发生的错误的类型的信息。可能发生的错误的列表,参见“OLE 2.01用户接口库”中的OleUIInsertObject。
 
  参数: dwFlags 是下列值之一: · COleInsertDialog::DocObjectOnly 将只插入DocObjects。
 
  · COleInsertDialog::ControlsOnly 将只插入ActiveX控件
 
  如果是零,则DoModal将既不插入一个DocObjects,也不插入一个ActiveX控件;它的返回值与上面所列的第一种原形的返回值一样。
 
  说明:
 
  此函数用来显示该OLE Insert Object对话框。
 
  如果你想通过设置m_io结构的成员来初始化不同的对话框控件,你应该在第一DoModal之前,但在对话框对象被构造之后进行。
 
  如果DoModal返回的是IDOK,则你可以调用其它的成员函数来获取用户输入到此对话框中的设置或信息。
 
  请参阅:
 
  COleDialog::GetLastError, CDialog::DoModal, COleInsertDialog::GetSelectionType, COleInsertDialog::GetClassID, COleInsertDialog::GetDrawAspect, COleInsertDialog::GetIconicMetafile, COleInsertDialog::GetPathName, COleInsertDialog::m_io
 

编辑本段COleConvertDialog

  COleConvertDialog::DoModal
 
  virtual int DoModal( );
 
  返回值:
 
  对话框的完成状态。它可以是下列值: · IDOK 若对话框成功显示。
 
  · IDCANCEL 如果用户取消了该对话框。
 
  · IDABORT 若出错。如果返回IDABORT,可调用COleDialog::GetLastError成员函数以取得关于出错类型的相关信息。关于所有可能出现的错误的列表清单,请参阅OLE文档中的OleUIConvert函数。
 
  说明:
 
  调用该函数,以显示OLE 转换对话框。
 
  如果要通过调整m_cv结构的值来初始化对话框中的控件状态,必须在调用DoModal之前,构造对话框对象之后完成此项工作。
 
  如果DoModal返回IDOK,可以调用其它成员函数获取用户在对话框中输入的设置或信息。
 
  请参阅:
 
  COleDialog::GetLastError, CDialog::DoModal, COleConvertDialog::m_cv, COleConvertDialog::DoConvert, COleConvertDialog::GetSelectionType, COleConvertDialog::GetClassID, COleConvertDialog::GetDrawAspect, COleConvertDialog::GetIconicMetafile
 

编辑本段COleChangeSourceDialog

  COleChangeSourceDialog::DoModal
 
  virtual int DoModal( );
 
  返回值:
 
  对话框的完成状态。它可以是下列值: · IDOK 若对话框成功显示。
 
  · IDCANCEL 如果用户取消了该对话框。
 
  · IDABORT 若出错。如果返回IDABORT,可调用COleDialog::GetLastError成员函数以取得关于出错类型的相关信息。关于所有可能出现的错误的列表清单,请参阅“OLE 2.01 用户界面库(User Interface Library)”中的OleUIChangeSource函数。
 
  说明:
 
  调用该函数,以显示OLE变换资源对话框。
 
  如果要通过调整m_cs结构的值来初始化对话框中的控件状态,必须在调用DoModal之前,构造对话框对象之后完成此项工作。
 
  如果DoModal返回IDOK, 可以调用其它成员函数获取用户在对话框中输入的设置或信息。下面所列的是典型的查询函数:
 
  ·GetFileName
 
  ·GetDisplayName
 
  ·GetItemName
 
  请参阅:COleChangeSourceDialog::COleChangeSourceDialog
 

编辑本段COleChangeIconDialog

  COleChangeIconDialog::DoModal
 
  virtual int DoModal( );
 
  返回值:
 
  对话框的完成状态。它可以是下列值: · IDOK 若对话框成功显示。
 
  · IDCANCEL 如果用户取消了该对话框。
 
  · IDABORT 若出错。如果返回IDABORT,可调用COleDialog::GetLastError成员函数以取得关于出错类型的相关信息。关于所有可能出现的错误的列表清单,请参阅“OLE 2.01 用户界面库(User Interface Library)”中的OleUIChangeIcon函数。
 
  说明:
 
  调用该函数,以显示OLE变换图标对话框。
 
  如果要通过调整m_cs结构的值来初始化对话框中的控件状态,必须在调用DoModal之前,构造对话框对象之后完成此项工作。
 
  如果DoModal返回IDOK,可以调用其它成员函数获取用户在对话框中输入的设置或信息。
 
  请参阅:
 
  COleDialog::GetLastError, CDialog::DoModal, COleChangeIconDialog::m_ci, COleChangeIconDialog::DoChangeIcon, COleChangeIconDialog::GetIconicMetafile
 

编辑本段COleBusyDialog成员

  COleBusyDialog::DoModal
 
  virtual int DoModal( ) const;
 
  返回值:
 
  对话框的完成状态。它可以是下列值: · IDOK 若对话框成功显示。
 
  · IDCANCEL 如果用户取消了该对话框。
 
  · IDABORT 若出错。如果返回IDABORT,可调用COleDialog::GetLastError成员函数以取得关于出错类型的相关信息。关于所有可能出现的错误的列表清单,请参阅“OLE 2.01 用户界面库(User Interface Library)”中的OleUIBusy函数。
 
  说明:
 
  调用该函数,以显示OLE服务器忙或服务器没有响应对话框。
 
  如果要通过调整m_bz结构的值来初始化对话框中的控件状态,必须在调用DoModal之前,构造对话框对象之后完成此项工作。
 
  如果DoModal返回IDOK,可以调用其它成员函数获取用户在对话框中输入的设置或信息。
 
  请参阅:
 
  COleDialog::GetLastError, CDialog::DoModal, COleBusyDialog::GetSelectionType, COleBusyDialog::m_bz
 

编辑本段CFontDialog类成员

  CFontDialog::DoModal
 
  virtual int DoModal( );
 
  返回值:
 
  IDOK或IDCANCEL。如果返回IDCANCEL,则调用WindowsCommDlgExtendedError函数判断是否发生了错误。
 
  IDOK或IDCANCEL是表明用户选择了OK还是Cancel按钮的常数。
 
  说明:
 
  调用此成员函数显示一个Windows通用字体对话框,并允许用户选择一种字体。
 
  如果想用设置m_cf结构成员的方法初始化各种字体对话控件,则应在调用DoModal之前,及创建了对话对象之后进行。
 
  如果DoModal返回IDOK,可用其它成员函数获得用户输入对话框的设置或信息。
 
  请参阅:CDialog::DoModal, CFontDialog::CFontDialog
 
  CFileDialog类成员
 
  [编辑本段]
 
  CFileDialog::DoModal
 
  virtual int DoModal( );
 
  返回值:
 
  IDOK或IDCANCEL。如果返回IDCANCEL,调用CommDlgExtendedError函数来判断是否是发生错误。
 
  IDOK或IDCANCEL是表明用户选择了OK还是Cancel按钮的常数。
 
  说明:
 
  调用此成员函数前显示一个Windows常用文件对话框,使用户浏览文件和目录并输入一个文件名。
 
  如果想通过设置m_ofn结构的成员来初始化各种文件对话框选项,则应在调用DoModal之前,创建对话对象之后进行。
 
  当用户单击对话框的OK或Cancel按钮或选择对话框控件菜单中的关闭,则控件返回你的应用,然后可以调用其它成员函数获取用户输入对话框中的更多信息和设置。
 
  DoModal是从CDialog类覆盖得到的虚函数。
 
  请参阅:CDialog::DoModal, CFileDialog::CFileDialog
 

编辑本段CDialog类成员

  CDialog::DoModal
 
  virtual int DoModal();
 
  返回值:
 
  整数值,指定了传递给CDialog::EndDialog(该函数用于关闭对话框) 的nResult参数值。如果函数不能创建对话框,则返回-1;如果出现其它错误,则返回IDABORT。
 
  说明:
 
  调用该成员函数使用模态对话框并返回对话框结果。当对话框处于活动状态时,该函数处理与用户的交互。这使得对话框是模态的,使用户在关闭对话框之前不能与其它窗口交互。
 
  如果用户单击了对话框中的按钮,如OK或Cancel,那么消息处理函数如OnOK或OnCancel被调用,从而关闭对话框。缺省的OnOK成员函数会对对话框数据进行有效性检验和更新,并关闭它得到结果IDOK。缺省OnCancel函数关闭对话框得到结果IDCANCEL,而不对对话框数据检验或更新,可以覆盖这些消息函数并改变它们的行为。注意 目前PreTransMessage被调用来处理模态对话框的消息。
 
  请参阅:::DialogBox, CWnd::IsDialogMessage
 

编辑本段CColorDialog类成员

  CColorDialog::DoModal
 
  virtual int DoModal( );
 
  返回值:
 
  IDOK或者IDCANCEL。如果返回了IDCANCEL,则可以调用Windows函数CommDlgExtendedError来检测是否发生了错误。
 
  说明:
 
  本函数用于显示Windows通用颜色对话框并接收用户的选择。
 
  如果想通过设置m_cc结构的各个成员来初始化不同的颜色对话框,应在对话框对象构造之后,调用DoModal之前进行。
 
  在调用DoModal之后,可以调用其它的成员函数检索设置信息和用户输入的信息。
 
  请参阅:CDialog::DoModal, CColorDialog::CColorDialog

 

原文地址:https://www.cnblogs.com/langzi93/p/2488859.html