对话框管理器——Windows内置的对话框代码
①负责创建对话框窗口及其上面的子窗口控件;在创建对话框函数的内部,Windows使用用户自定义的对话框模板,并且使用Windows内部定义的窗口类(一般类名是“#32770”)来创建对话框。
②提供内置的窗口过程来处理对话框消息(包括所有鼠标和键盘输入)
③内置的窗口过程会将消息传递给我们自定义的“对话框过程”(也叫“对话过程”)。
④对话框中,Windows负责处理在多个控件中转移输入焦点的相关逻辑。
11.1 模态对话框
11.1.1 对话框及其模板
(1)对话框的坐标单位——基于对话框所用的字体的大小(本例为“"MS Shell Dlg"”)
X轴:以字符的平均宽度的1/4为单位。如x=32表示8个字符宽度处
Y轴:以字符的平均高度的1/8为单位。如y=32表示4个字符高度处。
★一般字体的字符高度是宽度的两倍,所以X轴与Y轴的尺寸基本相同
★可通过MapDialogRect函数将字符为单位的坐标转换为对话框客户区的像素坐标。
(2)对话框模板
①STYLE语句与CreateWindow中的样式相似,模态对话框用WS_POPUP|DS_MODALFRAME
样式 |
功能 |
备注 |
WM_POPUP |
弹出式窗口 |
模态对话框用WS_POPUP|DS_MODALFRAME |
DS_MODALFRAME |
去边框 |
|
WM_CAPTION |
标题栏,允许移动对话框 |
CAPTION “DialogBox Caption” SetWindowText(hDlg,TEXT(“对话框”)); |
WS_SYSMENU |
添加系统菜单 |
允许Move或Close对话框 |
WS_THICKFRAME |
允许改变对话框大小 |
等价于对话框Border属性中选择Resizing |
②MNEU 菜单名 ——允许为对话框添加菜单
③FONT 字号,字体名称 ——发布程序要一起打包
④CLASS “类名”
A、没指定窗口类名时——Windows会自动提供一个特殊的窗口类,该窗口类的内置过程会调用我们定义的对话框过程(由DialogBox最后一个参数提供)
B、指定窗口类名时——可以使用自己的窗口类及窗口过程来处理对话框消息,窗口类的cbWndExtra必须设定为DLGWINDOWEXTRA。
⑤定义子窗口控件格式
控件类型 “文本”,ID,xPos,yPos,xWidth,yHeight,iStyle
CONTROL “文本”,ID,“类”,iStyle,xPos,yPos,xWidth,yHeight //通用格式
A、控件类型
控件类型 |
窗口类 |
窗口样式 |
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_NOTIFY|WS_BORDER |
COMBOBOX |
combobox |
CBS_SIMPLE|WS_TABSTOP |
★子控件除以上样式外,还有WS_CHILD|WS_VISIBLE样式
★除EDITTEXT、SCROLLBAR、LISTBOX、COMBOBOX没“文本”,其他都有。
控件类型 ID,xPos,yPos,xWidth,yHeight,iStyle//注意,没“文本”这项。
B、文本字段中的符号加“&”会添加一个键盘接口,如“&Red”,按R时,焦点会转过来。
C、应用举例
功能需求 |
相应的模板语句 |
复选框,文本左侧 |
CHECKBOX “TEXT”,ID,xPos,yPos,xWidth,yHeight,BS_LEFTTEXT |
没边框的编辑框 |
EDITTEXT,ID,xPos,yPos,xWidth,yHeight,NOT WS_BORDER |
按钮及等价代码 |
PUSHBUTTON “OK”,IDOK,10,20,32,14 CONTROL “OK”,IDOK,“button”,WS_CHILD|WS_VISIBLE| BS_PUSHBUTTON|WS_TABSTOP,10,20,32,14 |
D、模板语句及等价调用(以上面创建按钮的模板语句为例)
hCtrl =CreateWindow(TEXT(“button”,TEXT(“OK”),
WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON|WS_TABSTOP|BS_PUSHBUTTON,10*cxChar/4 ,20*cyChar /8,32*cxChar/4, 14*cyChar/8,
hDlg,IDOK,hInstance,NULL);
⑥WS_TABSTOP——可以通过TAB键获得输入焦点,按TAB键,焦点只会在有WS_TABSTOP的控件间转移。
⑦WS_GROUP——定义一组控件
A、从第一个含有WS_GROUP样式开始,到下一个含有该样式的控件之间的为一组
B、组内控件可以通过方向键循环转移焦点。
C、同组中随着光标移动键,不但会转移焦点,还会赋于新的焦点控件WS_TABSTOP样式,这样下次再按Tab时会定位到该控件上。
⑧不向父窗口发送消息的子控件(如文本和图标),ID设为IDC_STATIC(-1)。
⑨IDOK、IDCANCEL在WINUSER.H中分别被定义为1、2
11.1.2 对话框过程
(1)子窗口向父窗口发送WM_COMMAND过程:子窗口→父窗口(对话框)内置的窗口过程→自定义的对话框过程
(2)对话框过程
BOOL CALLBACK AboutDlgProc(HWND hDlg,UINT msg,WPARAM wParam,lPARAMlParam)
{
switch(message)
{
case WM_INITDIALOG:
return TRUE; //表示消息处理过了,不让对话框内置的窗口过程处理了。
case WM_COMMAND:
switch(LOWORD(wParam)) //子控件ID
{
case IDOK:
case IDCANCEL:
EndDialog(hDlg,0); //结束模态对话框,0会返回给创建模态对话框的那个函数,如作为DialobBox函数的返回值。
return TRUE; //该消息处理好了,不让内置的窗口过程处理了。
}
}
return FALSE; //False表示其余消息不处理,留给内置对话框窗口过程去处理
}
|
对话框过程 |
一般窗口过程 |
返回值 |
BOOL |
LRESULT |
默认处理 |
当返回值为 ①TRUE时表示该消息在对话框过程巳处理,不再传递给内置的对话框处理。 ②FALSE 表示该消息未处理好,得再交给内置的对话框过程。 |
DefWindowProc |
接收的第1条消息 |
①WM_INIDIALOG消息(对话框独有的)进行初始化工作,并把焦点设置为第1个含有WS_TABSTOP的子窗口控件。自定义的对话框过程不会收到WM_CREATE。 ②在该消息中可手动设置焦点(SetFocus),但返回值有点特殊,应设为FALSE。如果为TRUE,Windows会自动将输入焦点设置到第一个有WS_TABSTOP的子控件上。 |
WM_CREATE |
创建 |
DialogBox或DialogBoxIndirectParam——模态 CreateDialog——非模态 |
CreateWindow |
销毁 |
用EndDialog通知Windows销毁(内部会调用WM_DESTROY) |
WM_DESTROY |
WM_COMMAND |
LOWORD(wParam):子控件、菜单、加速键ID HIWORD(wParam):通知码,加速键时为1,菜单为0,其它为子控件的通知码 LParam:子控件句柄 |
![](https://images0.cnblogs.com/blog2015/772759/201508/020823576573868.png)
/*------------------------------------------ ABOUT1.C -- About Box Demo Program No. 1 (c) Charles Petzold, 1998 ------------------------------------------*/ #include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("About1"); MSG msg; HWND hwnd; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, szAppName); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (!RegisterClass(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, TEXT("About Box Demo Program"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HINSTANCE hInstance; switch (message) { case WM_CREATE: hInstance = ((LPCREATESTRUCT)lParam)->hInstance; return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_APP_ABOUT: DialogBox(hInstance, TEXT("AboutBox"), hwnd, AboutDlgProc); break; } return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: case IDCANCEL: EndDialog(hDlg, 0); return TRUE; } break; } return FALSE; }
//resource.h
//resource.h //{{NO_DEPENDENCIES}} // Microsoft Developer Studio generated include file. // Used by About1.rc // #define IDM_APP_ABOUT 40001 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40004 #define _APS_NEXT_CONTROL_VALUE 1003 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
//About1.rc
//Microsoft Developer Studio generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // English (U.S.) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE DISCARDABLE BEGIN "resource.h\0" END 2 TEXTINCLUDE DISCARDABLE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE DISCARDABLE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Dialog // ABOUTBOX DIALOG DISCARDABLE 32, 32, 180, 102 STYLE DS_MODALFRAME | WS_POPUP FONT 8, "MS Sans Serif" BEGIN DEFPUSHBUTTON "OK", IDOK, 66, 81, 50, 14 ICON "ABOUT1", IDC_STATIC, 7, 7, 21, 20 CTEXT "About1", IDC_STATIC, 40, 12, 100, 8 CTEXT "About Box Demo Program", IDC_STATIC, 7, 40, 166, 8 CTEXT "(c) Charles Petzold, 1998", IDC_STATIC, 7, 52, 166, 8 END ///////////////////////////////////////////////////////////////////////////// // // Menu // ABOUT1 MENU DISCARDABLE BEGIN POPUP "&Help" BEGIN MENUITEM "&About About1...", IDM_APP_ABOUT END END ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. ABOUT1 ICON DISCARDABLE "About1.ico" ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN "ABOUTBOX", DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 173 TOPMARGIN, 7 BOTTOMMARGIN, 95 END END #endif // APSTUDIO_INVOKED #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED
11.1.3 更复杂的对话框
【About2程序】
效果图:
/*------------------------------------------------------------ About2.C -- About Box Demo Program No.2 (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); TCHAR szAppName[] = TEXT("About2"); int iCurrentColor = IDC_BLACK, iCurrentFigure = IDC_RECT; int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; MSG msg; WNDCLASSEX wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, szAppName); wndclass.hIconSm = LoadIcon(hInstance, szAppName); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (!RegisterClassEx(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppName, // window class name TEXT("About Box Demo Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } void PaintWindow(HWND hwnd, int iColor, int iFigure) { static COLORREF crColor[8] = { RGB(0, 0, 0), //Black RGB(0, 0, 255), //Blue RGB(0, 255, 0), //Green RGB(0, 255, 255), //Cyan RGB(255, 0, 0), //Red RGB(255, 0, 255), //Meganta RGB(255, 255, 0), //Yellow RGB(255, 255, 255) //White }; HDC hdc; HBRUSH hBrush; RECT rect; hBrush = CreateSolidBrush(crColor[iColor - IDC_BLACK]); hdc = GetDC(hwnd); GetClientRect(hwnd, &rect); hBrush = SelectObject(hdc, hBrush); if (iFigure == IDC_RECT) //矩形按钮ID Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom); else Ellipse(hdc, rect.left, rect.top, rect.right, rect.bottom); DeleteObject(SelectObject(hdc, hBrush)); ReleaseDC(hwnd, hdc); } void PaintTheBlock(HWND hCtrl, int iColor, int iFigure) { InvalidateRect(hCtrl, NULL, TRUE); //这句意思是,在绘制新图像前,先把hCtrl上旧的内容清除掉。
//UpdateWindow的意思是,上述的操作要立即生效。然后再去执行PaintWindow,画出新的内容。
//这个顺序很好理解,因为要绘制新内容前,得先清除旧的内容。
//UpdateWindow很重要,要立即生效,原因如下: /* 1、如果不UpdateWindow的话,经过InvalidateRect,系统会向hCtrl窗口内置的窗口过程发送WM_PAINT消息
但这条消息不会被马上执行。换句话讲,程序执行完InvalidateRect后,会直接执行PaintWindow,此时此
刻新的内容确实在hCtrl上画出来了。
2、但问题来了,当本函数执行完后,因消息队列中,还有一条WM_PAINT消息。所以程序会转去执行这条消息。这
意味着,对于hCtrl来说,那个“清除”操作延迟到现在才执行,所以就会把新的内容给“清除”掉。结果表现出来,
好象这个函数就只擦除以前的以容,然后什么事都没做。 */ UpdateWindow(hCtrl); PaintWindow(hCtrl, iColor, iFigure); } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static HINSTANCE hInst; switch (message) { case WM_CREATE: hInst = ((LPCREATESTRUCT)lParam)->hInstance; return 0; case WM_COMMAND: switch (LOWORD(wParam)) //子控件ID { case IDM_APP_ABOUT: if (DialogBox(hInst, szAppName, hwnd, AboutDlgProc)) InvalidateRect(hwnd, NULL, TRUE); return 0; } break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); PaintWindow(hwnd, iCurrentColor, iCurrentFigure); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static int iColor, iFigure; static HWND hCtrlBlock; switch (message) { case WM_INITDIALOG: iColor = iCurrentColor; iFigure = iCurrentFigure; CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, iColor); CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, iFigure); hCtrlBlock = GetDlgItem(hDlg, IDC_PAINT); SetFocus(GetDlgItem(hDlg, iColor)); return FALSE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: iCurrentColor = iColor; iCurrentFigure = iFigure; EndDialog(hDlg, TRUE); //将TRUE作为DialogBox的返回值,用来决定是否重绘主窗口 return TRUE; case IDCANCEL: EndDialog(hDlg, FALSE); //将FALSE作为DialogBox的返回值 case IDC_BLACK: case IDC_RED: case IDC_GREEN: case IDC_YELLOW: case IDC_BLUE: case IDC_MAGENTA: case IDC_CYAN: case IDC_WHITE: iColor = LOWORD(wParam); CheckRadioButton(hDlg, IDC_BLACK, IDC_WHITE, iColor); PaintTheBlock(hCtrlBlock, iColor, iFigure); return TRUE; case IDC_RECT: case IDC_ELLIPSE: iFigure = LOWORD(wParam); CheckRadioButton(hDlg, IDC_RECT, IDC_ELLIPSE, iFigure); PaintTheBlock(hCtrlBlock, iColor, iFigure); return TRUE; } break; case WM_PAINT: PaintTheBlock(hCtrlBlock, iColor, iFigure); break; //不能直接return TRUE; 要交默认处理,因为无效区要通过BeginPaint有效化。 } return FALSE; }
//resource.h
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ 生成的包含文件。 // 供 About2.rc 使用 // #define IDC_BLACK 1001 #define IDC_BLUE 1002 #define IDC_GREEN 1003 #define IDC_CYAN 1004 #define IDC_RED 1005 #define IDC_MAGENTA 1006 #define IDC_YELLOW 1007 #define IDC_WHITE 1008 #define IDC_RECT 1009 #define IDC_ELLIPSE 1010 #define IDC_PAINT 1011 #define IDM_APP_ABOUT 40001 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40004 #define _APS_NEXT_CONTROL_VALUE 1012 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
//About2.rc
// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "winres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // 中文(简体,中国) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""winres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. ABOUT2 ICON "About2.ico" ///////////////////////////////////////////////////////////////////////////// // // Dialog // ABOUT2 DIALOGEX 32, 32, 200, 234 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN DEFPUSHBUTTON "&Ok", IDOK, 36, 205, 50, 14 PUSHBUTTON "Cancel", IDCANCEL, 99, 204, 50, 14 ICON "ABOUT2", IDC_STATIC, 7, 7, 21, 20 LTEXT "About2", IDC_STATIC, 95, 14, 24, 8 LTEXT "About Box Demo Program", IDC_STATIC, 69, 31, 83, 8 LTEXT "", IDC_PAINT, 102, 55, 77, 79 GROUPBOX "&Color", IDC_STATIC, 17, 49, 73, 141 CONTROL "&Black", IDC_BLACK, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 25, 61, 32, 10 CONTROL "B&lue", IDC_BLUE, "Button", BS_AUTORADIOBUTTON, 25, 77, 29, 10 CONTROL "&Green", IDC_GREEN, "Button", BS_AUTORADIOBUTTON, 25, 93, 35, 10 CONTROL "Cya&n", IDC_CYAN, "Button", BS_AUTORADIOBUTTON, 25, 109, 33, 10 CONTROL "&Red", IDC_RED, "Button", BS_AUTORADIOBUTTON, 25, 125, 29, 10 CONTROL "&Megenta", IDC_MAGENTA, "Button", BS_AUTORADIOBUTTON, 25, 141, 44, 10 CONTROL "&Yellow", IDC_YELLOW, "Button", BS_AUTORADIOBUTTON, 25, 157, 36, 10 CONTROL "&White", IDC_WHITE, "Button", BS_AUTORADIOBUTTON, 26, 173, 35, 10 GROUPBOX "&Figure", IDC_STATIC, 100, 146, 82, 43 CONTROL "Rec&tangle", IDC_RECT, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 112, 158, 48, 10 CONTROL "&Ellipse", IDC_ELLIPSE, "Button", BS_AUTORADIOBUTTON, 112, 175, 35, 10 END ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN "ABOUT2", DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 192 TOPMARGIN, 7 BOTTOMMARGIN, 228 END END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Menu // ABOUT2 MENU BEGIN POPUP "&Help" BEGIN MENUITEM "&About", IDM_APP_ABOUT END END #endif // 中文(简体,中国) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED
① 对比三种设置控件状态函数
|
将一组单选按钮的第3个设为Checked状态 |
第1种 |
for (i=idFirst,i<=idLast,i++) { SendMessage(GetDlgItem(hDlg,i),BM_SETCHECK,i==3,0); } |
第2种 |
for (i=idFirst,i<=idLast,i++) { SendDlgItemMessage(hDlg,i,BM_SETCHECK,i==3,0); } |
第3种 |
CheckRadioButton(hDlg,idFirst,idLast,3); |
②设置和获到复选框的状态
CheckDlgButton(hDlg,idCheckBox,iCheck);
iCheck = IsDlgButtonChecked(hDlg,idCheckBox);
(2)避免全局变量——iCurrentColor和iCurrentFigure是全局变量,应尽量避免!
①先定义结构体
typedef struct
{
int iColor,iFigure;
}ABOUTBOX_DATA;
②WndProc的改动
A、声明部分:Static ABOUTBOX_DATA ad = {IDC_BLACK,IDC_RECT};
B、创建对话框: DialogBoxParam(hInst,TEXT(“AboutBox”),hwnd,AboutDlgProc,&ad);
③对话框过程的变动
A、声明部分:static ABOUTBOX_DATA ad, *pad;
B、WM_INITDIALOG: pad = (ABOUT_DATA*)lParam;//从lParam取出传进来的ad
ad =*pad;
(3)禁用或启用子控件:EnableWindow(hwndCtrl,bEnable);
11.1.4 定义自己的控件
(1)定义自己的子控件,并运用于对话框,并用自己定义的子窗口过程来处理子窗口消息。
(2)自定义子控件:在CONTROL语句中,指定自己的窗口类。
/*------------------------------------------------------------ About3.C -- About Box Demo Program No.3 (c) Charles Petzold, 1998 ------------------------------------------------------------*/ #include <windows.h> #include "resource.h" LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK EllipsePushWndProc(HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK AboutDlgProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("About3"); HWND hwnd; MSG msg; WNDCLASSEX wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.lpfnWndProc = EllipsePushWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = NULL; wndclass.hIconSm = NULL; wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = TEXT("EllipsePush"); if (!RegisterClassEx(&wndclass)) { MessageBox(NULL, TEXT("This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0; } wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.cbSize = sizeof(WNDCLASSEX); wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(hInstance, szAppName); wndclass.hIconSm = LoadIcon(hInstance, szAppName); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; RegisterClassEx(&wndclass); hwnd = CreateWindow(szAppName, // window class name TEXT("About Box Demo Program"), // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters ShowWindow(hwnd, iCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; static HINSTANCE hInst; switch (message) { case WM_CREATE: hInst = ((LPCREATESTRUCT)lParam)->hInstance; return 0; case WM_COMMAND: switch (LOWORD(wParam)) { case IDM_APP_ABOUT: DialogBox(hInst, TEXT("About3"), hwnd, AboutDlgProc); return 0; } break; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } BOOL CALLBACK AboutDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: EndDialog(hDlg, 0); return TRUE; } break; } return FALSE; } //子窗口(按钮)过程 LRESULT CALLBACK EllipsePushWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { TCHAR szText[40]; HBRUSH hBrush; HDC hdc; PAINTSTRUCT ps; RECT rc; switch (message) { case WM_PAINT: GetClientRect(hwnd, &rc); GetWindowText(hwnd, szText, sizeof(szText)); hdc = BeginPaint(hwnd, &ps); hBrush = CreateSolidBrush(GetSysColor(COLOR_WINDOW)); hBrush = SelectObject(hdc, (HGDIOBJ)hBrush); SetBkColor(hdc, GetSysColor(COLOR_WINDOW)); SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT)); Ellipse(hdc, rc.left, rc.top, rc.right, rc.bottom); DrawText(hdc, szText, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER); DeleteObject(hBrush); EndPaint(hwnd, &ps); return 0; case WM_KEYUP: if (wParam != VK_SPACE) break; //继续执行下去,处理空格键 case WM_LBUTTONUP: SendMessage(GetParent(hwnd), WM_COMMAND, GetWindowLong(hwnd, GWL_ID), (LPARAM)hwnd); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
//resource.h
//{{NO_DEPENDENCIES}} // Microsoft Visual C++ 生成的包含文件。 // 供 About3.rc 使用 // #define IDM_APP_ABOUT 40002 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40003 #define _APS_NEXT_CONTROL_VALUE 1002 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif
//About3.rc
// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "winres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // 中文(简体,中国) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource.h\0" END 2 TEXTINCLUDE BEGIN "#include ""winres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Menu // ABOUT3 MENU BEGIN POPUP "&Help" BEGIN MENUITEM "About About3...", IDM_APP_ABOUT END END ///////////////////////////////////////////////////////////////////////////// // // Dialog // ABOUT3 DIALOGEX 0, 0, 167, 150 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN ICON "ABOUT3", IDC_STATIC, 7, 7, 20, 20 LTEXT "About3", IDC_STATIC, 68, 33, 24, 8 LTEXT "About Box Demo Program", IDC_STATIC, 44, 55, 83, 8 LTEXT "(c) Charles PetZold,1998", IDC_STATIC, 44, 77, 80, 8 CONTROL "OK", IDOK, "EllipsePush", WS_TABSTOP, 54, 113, 50, 14 //这里EllipsePush为自定义的 窗口类,很重要! END ///////////////////////////////////////////////////////////////////////////// // // Icon // // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. ABOUT3 ICON "ICON1.ICO" ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO // #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN "ABOUT3", DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 157 TOPMARGIN, 7 BOTTOMMARGIN, 142 END END #endif // APSTUDIO_INVOKED #endif // 中文(简体,中国) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED