`
蒙面考拉
  • 浏览: 160527 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

模态对话框与非模态对话框

阅读更多

原文地址:http://www.cnblogs.com/afarmer/archive/2012/03/31/2427328.html

 

模式对话框就是不处理它就没法处理父窗口,而非模式对话框就是不用先处理此对话框也可以处理父窗口.例子:在桌面上右击我的电脑,选择属性,弹出系统属性窗口,点击下面的技术支持,弹出技术支持信息,现在再对系统属性窗口进行操作就操作不了,这种叫做模式对话框;关闭技术支持信息,在系统属性里选择硬件,点击设备管理器,弹出设备管理器窗口,现在再对系统属性窗口进行操作仍然可以操作,这种就叫做非模式对话框。


在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以销毁非模式对话框。

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

四、其他

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

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

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

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

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

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


 

 

系统处理非模态对话框和模态对话框的区别

 

非模态对话框相对于模态对话框,他的创建和销毁过程和模态对话框有一定的区别 先看一下MSDN的原文: When   you   implement   a   modeless   dialog   box,   always   override   the   OnCancel   member   function   and   call   DestroyWindow   from   within   it.   Don’t   call   the   base   class   CDialog::OnCancel,   because   it   calls   EndDialog,   which   will   make   the   dialog   box   invisible   but   will   not   destroy   it.   You   should   also   override   PostNcDestroy   for   modeless   dialog   boxes   in   order   to   delete   this,   since   modeless   dialog   boxes   are   usually   allocated   with   new.   Modal   dialog   boxes   are   usually   constructed   on   the   frame   and   do   not   need   PostNcDestroy   cleanup. MS的指示:非模态对话框需要重载函数OnCanel,并且在这个函数中调用DestroyWindow。并且不能调用基类的OnCancel,因为基类的OnCancel调用了EndDialog这个函数,这个函数是针对模态对话框的。 还有一个必须重载的函数就是PostNcDestroy,这也是一个虚函数,通常的非模态对话框是用类的指针,通过new创建的,这就需要在PostNcDestroy函数中delete掉这个指针。

了解了理论过后,下面我们就可以用代码实现一下非模态对话框的创建和销毁过程:

//建立

//主框架中:

CTestDlg *pDlg=new CTestDlg;

pDlg->Create(IDD_TESTDLG,this);

pDlg->ShowWindow(SW_SHOW);

//对话框中:

void CTestDlg::OnCancel()

{

    DestroyWindow();

}

void CTestDlg::PostNcDestroy()

{

    CDialog::PostNcDestroy();

    delete this;

}

如果要在点击按钮的情况下,销毁非模态对话框,只需要把按钮的事件映射到OnCancel函数即可。

以下是一点资料供参考,非模态对话框的销毁顺序:

 

MFC应用程序中处理消息的顺序

1.AfxWndProc()      该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc

2.AfxCallWndProc() 该函数负责保存消息(保存的内容主要是消息标识符和消息参数)供应用程序以后使用,然后调用WindowProc()函数

3.WindowProc()      该函数负责发送消息到OnWndMsg()函数,如果未被处理,则调用DefWindowProc()函数

4.OnWndMsg()        该函数的功能首先按字节对消息进行排序,对于WM_COMMAND消息,调用OnCommand()消息响应函数,对于WM_NOTIFY消息,调用OnNotify()消息响应函数。任何被遗漏的消息将是一个窗口消息。OnWndMsg()函数搜索类的消息映像,以找到一个能处理任何窗口消息的处理函数。如果OnWndMsg()函数不能找到这样的处理函数的话,则把消息返回到WindowProc()函数,由它将消息发送给DefWindowProc()函数

5.OnCommand()       该函数查看这是不是一个控件通知(lParam参数不为NULL,如果lParam参数为空的话,说明该消息不是控件通知),如果它是,OnCommand()函数会试图将消息映射到制造通知的控件;如果他不是一个控件通知(或者如果控件拒绝映射的消息)OnCommand()就会调用OnCmdMsg()函数

6.OnCmdMsg()        根据接收消息的类,OnCmdMsg()函数将在一个称为命令传递(Command Routing)的过程中潜在的传递命令消息和控件通知。 例如:如果拥有该窗口的类是一个框架类,则命令和通知消息也被传递到视图和文档类,并为该类寻找一个消息处理函数

 

MFC应用程序创建窗口的过程

1.PreCreateWindow()   该函数是一个重载函数,在窗口被创建前,可以在该重载函数中改变创建参数 (可以设置窗口风格等等)

2.PreSubclassWindow() 这也是一个重载函数,允许首先子分类一个窗口

3.OnGetMinMaxInfo()   该函数为消息响应函数,响应的是WM_GETMINMAXINFO消息,允许设置窗口的最大或者最小尺寸

4.OnNcCreate()        该函数也是一个消息响应函数,响应WM_NCCREATE消息,发送消息以告诉窗口的客户区即将被创建

5.OnNcCalcSize()      该函数也是消息响应函数,响应WM_NCCALCSIZE消息,作用是允许改变窗口客户区大小

6.OnCreate()          该函数也是一个消息响应函数,响应WM_CREATE消息,发送消息告诉一个窗口已经被创建

7.OnSize()            该函数也是一个消息响应函数,响应WM_SIZE消息,发送该消息以告诉该窗口大小已经发生变化

8.OnMove()            消息响应函数,响应WM_MOVE消息,发送此消息说明窗口在移动

9.OnChildNotify()     该函数为重载函数,作为部分消息映射被调用,告诉父窗口即将被告知一个窗口刚刚被创建

 

MFC应用程序关闭窗口的顺序(非模态窗口)

1.OnClose()       消息响应函数,响应窗口的WM_CLOSE消息,当关闭按钮被单击的时候发送此消息

2.OnDestroy()     消息响应函数,响应窗口的WM_DESTROY消息,当一个窗口将被销毁时,发送此消息

3.OnNcDestroy()   消息响应函数,响应窗口的WM_NCDESTROY消息,当一个窗口被销毁后发送此消息

4.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作,被CWnd调用

 

MFC应用程序中打开模式对话框的函数调用顺序

1.DoModal()             重载函数,重载DoModal()成员函数

2.PreSubclassWindow()   重载函数,允许首先子分类一个窗口

3.OnCreate()            消息响应函数,响应WM_CREATE消息,发送此消息以告诉一个窗口已经被创建

4.OnSize()              消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗口大小发生变化

5.OnMove()              消息响应函数,响应WM_MOVE消息,发送此消息,以告诉窗口正在移动

6.OnSetFont()           消息响应函数,响应WM_SETFONT消息,发送此消息,以允许改变对话框中控件的字体

7.OnInitDialog()        消息响应函数,响应WM_INITDIALOG消息,发送此消息以允许初始化对话框中的控件,或者是创建新控件

8.OnShowWindow()        消息响应函数,响应WM_SHOWWINDOW消息,该函数被ShowWindow()函数调用

9.OnCtlColor()          消息响应函数,响应WM_CTLCOLOR消息,被父窗口发送已改变对话框或对话框上面控件的颜色

10. OnChildNotify()     重载函数,作为WM_CTLCOLOR消息的结果发送

 

MFC应用程序中关闭模式对话框的顺序

1.OnClose()        消息响应函数,响应WM_CLOSE消息,当"关闭"按钮被单击的时候,该函数被调用

2.OnKillFocus()    消息响应函数,响应WM_KILLFOCUS消息,当一个窗口即将失去键盘输入焦点以前被发送

3.OnDestroy()      消息响应函数,响应WM_DESTROY消息,当一个窗口即将被销毁时,被发送

4.OnNcDestroy()    消息响应函数,响应WM_NCDESTROY消息,当一个窗口被销毁以后被发送

5.PostNcDestroy() 重载函数,作为处理OnNcDestroy()函数的最后动作被CWnd调用

 

打开无模式对话框的顺序

1.PreSubclassWindow()    重载函数,允许用户首先子分类一个窗口

2.OnCreate()             消息响应函数,响应WM_CREATE消息,发送此消息以告诉一个窗口已经被创建

3.OnSize()               消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗口大小发生变化

4.OnMove()               消息响应函数,响应WM_MOVE消息,发送此消息以告诉窗口正在移动

5.OnSetFont()            消息响应函数,响应WM_SETFONT消息,发送此消息以允许改变对话框中控件的字体

以上这些的执行都是按给定的顺序执行!

  • 大小: 51.1 KB
分享到:
评论

相关推荐

    模态对话框与非模态对话框程序Java示例

    非模态对话框则允许用户同时与对话框和父窗口进行交互,提高了用户的生产力,因为它们不必按照特定顺序完成任务。在Swing库中,JDialog类可以用于创建自定义的非模态对话框。 例如,`C08_3_MyDialog.java`可能创建...

    MFC模态对话框与非模态对话框

    MFC中经常会用到弹出模态或非模态对话框,模态对话框与非模态对话框容易混淆

    vc的模态对话框和非模态对话框

    在Visual C++(VC)中,模态对话框与非模态对话框是两种常见的对话框类型,它们各自具备独特的特性和用途。理解这两种对话框的区别对于开发用户友好的应用程序至关重要。 #### 模态对话框特性 模态对话框是一种...

    详解VC++模态对话框和非模态对话框

    在VC++中,MFC(Microsoft Foundation Classes)框架提供了两种主要的对话框类型:模态对话框和非模态对话框。这两种对话框在程序执行流程和用户交互方面有着显著的区别。 模态对话框(Modal Dialog Box)是通过...

    VC中模态对话框和非模态对话框的编程

    这意味着用户可以同时与非模态对话框和其他用户界面对象进行交互。 #### 二、对话框的数据交换机制(DDX) 对话框通常包含多种控件,如文本框、复选框等,这些控件用于收集用户的输入数据。为了实现对话框与这些控件...

    mfc中模态、非模态对话框与主对话框之间的数据交换

    点击运行弹出一个对话框,点击DIALOG1按钮弹出一个模态对话框,在该对话框的编辑框输入文本点击确定该对话框消失且输入的文本被显示到主对话框MainDialog中,点击DAILOG2按钮弹出一个非模态对话框,操作现象和模态...

    MFC模态对话框和非模态对话框

    非模态对话框允许用户在对话框打开的同时与应用程序的其他部分进行交互。在MFC中,我们需要继承CDialog类,并重写 OnInitDialog() 函数,然后使用Create()函数来创建和显示非模态对话框。例如: ```cpp class ...

    MFC模态 非模态对话框 ARX2008+VS2005

    非模态对话框则不会阻止用户与父窗口交互,它们可以与父窗口同时存在并进行操作。在MFC中,我们通过`CWnd`类的派生类来实现非模态对话框,并使用`Create()`或`CreateEx()`方法创建。非模态对话框在ARX中适用于需要...

    模态对话框和非模态对话框创建和使用VS2010/MFC

    **非模态对话框** 不会阻止用户与主窗口或其他窗口交互。它像一个独立的窗口,可以同时与对话框和其他窗口进行操作。在MFC中,非模态对话框通常通过`Create()`函数创建并显示,而不是`DoModal()`。例如,创建一个名...

    android 模态与非模态对话框实现

    非模态对话框(Non-Modal Dialog)则不会阻止用户与应用程序的其他部分进行交互。一个典型的非模态对话框例子是PopupWindow,它可以在屏幕上显示一个浮动窗口,用户可以同时操作弹出窗口和主界面。PopupWindow的使用...

    vc非模态对话框例子

    非模态对话框与模态对话框不同,在非模态对话框活动的同时,用户还可以在应用程序的其他地方工作,而模态对话框在其关闭之前,用户不能在同一个应用程序的其他地方工作。本例将从主框架窗口创建一个简单的非模态...

    MFC学习之模态对话框和非模态对话框

    创建非模态对话框的步骤与模态对话框类似,但不调用`DoModal`,而是使用`Create`函数实例化对话框,并在需要时调用`ShowWindow(SW_SHOW)`显示它。 在给定的示例中,`Dialog`可能是包含模态和非模态对话框的源代码...

    VS2010+MFC 模态对话框、非模态对话框的显示与打开以及对话框的之间的数据传递

    在本文中,我们将深入探讨如何在VS2010中使用MFC实现模态对话框(Modal Dialog)和非模态对话框(Modeless Dialog)的显示与打开,以及它们之间的数据传递。 首先,模态对话框是一种阻止用户与应用程序其他部分交互...

    模态与非模态对话框创建

    **模态对话框与非模态对话框** 在Windows应用程序设计中,对话框是一种关键的用户界面元素,用于用户与程序之间的数据交换。对话框分为模态和非模态两种类型,它们各自有不同的特性和使用场景。 **1. 模态对话框**...

    模态与非模态对话框的区别与操作.pdf

    【模态对话框与非模态对话框的区别】 模态对话框和非模态对话框是Windows编程中两种常见的对话框类型,它们在用户交互和程序流程控制上有显著的差异。 1. **创建方式** - **模态对话框**(Modal Dialog Box)通常...

    模态与非模态对话框的区别.pdf

    【模态对话框与非模态对话框的区别】 在计算机编程中,特别是在Windows应用程序开发中,模态对话框(Modal Dialog Box)和非模态对话框(Modeless Dialog Box)是两种不同类型的用户界面元素,它们在用户交互和程序...

    创建非模态对话框

    3. **资源消耗**:相比模态对话框,非模态对话框可能会占用更多的系统资源,因为它不阻止用户与其他窗口交互。 #### 创建非模态对话框的步骤 根据给定的部分内容,创建非模态对话框主要包括以下几个步骤: 1. **...

    MFC多线程创建非模态对话框(防止一闪而逝)

    在本示例中,我们将讨论如何在MFC环境中创建一个非模态对话框,并通过多线程防止其“一闪而逝”的现象。 首先,我们要理解“一闪而逝”的问题。通常,当在主对话框的单击事件中直接创建并显示一个新的非模态对话框...

    qml自定义模态对话框

    模态对话框是一种阻塞用户与对话框之外的界面交互的窗口,直到用户完成对话框中的操作或关闭对话框。这种设计有助于集中用户的注意力,并确保在处理关键任务时不会被其他操作打扰。 创建自定义模态对话框的第一步是...

Global site tag (gtag.js) - Google Analytics