windows C语言编程——模态对话框
2017-01-19 16:03
190 查看
模态对话框,就是当程序显示此对话框时,用户不能在对话框和该程序的其他窗口之间进行切换。来看一个例子:
涉及到的头文件,也就是resource.h的主要代码:
资源文件的主要代码:
运行效果如下:
![](https://static.oschina.net/uploads/space/2017/0119/152607_51GN_147032.png)
程序的作用是,通过弹出的对话框选择颜色,然后再选择椭圆还是矩形,单击确定时将选择的东西在主窗口中显示出相应的效果。这个程序看起来并不复杂,但涉及到的知识还是很多的,所以值得细说一下。
1,关于WS_GROUP和WS_TABSTOP。
2,坐标值的大小。
3,对话框过程及激活对话框。
4,对话框的外边框。
5,关于RGB的创建。
6,关于WS_SYSMENU。
7,CONTROL语句与CreateWindow的关系。
8,关于设备环境句柄(HDC)及PAINTSTRUCT结构。获取HDC有两种方式:
BeginPaint函数的作用是擦去无效区域的背景以便绘图,同时还会填充PAINTSTRUST结构的各个字段,并返回HDC,它与EndPaint必须成对出现。而上面的代码中,如果BeginPaint与EndPaint之间没有任何绘制图形的代码,作用是将无效区域有效化。
GetDC与ReleaseDC有点类似,也必须成对出现,将GetDC返回的设备环境句柄中的裁剪矩形是整个客户区,而BeginPaint可以是部分区域。需要绘制的区域是存放在PAINTSTRUST结构中,该结构定义如下:
第三个字段RECT rcPaint,即存放需要绘制图形的矩形区域,这里面的值可以通过下列函数传过来。
这个函数的第二个字段便是需绘制矩形的值。重要绘制整个客户区可以采用以下方式:
9,绘制填充区域背景。
10,关于DialogBoxParam。
11,关于在主窗口绘制不同的图形。
以上几个方面,对于理解这个程序来说很重要,也涉及到很多Windows API编程的基础知识,值得反复研究。
/*------------------------------------------ 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) ; int iCurrentColor = IDC_BLACK, iCurrentFigure = IDC_RECT ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("About2") ; 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 ; } void PaintWindow (HWND hwnd, int iColor, int iFigure) { static COLORREF crColor[8] = { RGB ( 0, 0, 0), RGB ( 0, 0, 255), RGB ( 0, 255, 0), RGB ( 0, 255, 255), RGB (0xff, 0, 0), RGB (255, 0, 255), RGB (255, 255, 0), RGB (255, 255, 255) } ; HBRUSH hBrush ; HDC hdc ; RECT rect ; hdc = GetDC (hwnd) ; GetClientRect (hwnd, &rect) ; hBrush = CreateSolidBrush (crColor[iColor - IDC_BLACK]) ; hBrush = (HBRUSH) SelectObject (hdc, hBrush) ; if (iFigure == IDC_RECT) 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) ; UpdateWindow (hCtrl) ; PaintWindow (hCtrl, iColor, iFigure) ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HINSTANCE hInstance ; PAINTSTRUCT ps ; switch (message) { case WM_CREATE: hInstance = ((LPCREATESTRUCT) lParam)->hInstance ; return 0 ; case WM_COMMAND: switch (LOWORD (wParam)) { case IDM_APP_ABOUT: if (DialogBox (hInstance, TEXT ("AboutBox"), hwnd, AboutDlgProc)) InvalidateRect (hwnd, NULL, TRUE) ; return 0 ; } break ; case WM_PAINT: 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 HWND hCtrlBlock ; static int iColor, iFigure ; 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) ; return TRUE ; case IDCANCEL: EndDialog (hDlg, FALSE) ; return TRUE ; 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, LOWORD (wParam)) ; PaintTheBlock (hCtrlBlock, iColor, iFigure) ; return TRUE ; case IDC_RECT: case IDC_ELLIPSE: iFigure = LOWORD (wParam) ; CheckRadioButton (hDlg, IDC_RECT, IDC_ELLIPSE, LOWORD (wParam)) ; PaintTheBlock (hCtrlBlock, iColor, iFigure) ; return TRUE ; } break ; case WM_PAINT: PaintTheBlock (hCtrlBlock, iColor, iFigure) ; break ; } return FALSE ; }
涉及到的头文件,也就是resource.h的主要代码:
#define IDC_BLACK 1000 #define IDC_BLUE 1001 #define IDC_GREEN 1002 #define IDC_CYAN 1003 #define IDC_RED 1004 #define IDC_MAGENTA 1005 #define IDC_YELLOW 1006 #define IDC_WHITE 1007 #define IDC_RECT 1008 #define IDC_ELLIPSE 1009 #define IDC_PAINT 1010 #define IDM_APP_ABOUT 40001
资源文件的主要代码:
ABOUTBOX DIALOG DISCARDABLE 32, 32, 200, 234 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION FONT 8, "MS Sans Serif" BEGIN ICON "ABOUT2",IDC_STATIC,7,7,20,20 CTEXT "About2",IDC_STATIC,57,12,86,8 CTEXT "About Box Demo Program",IDC_STATIC,7,40,186,8 LTEXT "",IDC_PAINT,114,67,72,72 GROUPBOX "&Color",IDC_STATIC,7,60,84,143 RADIOBUTTON "&Black",IDC_BLACK,16,76,64,8,WS_GROUP | WS_TABSTOP RADIOBUTTON "B&lue",IDC_BLUE,16,92,64,8 RADIOBUTTON "&Green",IDC_GREEN,16,108,64,8 RADIOBUTTON "Cya&n",IDC_CYAN,16,124,64,8 RADIOBUTTON "&Red",IDC_RED,16,140,64,8 RADIOBUTTON "&Magenta",IDC_MAGENTA,16,156,64,8 RADIOBUTTON "&Yellow",IDC_YELLOW,16,172,64,8 RADIOBUTTON "&White",IDC_WHITE,16,188,64,8 GROUPBOX "&Figure",IDC_STATIC,109,156,84,46,WS_GROUP RADIOBUTTON "Rec&tangle",IDC_RECT,116,172,65,8,WS_GROUP | WS_TABSTOP RADIOBUTTON "&Ellipse",IDC_ELLIPSE,116,188,64,8 DEFPUSHBUTTON "OK",IDOK,35,212,50,14,WS_GROUP PUSHBUTTON "Cancel",IDCANCEL,113,212,50,14,WS_GROUP END ABOUT2 ICON DISCARDABLE "About2.ico" ABOUT2 MENU DISCARDABLE BEGIN POPUP "&Help" BEGIN MENUITEM "&About", IDM_APP_ABOUT END END #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO DISCARDABLE BEGIN "ABOUTBOX", DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 193 TOPMARGIN, 7 BOTTOMMARGIN, 227 END END #endif // APSTUDIO_INVOKED
运行效果如下:
![](https://static.oschina.net/uploads/space/2017/0119/152607_51GN_147032.png)
程序的作用是,通过弹出的对话框选择颜色,然后再选择椭圆还是矩形,单击确定时将选择的东西在主窗口中显示出相应的效果。这个程序看起来并不复杂,但涉及到的知识还是很多的,所以值得细说一下。
1,关于WS_GROUP和WS_TABSTOP。
2,坐标值的大小。
3,对话框过程及激活对话框。
4,对话框的外边框。
5,关于RGB的创建。
6,关于WS_SYSMENU。
7,CONTROL语句与CreateWindow的关系。
8,关于设备环境句柄(HDC)及PAINTSTRUCT结构。获取HDC有两种方式:
PAINTSTRUCT ps ; .... hdc = BeginPaint (hwnd, &ps) ; .... EndPaint (hwnd, &ps) ;
hdc = GetDC (hwnd) ; .... ReleaseDC (hwnd, hdc) ;
BeginPaint函数的作用是擦去无效区域的背景以便绘图,同时还会填充PAINTSTRUST结构的各个字段,并返回HDC,它与EndPaint必须成对出现。而上面的代码中,如果BeginPaint与EndPaint之间没有任何绘制图形的代码,作用是将无效区域有效化。
GetDC与ReleaseDC有点类似,也必须成对出现,将GetDC返回的设备环境句柄中的裁剪矩形是整个客户区,而BeginPaint可以是部分区域。需要绘制的区域是存放在PAINTSTRUST结构中,该结构定义如下:
typedef struct tagPAINTSTRUCT { HDC hdc; BOOL fErase; RECT rcPaint; BOOL fRestore; BOOL fIncUpdate; BYTE rgbReserved[32]; } PAINTSTRUCT, *PPAINTSTRUCT, *NPPAINTSTRUCT, *LPPAINTSTRUCT;
第三个字段RECT rcPaint,即存放需要绘制图形的矩形区域,这里面的值可以通过下列函数传过来。
BOOL InvalidateRect( HWND hWnd, // handle of window with changed update region CONST RECT *lpRect, // address of rectangle coordinates BOOL bErase // erase-background flag );
这个函数的第二个字段便是需绘制矩形的值。重要绘制整个客户区可以采用以下方式:
InvalidateRect(hwnd,NULL,TRUE)
9,绘制填充区域背景。
10,关于DialogBoxParam。
11,关于在主窗口绘制不同的图形。
以上几个方面,对于理解这个程序来说很重要,也涉及到很多Windows API编程的基础知识,值得反复研究。
相关文章推荐