您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > 06简单绘图程序的实现及菜单的使用
06简单绘图程序的实现及菜单的使用到现在为止已经分别实现了使用鼠标绘制线段、矩形、椭圆,能不能在一个程序里实现这三种操作的切换?当然可以!1、对绘制线段、矩形与椭圆的程序进行分析,每一种绘图操作有三个动作:鼠标落下、鼠标移动与鼠标弹起,分别对应于3段代码,对画线的三段代码进行分析,与这写代码相关的变量有:与消息相关的变量:HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam;与绘图操作相关的变量:POINTptStart,ptEnd;BOOLbMouseDown;如果把相关代码封装在三个绘图函数中,则以上变量都是窗口函数的局部变量,在绘图函数中是无法访问的,可以将消息的参数作为绘图函数的参数传到绘图函数中,也可以将绘图相关的变量变成函数参数,但这样存在以下问题:参数数量较多,效率较低,如果以后因为增加绘图函数的功能需要增加新的变量则需要修改函数的原型;因此可以将与绘图函数相关的变量封装在一个结构体内,在窗口函数中一个结构体变量,给绘图函数传入一个结构体指针。2、定义结构体如下:typedefstructtagDrawStru{POINTptStart,ptEnd;BOOLbMouseDown;}DRAWSTRU,*PDRAWSTRU;3、在窗口函数中定义如下静态局部变量:staticDRAWSTRUds;4、定义3个函数分别完成鼠标落下、移动和弹起的处理,代码如下:VOIDLineMouseDown(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam){pDs-ptStart.x=LOWORD(lParam);pDs-ptStart.y=HIWORD(lParam);pDs-ptEnd.x=pDs-ptStart.x;pDs-ptEnd.y=pDs-ptStart.y;pDs-bMouseDown=TRUE;SetCapture(hWnd);}VOIDLineMouseUp(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam){HDChdc;pDs-bMouseDown=FALSE;ReleaseCapture();hdc=GetDC(hWnd);SetROP2(hdc,R2_NOT);MoveToEx(hdc,pDs-ptStart.x,pDs-ptStart.y,NULL);LineTo(hdc,pDs-ptEnd.x,pDs-ptEnd.y);pDs-ptEnd.x=LOWORD(lParam);pDs-ptEnd.y=HIWORD(lParam);SetROP2(hdc,R2_COPYPEN);MoveToEx(hdc,pDs-ptStart.x,pDs-ptStart.y,NULL);LineTo(hdc,pDs-ptEnd.x,pDs-ptEnd.y);ReleaseDC(hWnd,hdc);}VOIDLineMouseMove(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam){HDChdc;if(pDs-bMouseDown){hdc=GetDC(hWnd);SetROP2(hdc,R2_NOT);MoveToEx(hdc,pDs-ptStart.x,pDs-ptStart.y,NULL);LineTo(hdc,pDs-ptEnd.x,pDs-ptEnd.y);pDs-ptEnd.x=LOWORD(lParam);pDs-ptEnd.y=HIWORD(lParam);MoveToEx(hdc,pDs-ptStart.x,pDs-ptStart.y,NULL);LineTo(hdc,pDs-ptEnd.x,pDs-ptEnd.y);ReleaseDC(hWnd,hdc);}}5、修改窗口过程,将鼠标消息的处理代码修改为函数调用,代码如下:caseWM_LBUTTONDOWN:LineMouseDown(&ds,hWnd,wParam,lParam);break;caseWM_LBUTTONUP:LineMouseUp(&ds,hWnd,wParam,lParam);break;caseWM_MOUSEMOVE:LineMouseMove(&ds,hWnd,wParam,lParam);break;6、在源程序文件的起始位置添加函数的声明:VOIDLineMouseDown(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);VOIDLineMouseUp(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);VOIDLineMouseMove(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);7、编译运行程序,观察运行结果。通过函数封装实现了绘制线段的操作8、同理对绘制矩形、椭圆的代码进行封装得到以下函数:VOIDRectMouseDown(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);VOIDRectMouseUp(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);VOIDRectMouseMove(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);VOIDEllipseMouseDown(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);VOIDEllipseMouseUp(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);VOIDEllipseMouseMove(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);9、定义一个函数指针类型:typedefVOID(*PDRAWFUN)(PDRAWSTRUpDs,HWNDhWnd,WPARAMwParam,LPARAMlParam);10、在窗口函数的定义部分定义3个函数指针变量:staticPDRAWFUNpMouseDown,pMouseUp,pMouseMove;11、在窗口收到WM_CREATE消息时对指针变量进行初始化:caseWM_CREATE:pMouseDown=EllipseMouseDown;pMouseUp=EllipseMouseUp;pMouseMove=EllipseMouseMove;break;12、修改鼠标消息的处理代码如下:caseWM_LBUTTONDOWN:pMouseDown(&ds,hWnd,wParam,lParam);break;caseWM_LBUTTONUP:pMouseUp(&ds,hWnd,wParam,lParam);break;caseWM_MOUSEMOVE:pMouseMove(&ds,hWnd,wParam,lParam);break;13、编译运行!可以实现修改3个函数指针变量指向不同的函数进行不同的绘图操作,最好是能够通过菜单或者工具栏实现指针变量的修改;14、为项目增加弹出式菜单如下图:菜单的参数如下表:ID标题&DrawIDM_DRAW_LINE&LineIDM_DRAW_RECT&RectangleIDM_DRAW_ELLIPSE&Ellipse15、为以上菜单项增加消息处理代码如下:caseIDM_DRAW_LINE:pMouseDown=LineMouseDown;pMouseUp=LineMouseUp;pMouseMove=LineMouseMove;break;caseIDM_DRAW_RECT:pMouseDown=RectMouseDown;pMouseUp=RectMouseUp;pMouseMove=RectMouseMove;break;caseIDM_DRAW_ELLIPSE:pMouseDown=EllipseMouseDown;pMouseUp=EllipseMouseUp;pMouseMove=EllipseMouseMove;break;编译运行程序,选择不同的菜单后,并使用鼠标绘制图形,发现程序有以下缺陷,菜单项不能反映当前鼠标操作时绘制什么图形。因此需要对菜单项添加标记。16、为菜单添加标记函数介绍:DWORDCheckMenuItem(HMENUhmenu,UINTuIDCheckItem,UINTuCheck);参数:hmenu:要做标记的菜单句柄uIDCheckItem:菜单项的ID或位置uCheck:为菜单加标记或清除标记,为下表中值的组合:值说明MF_BYCOMMAND指示uIDCheckItem参数表示菜单项的IDMF_BYPOSITION指示uIDCheckItem参数表示菜单项从0开始的位置MF_CHECKED添加选中标记MF_UNCHECKED清除选中标记将菜单消息的处理代码修改如下:caseIDM_DRAW_LINE:pMouseDown=LineMouseDown;pMouseUp=LineMouseUp;pMouseMove=LineMouseMove;CheckMenuItem(hMenu,IDM_DRAW_LINE,MF_BYCOMMAND|MF_CHECKED);CheckMenuItem(hMenu,IDM_DRAW_RECT,MF_BYCOMMAND|MF_UNCHECKED);CheckMenuItem(hMenu,IDM_DRAW_ELLIPSE,MF_BYCOMMAND|MF_UNCHECKED);break;caseIDM_DRAW_RECT:pMouseDown=RectMouseDown;pMouseUp=RectMouseUp;pMouseMove=RectMouseMove;CheckMenuItem(hMenu,IDM_DRAW_LINE,MF_BYCOMMAND|MF_UNCHECKED);CheckMenuItem(hMenu,IDM_DRAW_RECT,MF_BYCOMMAND|MF_CHECKED);CheckMenuItem(hMenu,IDM_DRAW_ELLIPSE,MF_BYCOMMAND|MF_UNCHECKED);break;caseIDM_DRAW_ELLIPSE:pMouseDown=EllipseMouseDown;pMouseUp=EllipseMouseUp;pMouseMove=EllipseMouseMove;CheckMenuItem(hMenu,IDM_DRAW_LINE,MF_BYCOMMAND|MF_UNCHECKED);CheckMenuItem(hMenu,IDM_DRAW_RECT,MF_BYCOMMAND|MF_UNCHECKED);CheckMenuItem(hMenu,IDM_DRAW_ELLIPSE,MF_BYCOMMAND|MF_CHECKED);break;17、编译运行程序!思考题:如何为系统加上颜色选择功能?绘图时当鼠标指针拖动到窗口的外面(标题栏的上部),会发现图形出现了异常,绘制的图形不在预期位置,分析为什么?(提示:分析HIWORD宏,#defineGET_Y_LPARAM(lp)((int)(short)HIWORD(lp))将所有的HIWORD宏用GET_Y_LPARAM宏替换,)为绘图程序增加线条颜色选择的功能到现在为止绘制出的图形都是黑色的,如果想绘制出不同颜色的图形则每次绘图时应创建指定颜色的画笔,因此为程序增加一个菜单如下图:菜单的参数如下表:ID标题&ColorIDM_COLOR_RED&RedIDM_COLOR_GREEN&GreenIDM_COLOR
本文标题:06简单绘图程序的实现及菜单的使用
链接地址:https://www.777doc.com/doc-3052178 .html