当前位置:文档之家› 简单的绘图程序实验报告

简单的绘图程序实验报告

面向对象程序设计实训(基于MFC程序设计)题目: 简单的绘图程序院系专业:姓名:学号:同组其他学生(学号):简单绘图程序说明1、功能分析目前这个软件的主要功能有如下:1、画直线:通过OnLine()函数实现。

2、画矩形:通过OnRectangle()函数实现。

3、画圆角矩形:通过OnRoundrect()函数实现。

4、画椭圆:通过OnEllipse()函数实现。

5、铅笔工具:可以画任意线条。

通过直接在OnMouseMove(UINT nFlags, CPointpoint)函数里面添加代码实现。

6、右键弹出菜单:可以在客户中点击鼠标右键,快速选择常用菜单。

通过OnContextMenu函数实现。

7、状态栏显示鼠标移动的坐标:在程序的右下角显示,通过调用setWidnowText和GetParent()实现。

8、画图颜色选择:可以画任何颜色的线条,通过OnColor()函数实现。

9、线条类型及线宽的设置:可以将画出的线条设置成实线、虚线、点线、点划线,双点划线,还可以设置线条的粗细,,通过实例这一功能立刻显示所选择线条的粗细及线型。

通过新建CLineSettingDlg类,其中OnSelchangeLineStyle()函数实现线型的改变,OnChangeEditLineWidth()函数实现线宽的改变。

再在CDrawView类中调用OnLineSetting()函数实现画笔的对话框,CLineSettingDlg类中的OnPaint()函数是实现示例功能的。

10、窗口的重绘时不擦除原来的内容:新建CShape类用来保存线条的颜色,线宽,填充色等属性,在窗口大小发生变化时有OnDraw(CDC* pDC)函数进行重绘工作,重绘中调用了各个绘图函数的Draw(CDC *pDC)函数。

11、所绘图形的保存于读取,通过Serialize(CArchive &ar)函数进行序列化操作,将所绘图形的信息通过文件的形式保存起来。

2、系统总体框架图1 总体框架3、模块设计与分析3.1画图模块:该模块的大部份功能都写在了CDrawView类里面。

该模块也是此次程序的重点模块之一,主要负责画一些简单图形,例如:直线、矩形、圆角矩形、椭圆、任意曲线(铅笔)等等;有线型、线宽的设置;还有画笔颜色和填充色的选择,可以画各种各样颜色的线条;还包含的右键菜单设置的函数。

3.2窗口模块:这部分大多数都是编译器自动生成,只做了一些修改,例如:使程序一开始运行便最大话,还是自定义程序的标题。

3.3菜单模块:该部分同样大部分都是编译器自动生成的,自己增添了一部分菜单例如:绘图工具、颜色设置、线条设置等等。

还有右键弹出菜单,有颜色及线条设置等等,让使用者可以进行快速的操作。

3.4工具栏与状态栏模块:除了编译器自动生成的之外,还加入了画直线、矩形、圆角矩形、椭圆、铅笔等工具的快速选择,状态栏可以显示鼠标移动的坐标。

