- 一、对话框的分类:
1)模式对话框 - 当对话框显示时,会禁止其他窗口的输入等用户交互操作。
2)非模式对话框 - 在对话框显示后,其他窗口同样可以接收输入等用户交互操作。
- 二、对话框的使用过程:
1)对话框窗口处理函数(参照MSDN - DialogProc)
2)添加窗口资源
3)创建对话框(模式对话框和非模式对话的创建不一样)
4)关闭对话框(模式对话框和非模式对话的删除也不一样)
- 三、对话框窗口处理函数(参照MSDN),模式对话框和非模式对话框,对话框窗口处理函数一样
1)BOOL CALLBACK DialogProc(
HWND hwndDlg, //窗口句柄
UINT uMsg, //消息ID
WPARAM wParam, //消息参数
LPARAM lParam //消息参数
);
返回TRUE - 表示 DialogProc 函数中处理了这个消息,缺省处理函数不需要处理。
返回FALSE - 表示 DialogProc 函数未处理这个消息,交给缺省处理函数处理。
- 四、模式对话框的创建和关闭
1)创建:
int DialogBox(
HINSTANCE hInstance, //应用程序实例句柄
LPCTSTR lpTemplate, //对话框模板资源ID
HWND hWndParent, //对话框父窗口
DLGPROC lpDialogFunc //对话框窗口处理函数
);
DialogBox 是一个阻塞函数,只有当对话框关闭后,才会返回,继续执行后续代码。返回值是通过 EndDialog 设置。
2)关闭:
BOOL EndDialog(
HWND hDlg, //关闭的对话框窗口句柄
int nResult //关闭的返回值
);
关闭模式对话框,只能使用 EndDialog ,不能使用 DestroyWindow 等函数。
nResult 是 DialogBox 函数退出时的返回值。在对话框退出的时候, nResult 作为返回值被 DialogBox 函数接收,可以用来判断点击了对话框中的哪个按钮。
注意: EndDialog 函数可以解除 DialogBox 的阻塞。
- 五、非模式对话框的创建和关闭:
1)创建:
HWND CreateDialog(
HINSTANCE hInstance, //应用程序实例句柄
LPCTSTR lpTemplate, //模板资源ID
HWND hWndParent, //父窗口句柄
DLGPROC lpDialogFunc //窗口处理函数
);
非阻塞函数,创建成功返回窗口句柄,需要使用 ShowWindow 函数显示对话框。
2)关闭:
关闭时使用 DestroyWindow 销毁窗口,不能使用 EndDialog 关闭对话框。
- 六、对话框和窗口的对比:
1.创建
模式对话框 - DialogBox 函数,是一个阻塞函数
非模式对话框 - CreateDialog
普通窗口 - CreateWindow/CreateWindowEx
2.窗口处理函数
对话框 - DialogProc ,被缺省的对话框窗口处理函数调用
普通窗口 - WindowProc ,需要调用缺省的窗口处理函数(DefWindowProc)
3.窗口消息
对话框 - WM_INITDIALOG
普通窗口 - WM_CREATE
4.窗口关闭
模式对话框 - EndDialog
非模式对话框 - DestroyWindow
七、实例代码
/*
说明:实现的功能:1、窗口的基本创建2、手动创建方式取代资源方式添加菜单3、模式对话框和非模式对话的创建和实现(对话框需要添加资源IDD_DLG)
4、为节省代码,模式对话框和非模式对话框共用一个对话框处理函数,因为处理方式不同,已经将模式对话框的菜单功能屏蔽掉
*/
#include <Windows.h>
#include <tchar.h>
#include "resource.h"
#define ID_DIALOG 1000 //非模式对话框
#define ID_MODELDLG 1001 //模式对话框
#define ID_QUIT 1002 //退出
HINSTANCE g_hInstance;
//窗口处理函数
LRESULT CALLBACK WndPro(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam);
//注册窗口类类名
TCHAR szClassName[] = _T("Main");
//窗口名称
TCHAR szWindowName[] = _T("窗口名称");
//对话框处理函数
BOOL CALLBACK MyDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam);
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
g_hInstance = hInstance;
//设计窗口类
WNDCLASSEX wndCls = {0};
wndCls.cbClsExtra = 0;
wndCls.cbSize = sizeof(WNDCLASSEX);
wndCls.cbWndExtra = 0;
wndCls.hbrBackground = (HBRUSH)COLOR_WINDOW;
wndCls.hCursor = NULL;
wndCls.hIcon = NULL;
wndCls.hIconSm = NULL;
wndCls.hInstance = hInstance;
wndCls.lpfnWndProc = WndPro;
wndCls.lpszClassName = szClassName;
wndCls.lpszMenuName = NULL;
wndCls.style = CS_VREDRAW | CS_HREDRAW;
//注册窗口类
if (!RegisterClassEx(&wndCls))
{
MessageBox(NULL,_T("注册窗口类失败!"),_T("提示"),MB_OK);
return 1;
}
//创建窗口
HWND hWnd = CreateWindowEx(0,szClassName,szWindowName,WS_OVERLAPPEDWINDOW,10,10,800,600,NULL,NULL,hInstance,NULL);
if (NULL == hWnd)
{
MessageBox(NULL,_T("创建窗口失败!"),_T("提示"),MB_OK);
return 1;
}
//显示和更新窗口
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
//消息循环
MSG msg;
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
void OnCreate(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
//创建菜单
HMENU hMain = CreateMenu();
HMENU hDialog = CreatePopupMenu();
AppendMenu(hDialog,MF_STRING,ID_MODELDLG,_T("模式对话框"));
AppendMenu(hDialog,MF_STRING,ID_DIALOG,_T("非模式对话框"));
AppendMenu(hDialog,MF_SEPARATOR,0,NULL);
AppendMenu(hDialog,MF_STRING,ID_QUIT,_T("退出"));
AppendMenu(hMain,MF_POPUP,(UINT)hDialog,_T("对话框"));
SetMenu(hWnd,hMain);
}
void OnBtnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
switch(LOWORD(wParam))
{
case IDOK:
/*
//关闭模式对话框
if(!EndDialog(hWnd,2))
{
MessageBox(NULL,_T("关闭对话框失败!"),_T("提示"),MB_OK);
return;
}*/
if(!DestroyWindow(hWnd)) //关闭非模式对话框
{
MessageBox(NULL,_T("关闭非模式对话框失败!"),_T("提示"),MB_OK);
return;
}
break;
case IDCANCEL:
/*
//关闭模式对话框
if(!EndDialog(hWnd,3))
{
MessageBox(NULL,_T("关闭对话框失败!"),_T("提示"),MB_OK);
return;
}*/
if(!DestroyWindow(hWnd)) //关闭非模式对话框
{
MessageBox(NULL,_T("关闭非模式对话框失败!"),_T("提示"),MB_OK);
return;
}
break;
}
}
BOOL CALLBACK MyDialogProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_SYSCOMMAND:
if (SC_CLOSE == wParam)
{
/*
//关闭对话框,模式对话框用EndDialog函数
if(!EndDialog(hwndDlg,1))
{
MessageBox(NULL,_T("关闭对话框失败!"),_T("提示"),MB_OK);
return 1;
}*/
if(!DestroyWindow(hwndDlg))//非模式对话框关闭,调用DestroyWindow函数
{
MessageBox(NULL,_T("关闭非模式对话框失败!"),_T("提示"),MB_OK);
return 1;
}
}
break;
case WM_INITDIALOG:
MessageBox(NULL,_T("对话框创建完成,显示之前调用"),_T("提示"),MB_OK);
break;
case WM_COMMAND: //按钮发送的是WM_COMMAND消息
OnBtnCommand(hwndDlg,wParam,lParam);
}
return FALSE;
}
void OnModelDlg(HWND hWnd)
{
//创建对话框,通过EndDialog的第二个参数作为返回值,判断点击了对话框中的控件
int ret = DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DLG),hWnd,MyDialogProc);
if (1 == ret)
{
MessageBox(NULL,_T("您点击了关闭对话框"),_T("提示"),MB_OK);
}
if (2 == ret)
{
MessageBox(NULL,_T("您点击了确定按钮关闭"),_T("提示"),MB_OK);
}
if (3 == ret)
{
MessageBox(NULL,_T("您点击了取消按钮关闭"),_T("提示"),MB_OK);
}
}
void OnDlg(HWND hWnd)
{
HWND hDialog = CreateDialog(g_hInstance,MAKEINTRESOURCE(IDD_DLG),hWnd,MyDialogProc);
if (NULL == hDialog)
{
MessageBox(NULL,_T("创建非模式对话框失败!"),_T("提示"),MB_OK);
return;
}
ShowWindow(hDialog,SW_SHOW);
}
void OnCommand(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
DWORD id = LOWORD(wParam); //WM_COMMAND消息附加项wParam的低字节表示菜单项的ID,高字节HIWORD为0
switch (id)
{
case ID_MODELDLG:
// OnModelDlg(hWnd); //模式对话框
break;
case ID_DIALOG:
OnDlg(hWnd); //非模式对话框
break;
case ID_QUIT:
if (IDYES == MessageBox(NULL,_T("确定要退出?"),_T("提示"),MB_YESNO))
{
PostQuitMessage(0);
}
break;
}
}
LRESULT CALLBACK WndPro(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch(uMsg)
{
case WM_COMMAND:
OnCommand(hWnd,wParam,lParam);
break;
case WM_CREATE:
OnCreate(hWnd,wParam,lParam);
break;
case WM_SYSCOMMAND:
if (SC_CLOSE == wParam)
{
if (IDYES == MessageBox(NULL,_T("确定要退出?"),_T("提示"),MB_YESNO))
{
PostQuitMessage(0);
}
else
return 1;
}
break;
}
return DefWindowProc(hWnd,uMsg,wParam,lParam);
}