一、对话框基本概念
1.对话框的分类
1)模式对话框:当对话框显示时,会禁止进程内的其它窗口与用户交互。如字体对话框。
2)非模式对话框:当对话框显示时,不会禁止进程内的其它窗口与用户交互。如查找对话框。
2.对话框的基本使用
1)对话框窗口过程函数
BOOL CALLBACK DialogProc (
HWND hDlg, // 对话框窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 消息参数
LPARAM lParam
);
返回TRUE:自定义窗口过程函数已处理此消息,缺省窗口过程函数不再处理此消息。
返回FALSE: 自定义窗口过程函数未处理此消息,缺省窗口过程函数负责处理此消息。
普通窗口:
LRESULT CALLBACK MyWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_PAINT:
...
return 0;
...
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
MyWndProc - 自定义窗口过程函数
DefWindowProc - 缺省窗口过程函数
自定义调缺省。
对话框窗口:
LRESULT CALLBACK DefDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (pfuncDlgProc (hDlg, uMsg, wParam, lParam))
return 0;
switch (uMsg) {
...
}
...
}
DefDlgProc - 缺省对话框窗口过程函数,系统中已经有缺省对话框窗口过程函数。它调用我们自己写的自定义对话框窗口过程函数。
pfuncDlgProc - 指向自定义对话框窗口过程函数
缺省调自定义。
所有的对话框都是一个类,都是由系统预定义好的,不需要自己定义,里面的窗口处理函数是DefDlgProc。所以需要一个函数指针来调用你的窗口过程函数。
2)注册窗口类由系统自动完成
3)添加对话框资源,定义对话框模板,根据该模板创建窗口
4)创建对话框
5)关闭对话框
二、模式对话框
1.创建
int DialogBox (
HINSTANCE hInstance, // 应用程序实例句柄,资源跟着实例走
LPCTSTR lpTemplate, // 对话框模板资源名
HWND hWndParent, // 父窗口句柄
DLGPROC lpDialogFunc // 对话框窗口过程函数
);
成功返回EndDialog函数的nResult参数,失败返回-1。
阻塞函数,直到对话框被关闭才会返回。
2.销毁
BOOL EndDialog (
HWND hDlg, // 对话框句柄
int nResult // DialogBox的返回值
);
成功返回TRUE, 失败返回FALSE。
模式对话框会用自己的消息循环挂起主消息循环,只能用EndDialog函数销毁模式对话框,DestroyWindow函数虽然也可以销毁窗口,但它不能恢复消息循环。
3.消息
对话框创建之后不会收到WM_CREATE消息,代之以WM_INITDIALOG消息。
代码实现哈:
1.添加一个菜单项用以表示模式对话框和非模式对话框。
2.添加一个对话框资源。ctrl+d可以有来改变对话框上控件的顺序。
3.先定义一个对话框窗口处理函数
BOOL CALLBACK ModalDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
switch(uMsg){
case WM_CLOSE:
EndDialog(hDlg,0);
return TRUE;
}
如果想处理控件可以到wParam的低16位表示控件Id。
case WM_COMMAND:
switch(LOWORD(wParam){
case IDOK:
EndDialog(hDlg,1);
return TRUE;
case IDCANCLEL:
EndDialog(hDlg,0);
return TRUE;
0和1为DialogBox 的返回值,用以区分。
}
return FALSE;
在主窗口的类当中把菜单挂上。
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDM_DLG_MODAL:
int nResult=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG),hWnd,ModalDlgProc);
if(nResult==1)
MessageBox(hWnd,"ok","dfdafe",MB_OK);
}
else if(nResult==0)
MessageBox(hWnd,"cancel","dafd",MB_OK);
无模式对话框
1.创建
HWND CreateDialog (
HINSTANCE hInstance, // 应用程序实例句柄
LPCTSTR lpTemplate, // 对话框模板资源名
HWND hWndParent, // 父窗口句柄
DLGPROC lpDialogProc // 对话框窗口过程函数
);
成功返回对话框窗口句柄,失败返回NULL。
非阻塞函数,创建成功即返回对话框句柄,需要调用ShowWindow函数显示该对话框。
2.销毁
BOOL DestroyWindow (
HWND hWnd // 窗口句柄
);
成功返回TRUE,失败返回FALSE。
无模式对话框
没有自己的消息循环,只是一个普通的子窗口,最好不要用EndDialog函数销毁。
3.消息
对话框创建之后不会收到WM_CREATE消息,代之以WM_INITDIALOG消息。
四、对比总结
普通窗口:
窗口过程函数:WindowProc调用DefWndProc
创建:CreateWindow/CreateWindowEx
销毁:DestroyWindow
消息:WM_CREATE
模式对话框:
窗口过程函数:DefDlgProc调用DialogProc
创建:DialogBox
销毁:EndDialog
消息:WM_INITDIALOG
无模式对话框:
窗口过程函数:DefDlgProc调用DialogProc
创建:CreateDialog
销毁:DestroyWindow
消息:WM_INITDIALOG
五、控件基本概念
1.系统预定义的窗口类:如按钮、编辑框。
2.通常情况下控件预定义的窗口过程函数可以处理绝大多数消息,只有在比较特殊的情况下,可以通过子类化定制其窗口过程函数。
3.控件子窗口可以通过唯一的ID标识。
4.程序与控件通过消息交换数据。
1)窗口消息:程序通过SendMessage函数发送给控件的消息。如设置/获取控件的文本、激活/禁用控件。
2)通知消息:当控件中有事件发生,控件会向其父窗口发送特定的通知消息,父窗口可以在其窗口过程函数中处理此通知消息。
六、静态框
1.显示文字、图标、位图等。
2.窗口类:STATIC
3.风格:
SS_ICON - 图标
SS_BITMAP - 位图
SS_BLACKFRAME - 黑框
SS_BLACKRECT - 黑块
SS_GRAYFRAME - 灰框
SS_GRAYRECT - 灰块
SS_LEFT - 靠左
SS_CENTER - 居中
SS_RIGHT - 靠右
SS_NOTIFY - 可发通知
SS_NOPREFIX - 不对&做转义
4.创建
CreateWindow/CreateWindowEx
CreateWindow ("STATIC", "标题", ...);
假设图标/位图的ID是101:
CreateWindow ("STATIC", "#101", ...);
控件ID通过CreateWindow/CreateWindowEx函数的hMenu参数设置。
程序中代码使用:
wcex.hbrBackground=GetSysColorBrush(COLOR_3DFACE);
#define IDC_STATIC_TEXT 4001
#define IDC_STATIC_ICON 4002
void OnCreate(){
int x=4,y=4;
CreateWindowEx(0,"STATIC","Text",WS_CHILD|WS_VISIBLE|SS_NOTIFY,x,y,32,32,hWnd,(hMENU)IDC_STATIC_TEXT,g_hInstance,NULL);
//图标
char szResID[128];
sprintf(szRestID,"#%u",IDI_RED);
CreateWindowEx(0,"STATIC",szRestID,WS_CHILD|WS_VISIBlE|SS_ICON|SS_NOTifY,x,y+=36,0,0,hWnd,(HMENU)IDC_STATIC_ICON,g_hInstance,NULL);
}
位图的加载类似
5.窗口消息
STM_SETICON - 设置图标
wParam - 图标句柄
lParam - 0
STM_GETICON - 获取图标,通过SendMessage返回图标句柄
wParam - 0
lParam - 0
STM_SETIMAGE - 设置图像
wParam - 图像类型(IMAGE_ICON/IMAGE_BITMAP/IMAGE_CURSOR)
lParam - 图像句柄
STM_GETIMAGE - 获取图像,通过SendMessage返回图像句柄
wParam - 图像类型
lParam - 0
#define IDT_ICON 101
static HICON hIcons[2]={NULL};
static DWORD dwCounter=0;
hIcons[0]=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_RED));
hIcons[1]=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_GREEN));
SetTimer(hWnd,IDT_ICON,500,NULL);
case WM_TIMER:
if(wParam==IDT_ICON){
SendMessage(GetDlgItem(hWnd,IDC_STATIC_ICON),STM_SETICON,(WPARAM)hIcons[++dwCounter%2],0);
}
break;
6.通知消息
1)需要创建时应用SS_NOTIFY风格。
2)随WM_COMMAND消息发送的通知
wParam - LOWORD:菜单、加速键、控件的ID
HIWORD:0(菜单)、1(加速键)、通知码(控件)
lParam - NULL(菜单、加速键)、句柄(控件)
通知码:
STN_CLICKED - 单击
STN_DBLCLK - 双击
STN_DISABLE - 禁用
STN_ENABLE - 激活
static HBITMAP hBmps[2]={NULL};
static BOOL bMM=TRUE;
hBmps[0]=LoadBitmap(g_hInstance,MAKEINTRESOURCE(IDB_MM));
hBmps[1]=LoadBitmap(g_hInstance,MAKEINTRESOURCE(IDB_GG));
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDC_STATIC_BMP:
switch(HIWORD(wParam)){
//换图
SendMessage(GetDlgItem(hWnd,IDC_STATIC(BMP),STM_SETIMAGE,IMAGE_BITMAP,
case STN_CLICKED:
return 0;
}
}
点击关闭按钮->WM_SYSCOMMAND(wParam==SC_CLOSE)->DefWindowProc->CloseWindow->WM_CLOSE->DefWindowProc->DestroyWindow->销毁窗口,然后发送WM_DESTROY->发送WM_QUIT->GetMessage返回FALSE->结束消息循环->进程结束
七、按钮
1.风格
1)下压按钮:BS_PUSHBUTTON、BS_DEFPUSHBUTTON
2)分组框:BS_GROUPBOX
3)复选框:
A.两态复选框:BS_CHECKBOX(通过代码设置状态)、BS_AUTOCHECKBOX(自动设置状态)
B.三态复选框:BS_3STATE(通过代码设置状态)、BS_AUTO3STATE(自动设置状态)
4)单选框:BS_RADIOBUTTON(通过代码设置状态)、BS_AUTORADIOBUTTON(自动设置状态)
2.窗口类:BUTTON
3.通知消息:BN_CLICKED - 单击
4.窗口消息:
BM_SETCHECK - 设置选择状态
wParam - BST_CHECKED(选)/BST_UNCHECKED(无)/BST_INDETERMINATE(灰)
lParam - 0
BM_GETCHECK - 获取选择状态,通过SendMessage返回
wParam - 0
lParam - 0
对于单选按钮使用WS_GROUP风格,可以实现单选按钮的组内互斥,组间独立。从一个具有WS_GROUP风格的按钮到下一个具有WS_GROUP风格的按钮之前为一组。
八、编辑框
1.分类
1)单行编辑框:只能编辑一行文字。
2)多行编辑框:可以编辑多行文字。
3)密码编辑框:输入任何字符都显示“*”。
2.类名:EDIT
3.风格
ES_AUTOHSCROLL - 水平方向自动滚动
ES_AUTOVSCROLL - 垂直方向自动滚动
ES_LEFT - 文字靠左
ES_CENTER - 文字居中
ES_RIGHT - 文字靠右
ES_MULTILINE - 多行
ES_NUMBER - 只能输入数字(0-9)
ES_PASSWORD - 密码
ES_READONLY - 只读
1.对话框的分类
1)模式对话框:当对话框显示时,会禁止进程内的其它窗口与用户交互。如字体对话框。
2)非模式对话框:当对话框显示时,不会禁止进程内的其它窗口与用户交互。如查找对话框。
2.对话框的基本使用
1)对话框窗口过程函数
BOOL CALLBACK DialogProc (
HWND hDlg, // 对话框窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 消息参数
LPARAM lParam
);
返回TRUE:自定义窗口过程函数已处理此消息,缺省窗口过程函数不再处理此消息。
返回FALSE: 自定义窗口过程函数未处理此消息,缺省窗口过程函数负责处理此消息。
普通窗口:
LRESULT CALLBACK MyWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
switch (uMsg) {
case WM_PAINT:
...
return 0;
...
}
return DefWindowProc (hWnd, uMsg, wParam, lParam);
}
MyWndProc - 自定义窗口过程函数
DefWindowProc - 缺省窗口过程函数
自定义调缺省。
对话框窗口:
LRESULT CALLBACK DefDlgProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
if (pfuncDlgProc (hDlg, uMsg, wParam, lParam))
return 0;
switch (uMsg) {
...
}
...
}
DefDlgProc - 缺省对话框窗口过程函数,系统中已经有缺省对话框窗口过程函数。它调用我们自己写的自定义对话框窗口过程函数。
pfuncDlgProc - 指向自定义对话框窗口过程函数
缺省调自定义。
所有的对话框都是一个类,都是由系统预定义好的,不需要自己定义,里面的窗口处理函数是DefDlgProc。所以需要一个函数指针来调用你的窗口过程函数。
2)注册窗口类由系统自动完成
3)添加对话框资源,定义对话框模板,根据该模板创建窗口
4)创建对话框
5)关闭对话框
二、模式对话框
1.创建
int DialogBox (
HINSTANCE hInstance, // 应用程序实例句柄,资源跟着实例走
LPCTSTR lpTemplate, // 对话框模板资源名
HWND hWndParent, // 父窗口句柄
DLGPROC lpDialogFunc // 对话框窗口过程函数
);
成功返回EndDialog函数的nResult参数,失败返回-1。
阻塞函数,直到对话框被关闭才会返回。
2.销毁
BOOL EndDialog (
HWND hDlg, // 对话框句柄
int nResult // DialogBox的返回值
);
成功返回TRUE, 失败返回FALSE。
模式对话框会用自己的消息循环挂起主消息循环,只能用EndDialog函数销毁模式对话框,DestroyWindow函数虽然也可以销毁窗口,但它不能恢复消息循环。
3.消息
对话框创建之后不会收到WM_CREATE消息,代之以WM_INITDIALOG消息。
代码实现哈:
1.添加一个菜单项用以表示模式对话框和非模式对话框。
2.添加一个对话框资源。ctrl+d可以有来改变对话框上控件的顺序。
3.先定义一个对话框窗口处理函数
BOOL CALLBACK ModalDlgProc(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam){
switch(uMsg){
case WM_CLOSE:
EndDialog(hDlg,0);
return TRUE;
}
如果想处理控件可以到wParam的低16位表示控件Id。
case WM_COMMAND:
switch(LOWORD(wParam){
case IDOK:
EndDialog(hDlg,1);
return TRUE;
case IDCANCLEL:
EndDialog(hDlg,0);
return TRUE;
0和1为DialogBox 的返回值,用以区分。
}
return FALSE;
在主窗口的类当中把菜单挂上。
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDM_DLG_MODAL:
int nResult=DialogBox(g_hInstance,MAKEINTRESOURCE(IDD_DIALOG),hWnd,ModalDlgProc);
if(nResult==1)
MessageBox(hWnd,"ok","dfdafe",MB_OK);
}
else if(nResult==0)
MessageBox(hWnd,"cancel","dafd",MB_OK);
无模式对话框
1.创建
HWND CreateDialog (
HINSTANCE hInstance, // 应用程序实例句柄
LPCTSTR lpTemplate, // 对话框模板资源名
HWND hWndParent, // 父窗口句柄
DLGPROC lpDialogProc // 对话框窗口过程函数
);
成功返回对话框窗口句柄,失败返回NULL。
非阻塞函数,创建成功即返回对话框句柄,需要调用ShowWindow函数显示该对话框。
2.销毁
BOOL DestroyWindow (
HWND hWnd // 窗口句柄
);
成功返回TRUE,失败返回FALSE。
无模式对话框
没有自己的消息循环,只是一个普通的子窗口,最好不要用EndDialog函数销毁。
3.消息
对话框创建之后不会收到WM_CREATE消息,代之以WM_INITDIALOG消息。
四、对比总结
普通窗口:
窗口过程函数:WindowProc调用DefWndProc
创建:CreateWindow/CreateWindowEx
销毁:DestroyWindow
消息:WM_CREATE
模式对话框:
窗口过程函数:DefDlgProc调用DialogProc
创建:DialogBox
销毁:EndDialog
消息:WM_INITDIALOG
无模式对话框:
窗口过程函数:DefDlgProc调用DialogProc
创建:CreateDialog
销毁:DestroyWindow
消息:WM_INITDIALOG
五、控件基本概念
1.系统预定义的窗口类:如按钮、编辑框。
2.通常情况下控件预定义的窗口过程函数可以处理绝大多数消息,只有在比较特殊的情况下,可以通过子类化定制其窗口过程函数。
3.控件子窗口可以通过唯一的ID标识。
4.程序与控件通过消息交换数据。
1)窗口消息:程序通过SendMessage函数发送给控件的消息。如设置/获取控件的文本、激活/禁用控件。
2)通知消息:当控件中有事件发生,控件会向其父窗口发送特定的通知消息,父窗口可以在其窗口过程函数中处理此通知消息。
六、静态框
1.显示文字、图标、位图等。
2.窗口类:STATIC
3.风格:
SS_ICON - 图标
SS_BITMAP - 位图
SS_BLACKFRAME - 黑框
SS_BLACKRECT - 黑块
SS_GRAYFRAME - 灰框
SS_GRAYRECT - 灰块
SS_LEFT - 靠左
SS_CENTER - 居中
SS_RIGHT - 靠右
SS_NOTIFY - 可发通知
SS_NOPREFIX - 不对&做转义
4.创建
CreateWindow/CreateWindowEx
CreateWindow ("STATIC", "标题", ...);
假设图标/位图的ID是101:
CreateWindow ("STATIC", "#101", ...);
控件ID通过CreateWindow/CreateWindowEx函数的hMenu参数设置。
程序中代码使用:
wcex.hbrBackground=GetSysColorBrush(COLOR_3DFACE);
#define IDC_STATIC_TEXT 4001
#define IDC_STATIC_ICON 4002
void OnCreate(){
int x=4,y=4;
CreateWindowEx(0,"STATIC","Text",WS_CHILD|WS_VISIBLE|SS_NOTIFY,x,y,32,32,hWnd,(hMENU)IDC_STATIC_TEXT,g_hInstance,NULL);
//图标
char szResID[128];
sprintf(szRestID,"#%u",IDI_RED);
CreateWindowEx(0,"STATIC",szRestID,WS_CHILD|WS_VISIBlE|SS_ICON|SS_NOTifY,x,y+=36,0,0,hWnd,(HMENU)IDC_STATIC_ICON,g_hInstance,NULL);
}
位图的加载类似
5.窗口消息
STM_SETICON - 设置图标
wParam - 图标句柄
lParam - 0
STM_GETICON - 获取图标,通过SendMessage返回图标句柄
wParam - 0
lParam - 0
STM_SETIMAGE - 设置图像
wParam - 图像类型(IMAGE_ICON/IMAGE_BITMAP/IMAGE_CURSOR)
lParam - 图像句柄
STM_GETIMAGE - 获取图像,通过SendMessage返回图像句柄
wParam - 图像类型
lParam - 0
#define IDT_ICON 101
static HICON hIcons[2]={NULL};
static DWORD dwCounter=0;
hIcons[0]=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_RED));
hIcons[1]=LoadIcon(g_hInstance,MAKEINTRESOURCE(IDI_GREEN));
SetTimer(hWnd,IDT_ICON,500,NULL);
case WM_TIMER:
if(wParam==IDT_ICON){
SendMessage(GetDlgItem(hWnd,IDC_STATIC_ICON),STM_SETICON,(WPARAM)hIcons[++dwCounter%2],0);
}
break;
6.通知消息
1)需要创建时应用SS_NOTIFY风格。
2)随WM_COMMAND消息发送的通知
wParam - LOWORD:菜单、加速键、控件的ID
HIWORD:0(菜单)、1(加速键)、通知码(控件)
lParam - NULL(菜单、加速键)、句柄(控件)
通知码:
STN_CLICKED - 单击
STN_DBLCLK - 双击
STN_DISABLE - 禁用
STN_ENABLE - 激活
static HBITMAP hBmps[2]={NULL};
static BOOL bMM=TRUE;
hBmps[0]=LoadBitmap(g_hInstance,MAKEINTRESOURCE(IDB_MM));
hBmps[1]=LoadBitmap(g_hInstance,MAKEINTRESOURCE(IDB_GG));
case WM_COMMAND:
switch(LOWORD(wParam)){
case IDC_STATIC_BMP:
switch(HIWORD(wParam)){
//换图
SendMessage(GetDlgItem(hWnd,IDC_STATIC(BMP),STM_SETIMAGE,IMAGE_BITMAP,
case STN_CLICKED:
return 0;
}
}
点击关闭按钮->WM_SYSCOMMAND(wParam==SC_CLOSE)->DefWindowProc->CloseWindow->WM_CLOSE->DefWindowProc->DestroyWindow->销毁窗口,然后发送WM_DESTROY->发送WM_QUIT->GetMessage返回FALSE->结束消息循环->进程结束
七、按钮
1.风格
1)下压按钮:BS_PUSHBUTTON、BS_DEFPUSHBUTTON
2)分组框:BS_GROUPBOX
3)复选框:
A.两态复选框:BS_CHECKBOX(通过代码设置状态)、BS_AUTOCHECKBOX(自动设置状态)
B.三态复选框:BS_3STATE(通过代码设置状态)、BS_AUTO3STATE(自动设置状态)
4)单选框:BS_RADIOBUTTON(通过代码设置状态)、BS_AUTORADIOBUTTON(自动设置状态)
2.窗口类:BUTTON
3.通知消息:BN_CLICKED - 单击
4.窗口消息:
BM_SETCHECK - 设置选择状态
wParam - BST_CHECKED(选)/BST_UNCHECKED(无)/BST_INDETERMINATE(灰)
lParam - 0
BM_GETCHECK - 获取选择状态,通过SendMessage返回
wParam - 0
lParam - 0
对于单选按钮使用WS_GROUP风格,可以实现单选按钮的组内互斥,组间独立。从一个具有WS_GROUP风格的按钮到下一个具有WS_GROUP风格的按钮之前为一组。
八、编辑框
1.分类
1)单行编辑框:只能编辑一行文字。
2)多行编辑框:可以编辑多行文字。
3)密码编辑框:输入任何字符都显示“*”。
2.类名:EDIT
3.风格
ES_AUTOHSCROLL - 水平方向自动滚动
ES_AUTOVSCROLL - 垂直方向自动滚动
ES_LEFT - 文字靠左
ES_CENTER - 文字居中
ES_RIGHT - 文字靠右
ES_MULTILINE - 多行
ES_NUMBER - 只能输入数字(0-9)
ES_PASSWORD - 密码
ES_READONLY - 只读