用过windows的对于对话框并不陌生,其主要用于完成特定的任务,是人机交互的一个方式。对话框可以分为两种:模态对话框和非模态对话框。
模态对话框也可分为两种,一种是系统方式的模态对话框,这种对话框只有当其结束时,你才能访问其他窗口,例如单击关机按钮时,出现的包含待机,重启,关机三个按钮的对话框。一种是需然不能点击父窗口,但可以点击其他窗口的模态对话框。
用VC++创建的对话框模板解析:
ABOUTBOX DIALOG DISCARDABLE 32,32,180,100
STYLE DS_MODLEFRAME|WS_POPUP
FONT 8,"MS San Serif"
BEGIN
DEFPUSHBUTTON "OK",IDOK,66,80,50,14
ICON "ABOUT1",IDC_STATIC,7,7,21,30
CTEXT "About1“,IDC_STATIC,40,12,100,8
CTEXT "About Box Program",IDC_STATIC,7,40,166,8
CTEXT "(c) Charles Petzold,1998",IDC_STATIC,7,52,166,8
END
解释:
(1):ABOUTBOX DIALOG DISCARDABLE 32,32,180,100。其中ABOUTBOX为对话框模板的名称,DIALOG为关键字,DISCARDABLE关键字和前面其他资源意思相同。后面的4个数字,前面两个数字为左上角相对于父窗口客户区的坐标,后面两个数字为对话框的宽度和高度。注意这四个数字的单位不是像素,其中x坐标方向的单位为对话框中字体的宽度的1/4,y坐标方向的单位为对话框字体的高度的1/8.
(2):STYLE DS_MODLEFRAME|WS_POPUP。这条语句为对话框的整体样式。STYLE为关键字。
(3):FONT 8,"MS San Serif"。这条语句为字体的样式和大小。
(4):当我们需要用窗口过程来对对话框的消息进行处理时,而不是用对话框过程来处理对话框消息时。我们需在对话框模板中添加语句:CLASS "类名"
(5):BEGIN和END之间为对话框中的空间。这个例子中用到了三种控件:DEFPUSHBUTTON(按钮),CTEXT(文本),ICON(图标).其格式如下:
控件类型 "文本",ID,x,y,xWidth,yHeight,iStyle 其中的iStyle可以省略。一些常见控件类型的样式和窗口类如下:
控件类型 | 窗口类 | 窗口样式 |
PUSHBUTTON | button | BS_PUSHBUTTON|WS_TABSTOP |
DEFPUSHBUTTON | button | BS_DEFPUSHBUTTON|WS_TABSTOP |
CHECKBOX | button | BS_CHECKBOX|WS_TABSTOP |
RADIOBUTTON | button | BS_RADIOBUTTON|WS_TABSTOP |
GROUPBOX | button | BS_GROUPBOX |
LTEXT | static | SS_LEFT|WS_GROUP |
CTEXT | static | SS_CENTER|WS_GROUP |
RTEXT | static | SS_RIGHT|WS_GROUP |
ICON | static | SS_ICON |
EDITTEXT | edit | ES_LEFT|WS_BORDER|WS_TABSTOP |
SCROLLBAR | scrollbar | SBS_HORZ |
LISTBOX | listbox | LBS_BOTIFY|WS_BORDER |
COBOBOX | combobox | CBS_SIMPLE|WS_TABSTOP |
1)上面的各种控件类型的样式都包含如下样式:WS_CHILD|WS_VISIBLE。注意:当需要去除上面默认包含的样式时,可在iStyle使用NOT,当然也可以加入一些其他的类型。如去除EDITTEXT中的边框:
EDITTEXT ID,x,y,xWidth,yHeight,NOT WS_BORDER
2)其中除去EDITTEXT,SCROLLBAR,LISTBOX,COMBOBOX外其格式都如下:
控件类型 "文本",ID,x,y,xWidth,yHeight,iStyle
其中EDITTEXT,SCROLLBAR,LISTBOX,COMBOBOX的格式都如下:
控件类型 ID,x,y,xWidth,yHeight,iStyle
注意:上面的格式也可以为:
CONTROL "文本',ID,"窗口类",类型,x,y,xWidth,yHeight
3)当需要TAB键来移动控件的输入焦点时,需在控件的样式中使用WS_TABSTOP。使用WS_TABSTOP后,创建对话框后,windows会自动将输入焦点定位到第一个具有WS_TABSTOP样式的控件上,这样可以用TAB键在具有WS_TABSTOP样式的各个控件间移动。
4)当使用WS_GROUP样式后,就可以使用方向键来移动输入焦点。
模态对话框
模态对话框的创建使用DialogBox函数:
int DialogBox(HINSTANCE hlnstance,LPCTSTRIpTemplate,HWND hWndParent,DLGPROC IpDialogFunc);
注意:其也可以运用DialogBoxParam函数来创建对话框,这个函数多了最后一个参数,其为一个指针类型。
其中的第一个参数为实例句柄,第二参数为使用的对话框模板名,第三个参数为产生对话框的窗口的句柄,第四个参数为对话框过程,其格式如下:
BOLL CALLBACK ABOUTDLGPROC(HWND hlg,UINT message,WPARAM wparam,LPARAM lparam)
{
switch(message)
{
WM_INITDIALOG:
return TRUE;
WM_COMMAND:
{
switch(LOWORD(wparam))
{
WM_IDOK:
WM_IDCANCLE:
EndDialog(hlg,0);
return TRUE;
}
return FALSE;
}
对话框的结束使用EndDialog函数。其中第一个参数为对话框的句柄,第二个参数为一个整数,其会作为DialogBox的返回值,我们可以通过这个值,对结果进行处理。通过这个窗口过程我们可以看到,当对话框过程对消息进行处理时,其会返回一个TRUE值,当不对消息进行处理时,会返回FALSE值,这是windows就会调用DefWindowProc函数对对话框过程没有处理的消息进行处理。
对话框过程和窗口过程的区别(非模态对话框相同):
1):对话框过程的返回值为BOOL值,而窗口过程的返回值为LRESULT。
2):当窗口过程不对消息进行处理时,会调用DefWindowProc函数;当对话框不对消息进行处理时会返回FALSE值,否则返回TRUE值。
3):对话框不对WM_PAINT和WM_DESTROY消息进行处理,其也不会接收到WM_CREATE消息,其最先接收到得消息是WM_INITDIALOG。
模态对话框过程处理消息的过程:首先windows会把消息发送给对话框管理器DefDialogProc,DefDialogProc根据用户需要调用对话框过程函数。对话框过程函数对消息进行处理时,返回TRUE值;如果不对消息进行处理,会返回FALSE值。如果DefDialogProc接收到得对话框过程函数返回的值是FALSE时,其会自己进一步处理或者调DefWindowProc
函数来班子处理,其处理完后会返回DefDialogProc,最后DefDialogProc会返回到windows。过程图如下:
message windows
| |
DefDialogProc -------->DefWindowProc
对话框管理器 <--------用窗口过程函数进行处理
| 0|1
应用程序的对话框函数
非模态对话框
非模态对话框的创建运用CreateDialog函数:
HWND CreateDialog(HINSTANCE hlnstance,LPCTSTR lpTemplate,HWND hWndParent,DLGPROC IpDialogFunc);
其中的参数和DialogBox的参数相同。也可以调用CreateDialogParam函数。
注意:非模态对话框产生的消息会进入消息队列,因此可以在不同的窗口间切换。
非模态对话框和模态对话框的区别:
1):非模态对话框一般包含标题栏和系统菜单栏。这样可以通过鼠标或者键盘通过点击标题栏来移动对话框,以便对对话框下的内容好操作。而莫泰对话框由于不能对其他窗口进行操作,所以无需标题栏。
2):非模态对话框需我们用WS_VISIBLE或这调用ShowWindow函数来显示对话框,而模态对话框无需我们明确指示。
3):非模态对话框的消息由windows产生,进入消息队列,而模态对话框的消息不进入消息队列,其由windows发出经对话框管理器,再到对话框过程。对于非模态对话框在用GetMessage获取消息时必须对获取的消息进行一些判断,这样才能保证获取的消息能过被送到对话框处理函数。如下:
while(GetMessage(&msg,NULL,0,0))
{
if(hDlgModeless==0||IsDialogMessage(hDlgModeless,&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
其中hDlgModelsee为CreateDialog函数的返回值,如果CreateDialog函数创建对话框成功会返回对话框的句柄,否则返回0.IsDialogMessage(hDlgModeless,&msg)函数将消息发送到对话框过程函数,并返回TRUE(非零值),否则返回FALSE值.
注:非模态对话框的窗口过程和窗口过程的区别和模态对话框相同。结束对话框调用DestroyWindow函数。
WM_COMMAND消息中wparam的高字节为子窗口ID,低字节为通知码,lparam为子窗口句柄。