模式对话框与⾮模式对话框的区别
模式对话框就是不处理它就没法处理⽗窗⼝,⽽⾮模式对话框就是不⽤先处理此对话框也可以处理⽗窗⼝.例⼦:在桌⾯上右击我的电脑,选择属性,弹出系统属性窗⼝,点击下⾯的技术⽀持,弹出技术⽀持信息,现在再对系统属性窗⼝进⾏操作就操作不了,这种叫做模式对话框;关闭技术⽀持信息,在系统属性⾥选择硬件,点击设备管理器,弹出设备管理器窗⼝,现在再对系统属性窗⼝进⾏操作仍然可以操作,这种就叫做⾮模式对话框。
在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 将它交由对话消息处理函数处理,并返回TRU
E。不需要再派发了。
注意:这个⽅法并不是很好⽤,因为当对话框过多的时候,处理起来就⽐较⿇烦了。另⼀种处理的⽅法是利⽤⼦类化控件的⽅法,来处理控件间的交互。
三、销毁的区别
模式对话框的销毁是使⽤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值。
模态⾮模态
形式上①⼀个模式对话框是⼀个有系统菜单、标题栏、边线等的弹出式窗⼝。
在创建对话框时指定WS_POPUP, WS_SYSMENU, WS_CAPTION和
DS_MODALFRAME风格。即使没有指定WS_VISIBLE风格,模式对话框也
会被显⽰。
②创建对话框窗⼝时,将发送WM_INITDIALOG消息(如果指定对话框的
DS_SETFONT风格,还有WM_SETFONT消息)给对话框过程。(对话框的
窗⼝过程由Windows系统提供,⽤户在创建对话框窗⼝时提供⼀个对
话框过程由窗⼝过程调⽤。)
③对话框窗⼝被创建之后,Windows使得它成为⼀个激活的窗⼝,它保持激
活直到对话框过程调⽤::EndDialog函数结束对话框的运⾏或者Windows激活
另⼀个应⽤程序为⽌,在激活时,⽤户或者应⽤程序不可以激活它的所属窗
⼝(Owner window)。
①⼀个⽆模式对话框是⼀个有系统菜单、标题栏、边线等
的弹出式窗⼝。在创建对话框模板时指定WS_POPUP、
WS_CAPTION、WS_BORDER和WS_SYSMENU风格。如
果没有指定WS_VISIBLE风格,⽆模式对话框不会
⾃动地显⽰出来。
②⼀个⽆模式对话框既不会禁⽌所属窗⼝,也不会给它发送消
息。当创建⼀个模式对话框时,Windows使它成为活动窗
⼝,但⽤户或者程序可以随时改变和设置活动窗⼝。如果对
话框失去激活,那么即使所属窗⼝是活动的,在Z轴顺序上,
它仍然在所属窗⼝之上。
创建DoModal()Create()
销毁⼀个应⽤程序通过调⽤::EndDialog函数来销毁⼀个模式对话框。⼀般情况
下,当⽤户从系统菜单⾥选择了关闭(Close)命令或者按下了确认(OK)
或取消(CANCLE)按钮,::EndDialog被对话框过程
所调⽤。调⽤::EndDialog时,指定其参数nResult的值,Windows将在销毁对
话框窗⼝后返回这个值,⼀般,程序通过返回值判断对话框窗⼝是否完成了
任务或者被⽤户取消。
※ EndDialog(IDC_BUTTON_DEFAULT);我们的代码中EndDialog⽅法在指定
的BUTTON处理事件结束时调⽤,来关闭对话框
在应⽤程序结束之前,它必须销毁所有的⽆模式对话框。使
⽤::DestroyWindow销毁⼀个⽆模式对话框,不是使
⽤::EndDiaLog。⼀般来说,对话框过程响应⽤户输⼊,如
⽤户选择了“取消”按钮,则⾃动调⽤::DestroyWindow;如果
⽤户没有有关动作,则应⽤程序必须调⽤::DestroyWindow。
系统处理⾮模态对话框和模态对话框的区别
⾮模态对话框相对于模态对话框,他的创建和销毁过程和模态对话框有⼀定的区别先看⼀下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()    重载函数,允许⽤户⾸先⼦分类⼀个窗⼝
delete in2.OnCreate()            消息响应函数,响应WM_CREATE消息,发送此消息以告诉⼀个窗⼝已经被创建
3.OnSize()              消息响应函数,响应WM_SIZE消息,发送此消息以告诉窗⼝⼤⼩发⽣变化
4.OnMove()              消息响应函数,响应WM_MOVE消息,发送此消息以告诉窗⼝正在移动
5.OnSetFont()            消息响应函数,响应WM_SETFONT消息,发送此消息以允许改变对话框中控件的字体以上这些的执⾏都是按给定的顺序执⾏!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。