Dialog 依其 与父窗口的关系,分为两类:
- Modal dialog: 在关闭对话框前,不能激活同一应用的其他窗口;
- Modeless dialog:
创建Modal Dialog Box
可以使用API函数DialogBox创建一个Modal Dialog Box。You must specify the identifier or name of a dialog box template resource and a pointer to the dialog box procedure. The DialogBox function loads the template, displays the dialog box, and processes all user input until the user closes the dialog box.
1. 打开Resource Editor,在Menu的模板中加入一个新的项目,比如叫Dialog Help,并在其下面新创建一个下拉菜单项目Introduction(Dialog);这时,在rc文件中Menu模板的定义如下所示:
BEGIN
POPUP "&File"
BEGIN
MENUITEM "E&xit", IDM_EXIT
END
POPUP "Edit"
BEGIN
MENUITEM "Search(Modeless Dialog)", ID_EDIT_SEARCH
END
POPUP "&Help"
BEGIN
MENUITEM "&About ...", IDM_ABOUT
END
POPUP "Dialog Help"
BEGIN
MENUITEM "Introduction(Dialog)", ID_DIALOGHELP_INTRODUCTION
END
END
可以看到,在下拉菜单项Introduction(Dialog)边上的字符串:ID_DIALOGHELP_INTRODUCTION,这是用户点击该菜单项时,所发出的WM_COMMAND消息的WPARAM参数,可以用来判断是哪个下拉菜单项被打开了。
2. 打开Resource Editor,新创建一个Dialog模板, 将其ID 改为IDD_Introduction,并其中保持只有一个OK按钮和一个Text label。这时,在rc文件中会新生成一个Dialog的定义:
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
DEFPUSHBUTTON "OK",IDOK,259,162,50,14
CTEXT "HelloDialogBox, Version 1.0, Created by Jackie",IDC_STATIC,77,80,160,22,SS_NOPREFIX
END
注意我们改后的Dialog ID,在我们创建这个Dialog时,需要使用这个ID。
3. 在主程序中加入该Dialog的消息处理函数。
INT_PTR CALLBACK Introduction(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
UNREFERENCED_PARAMETER(lParam);
switch (message)
{
case WM_INITDIALOG:
return (INT_PTR)TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return (INT_PTR)TRUE;
}
break;
}
return (INT_PTR)FALSE;
}
这个消息处理函数只处理了两个Command消息。
4. 为Menu的下拉项添加响应行为:
{
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// Parse the menu selections:
switch (wmId)
{
case ID_DIALOGHELP_INTRODUCTION:
DialogBox(hInst, MAKEINTRESOURCE(IDD_Introduction), hWnd, Introduction);
break;
注意, 这里我们使用了case ID_DIALOGHELP_INTRODUCTION来识别哪个项目被点击了,然后使用DialogBox(hInst, MAKEINTRESOURCE(IDD_Introduction), hWnd, Introduction);来创建了一个Dialog。
5. 编译运行吧。
创建Modeless Dialog Box
可以使用CreateDialog 创建一个Modeless Dialog Box。specifying the identifier or name of a dialog box template resource and a pointer to the dialog box procedure。下面是创建Modeless Dialog Box的具体步骤:
1. 与Modal Dialog 的一样
2. 与Modal Dialog 的一样
3. Modeless Dialog Box的窗口处理函数并无特殊之处。但是,主窗口和Dialog都有可能有新的Message,这样在主消息循环中,需要区分是给Dialog的Message,还是给主窗口的Message,代码如下:
代码
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{
if (bRet == -1)
{
// Handle the error and possibly exit
}
else if (!IsWindow(hwndGoto) || !IsDialogMessage(hwndGoto, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
4. Menu的下拉项响应行为会有所不同。由于该类型的Dialog被打开时,应用程序的其他Window依然可以被激活,那么就有可能再次打开同一个类型的Dialog,因此为了避免产生多个同类型的Dialog,程序需要判断是否有多个Dialog被打开。
...
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDM_GOTO:
if (!IsWindow(hwndGoto))
{
hwndGoto = CreateDialog(hinst,
MAKEINTRESOURCE(DLG_GOTO),
hwnd,
(DLGPROC)GoToProc);
ShowWindow(hwndGoto, SW_SHOW);
}
break;
}
return 0L;
5. 编译运行。
Dialog Box的初始化
在dialog 的窗口处理函数中,一般都要处理WM_INITDIALOG消息。当收到这个消息时,可以初始化Dialog中一些控件的初始值、焦点的位置等。
在内存中创建模板
参考资料:http://msdn.microsoft.com/en-us/library/ms644996(VS.85).aspx