模态和非模态

来源:互联网 发布:浪迹教育 知乎 编辑:程序博客网 时间:2024/06/05 07:25

 首先,应用老奎哥给我的帮助:

我调用WM_CLOSE后,他退出的是程序还是本窗口呢?比如:我一个主界面,点击进入了子界面,我在字界面里面WM_CLOSE,想关闭字界面,但退出的仍然是整个程序!有办法让只关闭字界面吗?以前我是隐藏字界面。但现在在创建的时候初始化了好多东西。如果隐藏了,下次进入初始化都做不了!!!

1,我创建好字界面,我就保存字界面句柄m_pParent = m_hWnd; 2.case IDM_OK: ::sendMessage (m_pParent, WM_CLOSE, 0, 0); break; 3.if (nMessage == WM_CLOSE) { DestroyWindow(m_pParent); } if (nMessage == WM_DESTROY) { g_EGp.Exit();//析构EGp类 PostQuitMessage(0); return 1; }

 

如果是模态的,你的代码就应该没有问题(模态表示有消息泵

如果是非模态的, 去掉PostQuitMessage就可以了

老奎xdkui 说 (10:24):
但是我建议你用模态的,一般这种弹出window都是作为子window以模态形式存在的
老奎xdkui 说 (10:25):
不然,如果你们的测试人员很强的话,你会遇到无穷无尽的bug,windows关系的bug很难调的
(这里还不能深入理解,看到的朋友可以给我再留言讲讲。谢谢。。。)

现在收集一些这方面的知识,以便以后理解。

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


使用非模态对话框与使用模态对话框相似,但是也有一些重要的区别:

首先,非模态对话框通常包含一个标题列和一个系统菜单按钮。当您在Developer Studio中建立对话框时,这些是内定选项。用于非模态对话框的对话框模板中的STYLE叙述形如:

STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE       
标题列和系统菜单允许使用者,使用鼠标或者键盘将非模态对话框移动到另一个显示区域。对于模态对话框,您通常无须提供标题列和系统菜单,因为使用者不能在其下面的窗口中做任何其它的事情。

第二项重要的区别是:注意,在我们的范例STYLE叙述中包含有WS_VISIBLE样式。在 Developer Studio中,从「Dialog Properties」对话框的「More Styles」页面卷标中选择此选项。如果省略了WS_VISIBLE,那么您必须在CreateDialog呼叫之后呼叫ShowWindow:

 

hDlgModeless = CreateDialog (  . . .  ) ;  

 ShowWindow (hDlgModeless, SW_SHOW) ;       
如果您既没有包含WS_VISIBLE样式,又没有呼叫ShowWindow,那么非模态对话框将不会被显示。如果忽略这个事实,那么习惯于模态对话框的程序写作者在第一次试图建立非模态对话框时,经常会出现问题。

第三项区别:与模态对话框和消息框的消息不同,非模态对话框的消息要经过程序式的消息队列。要将这些消息传送给对话框窗口消息处理程序,则必须改变消息队列。方法如下:当您使用CreateDialog建立非模态对话框时,应该将从呼叫中传回的对话框句柄储存在一个整体变量(如hDlgModeless)中,并将消息循环改变为:

 

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

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

TranslateMessage (&msg) ;  

 DispatchMessage  (&msg) ;  

 } 

}       
如果消息是发送给非模态对话框的,那么IsDialogMessage将它发送给对话框中窗口消息处理程序,并传回TRUE(非0);否则,它将传回FALSE(0)。只有hDlgModeless为0或者消息不是该对话框的消息时,才必须呼叫TranslateMessage和DispatchMessage函数。如果您将键盘快捷键用于您的程序窗口,那么消息循环将如下所示:

 

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

{  

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

 {  

if (!TranslateAccelerator (hwnd, hAccel, &msg)) 

     {

        TranslateMessage (&msg) ;  

        DispatchMessage  (&msg) ;   

    }  

 }   

}       
由于整体变量被初始化为0,所以hDlgModeless将为0,直到建立对话框为止,从而保证不会使用无效的窗口句柄来呼叫IsDialogMessage。在清除非模态对话框时,您也必须注意这一点,正如最后一点所说明的。

hDlgModeless变量也可以由程序的其它部分使用,以便对非模态对话框是否存在加以验证。例如,程序中的其它窗口可以在hDlgModeless不等于0时给对话框发送消息。

最后一项重要的区别:使用DestroyWindow而不是EndDialog来结束非模态对话框。当您呼叫DestroyWindow后,将hDlgModeless整体变量设定为0。

使用者习惯于从系统菜单中选择「Close」来结束非模态对话框。尽管启用了「Close」选项,Windows内的对话框窗口消息处理程序并不处理WM_CLOSE消息。您必须自己在对话框程序中处理它:

 

case        WM_CLOSE :     

  DestroyWindow (hDlg) ;  

  hDlgModeless = NULL ; 

  break ;       
注意这两个窗口句柄之间的区别:DestroyWindow的hDlg参数是传递给对话框程序的参数;hDlgModeless是从CreateDialog传回的整体变量,程序在消息循环内检验它。

您也可以允许使用者使用按键来关闭非模态对话框,处理方式与处理WM_CLOSE消息一样。对话框必须传回给建立它的窗口之任何数据都可以储存在整体变量中。如果不喜欢使用整体变量,那么您也可以用CreateDialogParam来建立非模态对话框,并按前面介绍的方法让它储存一个结构指针。

 

http://phil2360.spaces.live.com/blog/cns!71CD456F35382A94!261.entry

 

原创粉丝点击