简单绘图程序1 需求说明1.1 问题描述设计一个简单的绘图应用程序,可以绘制图形或自由绘制线段,可以更改颜色、画笔粗细、保存文件。
1.2功能说明1.图形绘制功能:直线、椭圆、矩形。
在菜单栏中选择需要的图形(也可以通过工具栏中选择)用鼠标便能在视图中绘出相应的图形。
2.可以绘制自由线段3.对图形的操作:能通过菜单栏弹出对话框选择线宽、自定义颜色,也可以擦除绘制的线段。
4.可以保存绘图文件,保存后打开可以继续绘制。
2.1.3 数据说明在程序运行以后,当用户单击某个菜单项时,应该把用户的选择保存起来,以便随后的绘图操作使用。
在CDzyView类中添加一个私有变量xz;用来保存用户的选择(直线、矩形、椭圆、自由绘图)在绘制时都可有两点来确定其图形。
当鼠标左击时得到一个点,当鼠标停止移动时得到另外一个点。
为视图类CDzyView分别捕获鼠标左键按下和弹起这两个消息。
当鼠标左键按下时,需要将鼠标当前按下点保存至sx、sy,在鼠标移动停止后,将当前坐标保存至ex,ey.其他主要数据说明:int fd 判断是否为自由绘图模式int w 线宽int R RGB中的Rint G RGB中的Gint B RGB中的BCGraph类中int m_nType:保存后重绘时用户的选择int qdx; 重绘起点xint qdy; 重绘起点yint zdx; 重绘终点xint zdy; 重绘终点yCLine类中int cx; 重绘线宽int sx; 重绘起点xint sy; 重绘起点yint zx; 重绘终点xint zy; 重绘终点yint w; 重绘线宽自定义颜色对话框关联变量:IDC_EDIT_RED int m_RedIDC_EDIT_GREEN int m_GreenIDC_EDIT_BLUE int m_BlueIDC_SCROLL_RED CScrollBar m_SredIDC_SLIDER_GREEN CSliderCtrl m_SgreenIDC_SPIN_BLUE CSpinButtonCtrl m_Sblue2 分析、设计与实现2.1 主要功能设计与实现2.1.1 有关文档视图功能的设计与实现单文档结构可序列化的类CGraph从CObject派生可序列化的类CLine从CObject派生对话框类zdyyanse从CDialog派生2.1.2 有关消息处理的设计与实现方案:需要响应的消息应有:鼠标移动、鼠标左键按下、鼠标左键抬起、菜单栏中的画矩形、画直线、画椭圆、自由绘图、更多选项中的自定义颜色、工具栏中的红色、蓝色、绿色、线宽1、线宽2、线宽3、橡皮擦。
整体思路为,用户选择不同的功能后就响应相应的消息处理函数,给xz赋对应的值。
选择不同的线宽,线色,即可改变画笔或画刷的属性。
鼠标的按下响应函数OnLButtonDown(),捕捉鼠标当前位置得到起点的坐标,鼠标的拖动响函数OnMouseMove()改变终点的坐标,鼠标的弹起响应OnLButtonUp(),得到绘制图形。
ID_DRAW_ELLIPSE:COMMAND 画椭圆ID_DRAW_LINE:COMMAND 画直线ID_DRAW_RECTANGLE:COMMAND 画矩形ON_WM_LBUTTONDOWN 鼠标左键按下ON_WM_LBUTTONUP 鼠标左键抬起ON_WM_MOUSEMOVE 鼠标移动void CDzyView::OnDrawEllipse(){// TODO: Add your command handler code herexz=3;}//当用户选择画椭圆,将变量xz赋值为3.void CDzyView::OnDrawLine(){// TODO: Add your command handler code herexz=1;}//当用户选择画直线,将变量xz赋值为1.void CDzyView::OnDrawRectangle(){// TODO: Add your command handler code herexz=2;}//当用户选择画矩形,将变量xz赋值为2.void CDzyView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultsx=point.x;sy=point.y;fd=1;CView::OnLButtonDown(nFlags, point);}//鼠标左键按下,将当前坐标赋值给sx,sy 并判断鼠标是否按下(fd=1)void CDzyView::OnLButtonUp(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultCClientDC dc(this); //this一般指向本窗口或当前活动视图CPen pen; //定义画笔pen.CreatePen(PS_SOLID,w,RGB(R,G,B)); //创建画笔dc.SelectStockObject(NULL_BRUSH);dc.SelectObject(&pen); //获取画笔fd=0;switch (xz){case 1:dc.MoveTo(sx,sy);dc.LineTo(ex,ey);break;case 2:dc.Rectangle(sx,sy,ex,ey);break;case 3:dc.Ellipse(sx,sy,ex,ey);break;}CGraph *pGraph=new CGraph(xz,sx,sy,ex,ey,w,R,G,B);GetDocument()->m_obArray.Add(pGraph);CView::OnLButtonUp(nFlags, point);CDzyDoc* pDoc=GetDocument();}//鼠标抬起时进行绘图,并将用户画的每一个图形对象保存到m_obArray中void CDzyView::OnMouseMove(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call defaultex=point.x;ey=point.y;CMainFrame *pFrame;pFrame=(CMainFrame *)AfxGetApp()->m_pMainWnd ; //获得指向主框架窗口的指针CStatusBar *pStatus=&pFrame->m_wndStatusBar;//获得指向主框架窗口上状态条的地址CString str;if(pStatus){str.Format("X=%d",point.x);pStatus->SetPaneText(1,str); //在第1个窗格中显示str的内容str.Format("Y=%d",point.y);pStatus->SetPaneText(2,str); //在第2个窗格中显示str的内容}if(xz==4){if(fd==1){CLine *pLine=new CLine(sx,sy,ex,ey,w,R,G,B);GetDocument()->m_lineObarry.Add(pLine);CClientDC dc(this);CPen pen; //定义画笔pen.CreatePen(PS_SOLID,w,RGB(R,G,B)); //创建画笔dc.SelectObject(&pen); //获取画笔dc.MoveTo(sx,sy);dc.LineTo(point);sx=point.x;sy=point.y;}}CView::OnMouseMove(nFlags, point);}//获取终点坐标,并进行自由绘图操作,同时在状态栏中显示鼠标当前坐标。
并保存自由绘图的坐标。
void CDzyView::OnW1(){// TODO: Add your command handler code herew=2;}//将线宽设为2void CDzyView::OnW2(){// TODO: Add your command handler code herew=3;}//将线宽设为3void CDzyView::Onw3(){// TODO: Add your command handler code here w=5;}//将线宽设为5void CDzyView::OnBlue(){// TODO: Add your command handler code here R=0;G=0;B=255;}//工具栏中选择蓝色void CDzyView::OnRed(){// TODO: Add your command handler code here R=255;G=0;B=0;}//工具栏中选择红色void CDzyView::OnGreen(){// TODO: Add your command handler code here R=0;G=255;B=0;}//工具栏中选择绿色void CDzyView::OnFreedraw(){// TODO: Add your command handler code here xz=4;}//自由绘图void CDzyView::OnEraser(){// TODO: Add your command handler code here R=255;G=255;B=255;xz=4;}void CDzyView::Onzdy(){// TODO: Add your command handler code herezdyyanse dlg; //定义对话框对象int result= dlg.DoModal();if(result==IDOK){R=dlg.m_Red;B=dlg.m_Blue;G=dlg.m_Green;}}2.1.3 有关菜单、工具栏、状态栏设计与实现保持原有菜单并添加绘图工具--矩形颜色与线宽----颜色自由绘图更多椭圆线宽------线宽1直线线宽2线宽3工具栏:添加矩形、直线、椭圆的快速绘图按钮添加颜色快速选择按钮添加线宽快速选择按钮状态栏:设计显示当前鼠标坐标2.1.4 有关对话框的设计与实现通过菜单点击更多选项中的自定义颜色弹出对话框用滚动条、滑动条、旋转按钮修改3种颜色的值,并改变改变预览值的填充色初始化单色的值为0~255,应把滚动控件值的变化范围限制在此区间,且初始值为0 颜色的存储3种单色值存放在编辑框的关联变量中(int型)滚动控件当前值的变化和编辑框中数值的变化均应改变这3个关联变量(关联变量与编辑框、滚动控件联动)可在相应的消息处理函数中完成联动画图3种单色值每次变化,都重画椭圆,所以画椭圆的代码应放在每个消息处理函数中void zdyyanse::OnChangeEditBlue(){// TODO: If this is a RICHEDIT control, the control will not// send this notification unless you override the CDialog::OnInitDialog()// function and call CRichEditCtrl().SetEventMask()// with the ENM_CHANGE flag ORed into the mask.UpdateData();m_Sblue.SetPos(m_Blue);// TODO: Add your control notification handler code here}void zdyyanse::OnChangeEditGreen(){// TODO: If this is a RICHEDIT control, the control will not// send this notification unless you override the CDialog::OnInitDialog()// function and call CRichEditCtrl().SetEventMask()// with the ENM_CHANGE flag ORed into the mask.UpdateData();m_Sgreen.SetPos(m_Green);// TODO: Add your control notification handler code here}void zdyyanse::OnChangeEditRed(){// TODO: If this is a RICHEDIT control, the control will not// send this notification unless you override the CDialog::OnInitDialog()// function and call CRichEditCtrl().SetEventMask()// with the ENM_CHANGE flag ORed into the mask.UpdateData();m_Sred.SetScrollPos(m_Red);// TODO: Add your control notification handler code here}void zdyyanse::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) {// TODO: Add your message handler code here and/or call defaultif(pScrollBar==&m_Sred){ // 滚动条switch(nSBCode){case SB_THUMBTRACK: // 拖动划块m_Sred.SetScrollPos(nPos);m_Red=nPos; break;case SB_LINEDOWN: // 按zuo按钮m_Red=m_Sred.GetScrollPos()+1;m_Sred.SetScrollPos(m_Red); break;case SB_LINEUP: // 按you按钮m_Red=m_Sred.GetScrollPos()-1;m_Sred.SetScrollPos(m_Red); break;}}if((pScrollBar->GetDlgCtrlID())==IDC_SLIDER_GREEN ) // 滑动条m_Green=m_Sgreen.GetPos();UpdateData(false);CDC* pDC=GetDC();CBrush newBrush;CPen newPen;newBrush.CreateSolidBrush(RGB(m_Red,m_Green,m_Blue));newPen.CreatePen(PS_SOLID,1,RGB(m_Red,m_Green,m_Blue));pDC->SelectObject(&newPen);pDC->SelectObject(&newBrush);pDC->Rectangle(50,70,150,150);ReleaseDC(pDC);CDialog::OnHScroll(nSBCode, nPos, pScrollBar);}BOOL zdyyanse::OnInitDialog(){CDialog::OnInitDialog();// TODO: Add extra initialization herem_Sred.SetScrollRange(0,255);m_Sred.SetScrollPos(0);m_Sgreen.SetRange(0,255);m_Sgreen.SetPos(0);m_Sblue.SetRange(0,255);m_Sblue.SetPos(0);return TRUE; // return TRUE unless you set the focus to a control// EXCEPTION: OCX Property Pages should return FALSE }void zdyyanse::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){// TODO: Add your message handler code here and/or call defaultm_Blue=nPos;UpdateData(false);CDC* pDC=GetDC();CBrush newBrush;CPen newPen;newBrush.CreateSolidBrush(RGB(m_Red,m_Green,m_Blue));newPen.CreatePen(PS_SOLID,1,RGB(m_Red,m_Green,m_Blue));pDC->SelectObject(&newPen);pDC->SelectObject(&newBrush);pDC->Rectangle(50,70,150,150);ReleaseDC(pDC);CDialog::OnVScroll(nSBCode, nPos, pScrollBar);}2.1.5 有关图形显示的设计与实现为用户提供绘制矩形、椭圆、直线、自由曲线功能。