对话框的创建
对话框分为模态对话框和非模态对话框两种形式
模态对话框:自建消息循环,并且通过EnableWindow禁用了父窗口的键盘鼠标输入达到阻塞父窗口的功能。当有对话框,父窗口阻塞时,透过对话框是无法对父窗口进行操作的,这也就是父窗口堵塞的结果
非模态对话框:与父窗口共用消息循环,没有父窗口堵塞,其余和模态对话框一致
在应用前,我们手动在Windows桌面程序创建的窗口的顶层菜单上做出如下修改
并将模态对话框ID修改为ID_DLG1,非模态对话框ID修改为ID_DLG2
同样的,对话框我们也可以在资源文件中手动创建一个模态对话框并修改ID为IDD_DIALOG_ONE,一个非模态对话框并修改ID为IDD_DIALOG_TWO
现在我们对这模态对话框进行一个应用。该应用在case WM_COMMAND消息中处理
case WM_COMMAND:
{
switch (LOWORD(wParam)) //判断菜单的选择
{
case ID_DLG1: //选择模态对话框
{
//开始创建模态对话框
//GetWindowLongPtr(hWnd,GWLP_HINSTANCE) 该函数只能作为子窗口获取模块句柄的方式,因为参数中有父窗口句柄,而父窗口本身是没有父窗口的
//GetModuleHandle(NULL)常用于作为父窗口获取模块句柄的方式,也可获取子窗口句柄。填NULL获取主模块句柄
//MODULE实际上就是HINSTANCE的封装,本质上就是模块基址
// MAKEINTRESOURCE()将对话框ID转换为指向对话框的指针
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG_ONE), hWnd, Dialog1WndProc);//创建模态对话框并可直接显示。注意参数四是该对话框的窗口过程,需要我们自行创建,和正常的窗口过程没有区别
break;
}
case ID_DLG2://选择非模态对话框
{
HWND hDlg2 = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG_TWO), hWnd, Dialog2WndProc);//每个对话框都需要再创建一个窗口过程函数。创建好对话框以后不会直接显示
ShowWindow(hDlg2, SW_SHOW);//显示非模态对话框
break;
}
default:
break;
}
}
INT_PTR CALLBACK Dialog1WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) //自行创建的对话框的窗口过程函数,注意返回值
{
switch (message)
{
case WM_INITDIALOG:
{
return (INT_PTR)TRUE;
}
case WM_CLOSE:
{
EndDialog(hWnd, 0);
break;
}
default:
break;
}
return 0;
}
INT_PTR CALLBACK Dialog2WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)//非模态对话框的窗口过程函数
{
switch (message)
{
case WM_INITDIALOG:
{
return (INT_PTR)TRUE;
}
case WM_CLOSE:
{
EndDialog(hWnd, 0);
break;
}
default:
break;
}
return 0;
}
完成以上过程以后,我们运行程序点击模态对话框,就会出现一个对话框了。点击非模态对话框时,也是如下相同的对话框
对话框的优点
对话框最好的优点便是我们在手动设置对话框时,可以直接在工具箱中拖动在对话框添加相关的东西。注意将对话框的属性view改为report
下图便是我们实践的结果
此时该模态对话框便有了如上图的控件,每个控件都有自己的ID,我们只需要对其进行应用而不用再次创建。
对话框设置
该对话框是通过点击父窗口菜单模态对话框选项实现的,现在我们使它通过运行程序后直接就是父窗口:
我们直接做出如下修改即可:
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
hInst = hInstance; // 将实例句柄存储在全局变量中
/* HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
750, 400, 500, 800, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
*/
DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DIALOG_ONE), NULL, Dialog1WndProc);
return TRUE;
}
对话框应用
INT_PTR CALLBACK Dialog1WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) //自行创建的对话框的窗口过程函数,注意返回值
{
switch (message)
{
case WM_CREATE:
{
break;
}
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case ID_MSG:
{
MessageBox(NULL, L"Msg", L"Msg", MB_OK);
break;
}
default:
break;
}
break;
}
case WM_INITDIALOG: //对控件的应用在此消息中
{
HWND hTreeWnd = GetDlgItem(hWnd, IDC_TREE1);// IDC_TREE1就是对话框中树控件的ID
HTREEITEM hRoot1 = CreateTreeNode(hTreeWnd, TVI_ROOT, L"RootNode1");
HTREEITEM h1SubNode1 = CreateTreeNode(hTreeWnd, hRoot1, L"hSubNode1");
CreateTreeNode(hTreeWnd, h1SubNode1, L"hSubNode1Sub1");
CreateTreeNode(hTreeWnd, h1SubNode1, L"hSubNode1Sub2");
HTREEITEM h1SubNode2 = CreateTreeNode(hTreeWnd, hRoot1, L"hSubNode2");
HTREEITEM hRoot2 = CreateTreeNode(hTreeWnd, TVI_ROOT, L"RootNode2");
HTREEITEM h2SubNode1 = CreateTreeNode(hTreeWnd, hRoot2, L"hSubNode1");
HTREEITEM h2SubNode2 = CreateTreeNode(hTreeWnd, hRoot2, L"hSubNode2");
HTREEITEM hRoot3 = CreateTreeNode(hTreeWnd, TVI_ROOT, L"RootNode3");
HTREEITEM h3SubNode1 = CreateTreeNode(hTreeWnd, hRoot3, L"hSubNode1");
HTREEITEM h3SubNode2 = CreateTreeNode(hTreeWnd, hRoot3, L"hSubNode2");
break;
return (INT_PTR)TRUE;
}
case WM_CLOSE:
{
EndDialog(hWnd, 0);
break;
}
default:
break;
}
return 0;
}
作业
封装自己的界面库