4、类的设计与分析4.1、CAboutDlg类由编译器生成,只做了一处的修改:m_pMainWnd->SetWindowText(_T("简单绘图工具")); //设定主框架窗口标题4.2、CDrawView类由编译器自动生成的类部分源代码:void CDrawView::OnLButtonDown(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call default if(m_flag==0){SetCapture();::SetCursor(m_hCross);m_ptOrigin = point;m_lMouseDown = true;}else{m_ptOrigin = point;m_ptOld = point;//临时点m_lMouseDown = true;//鼠标左键被按下SetCapture(); // 将鼠标消息发送到视窗口CRect rect;GetClientRect(&rect); // 得到客户窗口的大小ClientToScreen(&rect); // 将当前窗口坐标转换成屏幕坐标ClipCursor(&rect); // 把鼠标限定在其参数指定的矩形区域内SetCursor(m_hCross); // 获得十字光标}CScrollView::OnLButtonDown(nFlags, point);}/*响应鼠标移动消息,将起点与临时点之间的线擦除*/void CDrawView::OnMouseMove(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call default CString str;str.Format("x=%d,y=%d",point.x,point.y);//得到框架类窗口的指针GetParent(),然后指针强制转换为框架类的类型(CMainFrame*)//调用状态栏类的成员函数setWidnowText((CMainFrame*)GetParent())->m_wndStatusBar.SetWindowText(str);if( m_lMouseDown ){//初始化CClientDC dc(this);CPen pen(m_vLineStyle,m_vLineWidth,m_color);dc.SelectObject(&pen);CBrush brush; //定义画刷CPen * pOldPen = dc.SelectObject(&pen);//将画笔选入DC,并保存以前所用的画笔brush.CreateSolidBrush(m_fColor); //创建画刷dc.SelectObject(&brush); //获取画刷if(m_flag==0){CClientDC dc(this);CPen pen(m_vLineStyle,m_vLineWidth,m_color);dc.SelectObject(&pen);CDrawDoc *pDoc = GetDocument();ASSERT_VALID(pDoc);CPoint ptOrg, ptStart, ptEnd;ptOrg = GetScrollPosition(); // 获得当前工作区原点的坐标ptStart = m_ptOrigin + ptOrg; // 加上原点的坐标来修正线段的坐标ptEnd = point + ptOrg;CCLine *pCLine = new CCLine(ptStart,ptEnd,m_vLineStyle, m_vLineWidth,m_color,m_fColor);pDoc->m_obArray.Add(pCLine);pDoc->SetModifiedFlag();dc.MoveTo(m_ptOrigin);dc.LineTo(point);m_ptOrigin = point;}switch(m_flag){case 1: //画直线dc.SetROP2( R2_NOT ); //当前绘制的像素值设为屏幕像素值的反,这样可以覆盖掉上次的绘图,(自动擦除上次绘制的图形)dc.SelectStockObject(NULL_BRUSH);//使图线不遮去原有背景dc.MoveTo( m_ptOrigin ); //这两行代码擦除从起点到dc.LineTo( m_ptOld ); //上次鼠标移动到的位置之间的临时线dc.SelectObject(&pen);dc.MoveTo( m_ptOrigin ); //这两行代码从起点到鼠标当前位置画线dc.LineTo( point ); //break;case 2: //画矩形dc.SetROP2( R2_NOT );dc.SelectStockObject(NULL_BRUSH);dc.Rectangle(CRect(m_ptOrigin,m_ptOld));dc.SelectObject(&pen);dc.Rectangle(CRect(m_ptOrigin,point));break;case 3: //画圆角矩形dc.SetROP2( R2_NOT );dc.SelectStockObject(NULL_BRUSH);dc.RoundRect(CRect(m_ptOrigin,m_ptOld),CPoint(15, 15));dc.RoundRect(CRect(m_ptOrigin,point),CPoint(15, 15));break;case 4: //画椭圆dc.SetROP2( R2_NOT );dc.SelectStockObject(NULL_BRUSH);dc.Ellipse(CRect(m_ptOrigin,m_ptOld));dc.Ellipse(CRect(m_ptOrigin,point));break;case 5: //画圆,将椭圆的长轴长度与短轴长度相同即可dc.SetROP2( R2_NOT );dc.SelectStockObject(NULL_BRUSH);dc.Ellipse(m_ptOrigin.x,m_ptOrigin.y,m_ptOld.x,m_ptOrigin.y+m_ptO ld.x-m_ptOrigin.x);dc.Ellipse(m_ptOrigin.x,m_ptOrigin.y,point.x,m_ptOrigin.y+point.x -m_ptOrigin.x);break;}//switch 结束dc.SelectObject(pOldPen);//恢复先前的画笔m_ptOld = point;}//if 结束CScrollView::OnMouseMove(nFlags, point);}void CDrawView::OnLButtonUp(UINT nFlags, CPoint point){// TODO: Add your message handler code here and/or call default if(m_flag==0){if( m_lMouseDown ){m_lMouseDown = false;ReleaseCapture();ClipCursor( NULL );}}else{if( m_lMouseDown ){m_lMouseDown = false;CClientDC dc(this);CPen pen(m_vLineStyle,m_vLineWidth,m_color);dc.SelectObject(&pen);CBrush brush; //定义画刷brush.CreateSolidBrush(m_fColor); //创建画刷dc.SelectObject(&brush); //获取画刷CPen * pOldPen = dc.SelectObject(&pen);ReleaseCapture();ClipCursor( NULL );switch(m_flag){case 1: //画直线dc.SetROP2( R2_COPYPEN );//使用当前的画笔的颜色dc.MoveTo( m_ptOrigin ); //这两行代码从起点到鼠标当前位置画线dc.LineTo( point ); //break;case 2: //画矩形dc.Rectangle(CRect(m_ptOrigin,point));break;case 3: //画圆角矩形dc.RoundRect(CRect(m_ptOrigin,point),CPoint(10,15));break;case 4: //画椭圆dc.SetROP2( R2_COPYPEN );dc.Ellipse(CRect(m_ptOrigin,point));break;case 5: //画圆dc.SetROP2( R2_COPYPEN );dc.Ellipse(m_ptOrigin.x,m_ptOrigin.y,point.x,m_ptOrigin.y+point.x -m_ptOrigin.x);break;}//switch 结束//实现文件保存,将各图形类的地址保存在CObArray m_obArray数组中CDrawDoc* pDoc = GetDocument(); //得到文档类指针CShape *pShape ;CPoint ptOrg;ptOrg = GetScrollPosition(); // 获得当前工作区原点的坐标m_ptOrigin = m_ptOrigin + ptOrg; // 加上原点的坐标来修正线段的坐标point = point + ptOrg;switch(m_flag){case 1:pShape = new CLine(m_ptOrigin,point,m_vLineStyle, m_vLineWidth,m_color,m_fColor);break;case 2:pShape = new CRectangle(m_ptOrigin,point,m_vLineStyle, m_vLineWidth,m_color,m_fColor);break;case 3:pShape = new CRoundRect(m_ptOrigin,point,m_vLineStyle, m_vLineWidth,m_color,m_fColor);break;case 4:pShape = new CEllipse(m_ptOrigin,point,m_vLineStyle, m_vLineWidth,m_color,m_fColor);break;case 5:pShape = new CCircle(m_ptOrigin,point,m_vLineStyle, m_vLineWidth,m_color,m_fColor);break;}pDoc->m_obArray.Add(pShape);pDoc->SetModifiedFlag();}//if 结束m_lMouseDown = false;}CScrollView::OnLButtonUp(nFlags, point);}4.3、CMainFrame类主要由编译器生成,做了小部分修改://工具条的风格if (!s_ShapeToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_LEFT| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||!s_ShapeToolBar.LoadToolBar(IDR_SHAPETOOLBAR)){TRACE0("Failed to create toolbar\n");return -1; // fail to create}int nCount =s_ShapeToolBar.GetToolBarCtrl().GetButtonCount();//设置工具条按钮能被按下并且弹起for(int i=0;i<nCount;i++){s_ShapeToolBar.SetButtonStyle(i,TBBS_CHECKGROUP);}s_ShapeToolBar.EnableDocking(CBRS_ALIGN_ANY);//以下两行使形状工具条和标准工具条具有停靠能力,并且可以停靠在任何地方m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);EnableDocking(CBRS_ALIGN_ANY);DockControlBar(&m_wndToolBar);DockControlBar(&s_ShapeToolBar,AFX_IDW_DOCKBAR_LEFT,NULL);//使形状工具条停靠在客户区左边。

相关主题