《Windows程序设计》之对话框

来源:互联网 发布:阿里云虚拟主机搭建ss 编辑:程序博客网 时间:2024/06/08 18:07
///////////////////////////////////////////////////////////////////////////《Windows程序设计》第11章对话框代码ABOUT2/////////////////////////////////////////////////////////////////////////#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_VREDRAW|CS_HREDRAW;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.lpszClassName=szAppName;wndclass.lpszMenuName=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(255,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);elseEllipse(hdc,rect.left,rect.top,rect.right,rect.bottom);DeleteObject(SelectObject(hdc,hBrush));ReleaseDC(hwnd,hdc);}//对下面这个函数不理解,常规想法应该是PaintWindow后再UpdateWindow,但事实这样不可以,系统会卡住void PaintTheBlock(HWND hCtrl,int iColor,int iFigure){//使子窗口控件无效InvalidateRect(hCtrl,NULL,TRUE);//如果窗口更新的区域不为空,UpdateWindow函数通过发送一个WM_PAINT消息来更新指定窗口的客户区。//函数绕过应用程序的消息队列,直接发送WM_PAINT消息给指定窗口的窗口过程,如果更新区域为空,则不发送消息。//对此UpdateWindow还不是不懂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://根据对话框模板资源创建一个模态的对话框//这边是回调完成后才触发的//直到指定的回调函数通过调用EndDialog函数中止模态的对话框才能返回控制。//调用失败,返回-1//调用成功,返回EndDialog中的参数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));//这个返回TRUE跟FALSE,好像对结果没啥影响,不知其原因return FALSE;case WM_COMMAND://LOWORD(wParam)是指明哪个控件switch(LOWORD(wParam)){case IDOK:iCurrentColor=iColor;iCurrentFigure=iFigure;//这个返回关系着DialogBox的返回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;}///////////////////////////////////////////////////////////////////////////在一开始生成子窗口时,调用过程如下://PaintTheBlock----------->UpdateWindow-------->PaintWindow//在切换颜色与形状时,调用过程如下://UpdateWindow--------->PaintWindow//UpdateWindow到底做了什么?不是说会调用WM_PAINT么,但是我设置断点却没有/////////////////////////////////////////////////////////////////////////

看了几个帖子,好像大体理解了这个问题。

1、PaintTheBlock中传入的第一个参数并不是子窗口的,而是子窗口中一个Text控件的(用来画图的)。

2、调用InvalidateRect是来设置这个子窗口控件的区域无效

3、调用UpdateWindow是用来触发WM_PAINT,这个WM_PAINT是这个子窗口控件的WM_PAINT,而不是子窗口的。

4、上面两句代码的意思应该就是想清除这个文本控件的特征吧,然后直接来画图。

不知道这么理解对不对,还希望各位多多提意见

原创粉丝点击