对话框分为“模态对话框”和“非模态对话框”两种。模态对话框允许用户在对话框与
其他程序之间进行切换(系统模态对话框例外,显示了系统模态对话框之后,要完成其他任
何操作,必须先结束该对话框)。但在清除模态对话框之前,用户不能切换到同一程序的其他
窗口中。非模态对话框与用户常见的普通弹出式窗口相似,除了允许用户在对话框与其他程
序之间切换,还允许在对话框与创建对话框的窗口之间切换。
创建模式对话框和非模式对话框函数的参数是相同的,所不同的是前者在清楚对话框之
后函数才返回值,而后者是立即返回对话框的句柄。
使用非模态对话框与使用模态对话框有一些重要的区别:
第一,非模态对话框通常包含一个标题栏和一个系统菜单框。用于非模态对话框的对话
框模板中的STYLE语句如下:
STYLE WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_VISIBLE
标题栏和系统菜单允许用户使用鼠标或者键盘将非模态对话框移到另一个显示区域。而
对于模态对话框,通常无需提供标题栏和系统菜单,因为用户不能在其下面的窗口中做任何
其他事情。
第二,如果在非模态对话框的STYLE中不包含WS_VISIBLE 风格,那么读者必须在
CreatDialog调用之后调用ShowWindow。调用语句如下:
dDlgModeless=CreateDialog();
ShowWindow(hDlgModeLess,SW_SHOW);
否则非模态对话框将不被显示,而在模态对话框中则不必如此。
第三,与模态对话框不同,非模态对话框的消息要经过程序的消息队列。要将这些消息
传给对话框窗口过程,则必须要更改消息队列。当读者使用CreateDialog创建非模态对话框
时,应该将从调用中返回的对话框句柄保存在一个全局变量(如hDlgModeless)中,并将消
息循环更改为:
While(GetMessage(&msg,NULL,0,0))
{
if(hDlgModeless==0||!lsDialogMessage(hDlgModeless,&msg))
Windows下的C/C++高级编程
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
如果消息是发给非模态对话框的,那么IsDialogMessage将它发送给对话框中窗口过程并返回TRUE,否则,将返回FALSE。只有dDlgModeless为零或者消息不是该对话框时才调用TranslateMessage和DispatchMessage函数。如果将键盘加速键用于程序窗口,消息循环就变成如下所示:
While(GetMessage(&msg,NULL,0,0))
{
if(hDlgModeless==0||!lsDialogMessage(hDlgModeless,&msg))
{
if(!TranslateAcceleratot(hwnd,hAccel,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
由于全局变量hDlgModeless被初始化为0,直到创建对话框为止,从而保证了不会使用无效的窗口句柄来调用IsDialogMessage。
hDlgModeless变量也可以由程序的其他部分使用,用来对非模态对话框是否存在加以验证。
第四,使用DestoryWindow而不是EndDialog来结束非模态对话框,这就更显示了非模态对话框的窗口特性了,当读者调用了DestoryWindow后,将使用hDlgModeLess全局变量设置为0。
由于用户习惯从菜单中选择关闭来结束非模态对话框,而Windows内的对话框窗口过程并不处理WM_CLOSE消息,所以用户有必要在对话框过程中处理它。
case WM_CLOSE:
DestroyWindow(hDlg);
hDlgModeLess=NULL;
break;
用户也可以使用下压按钮来关闭非模态对话框,这和处理WM_CLOSE消息是一样的。对话框必须返回给创建它的窗口的任何数据都可以被存储在全局变量中。