MFC中图形的临时保存和重绘

来源:互联网 发布:淘宝司法拍卖是什么 编辑:程序博客网 时间:2024/04/28 07:39

     在绘图设计时,我们在工具栏和菜单栏上创建了绘图功能,但在窗口绘制一些图形,当窗口的尺寸发生变化时,会发现窗口中绘制的图形都消失了。这是因为当窗口尺寸发生变化时,引起窗口的重绘,会发送WM_PAINT消息,这时会首先擦除窗口的背景,然后再进行重绘操作,这样就把窗口中先前绘制的图形擦除掉了。

(1)图形的临时保存

为使所绘制的图形始终在窗口中呈现出来,就需要在提前将这些图形临时保存起来。保存图形的方式有多种,对于本程序的图形主要有以下要素:起点、终点、绘制的类型(点、线、矩形、或椭圆)、位图起点坐标、线宽、线型、颜色等。为此我们创建CGraph类,来保存图形要素,这里仅列出重载的构造函数。

//重载构造函数

CGraph::CGraph(UINTm_nDrawType,CPointm_ptOrigin,CPointm_ptEnd,CPointbmpOrigin,UINTLineWidth,int LineStyle,COLORREF clr)

{

    this->m_nDrawType =m_nDrawType ;

    this->m_ptOrigin =m_ptOrigin ;

    this->m_ptEnd =m_ptEnd ;

    this->bmpOrigin =bmpOrigin ;

    this->LineWidth =LineWidth ;

    this->LineStyle =LineStyle ;

    this->clr = clr;

}

MFC中提供了一个集合类:CPtrArray,它可以用来存储CPtr类型的对象,而且它的容量是可以动态增加的,返回的是void类型的指针数组。此处,我们利用CPtrArray对象来存储多个对象的地址,如果想要增加一个成员,可以调用其Add方法,来增加一个void指针所对象,如果想要取得这个集合类中的某个元素,可以调用其GetAt方法,因为GetAt方法返回的是Void*类型,所以应将其强制转换为CGranph类型的指针。

往m_ptrArray动态添加图像对象:

CGraph*pGraph=newCGraph(m_nDrawType,m_ptOrigin,point,bmpOrigin,m_nLineWidth,m_nLineStyle,m_clr  );

m_ptrArray .Add (pGraph);

(2)OnDraw中重绘

保存完图形要素后,当窗口重绘时,OnDraw函数根据每一个已保存的图形绘制类型,利用其起点和终点将该图形在窗口重绘出来。首先在DrawView.cpp中添加头文件#include “Graph.h”,往OnDraw函数添加以下代码:

        //重绘原有的作图 

        CBrush  *pBrush=CBrush ::FromHandle ((HBRUSH)GetStockObject (NULL_BRUSH));

        pDC->SelectObject (pBrush );

        CPoint PStart,PEnd;

        for (int i  = 0;  i<m_ptrArray .GetSize () ; i++)

        {  

            //求取相对坐标和变换后的坐标

            TempOrigin.x =xorigin -((CGraph*)m_ptrArray.GetAt(i))->bmpOrigin.x ;

            TempOrigin.y =yorigin -((CGraph*)m_ptrArray.GetAt(i))->bmpOrigin.y ;

            PStart.x =((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin .x+ TempOrigin.x ;

            PStart.y =((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin .y+ TempOrigin.y ;

            PEnd.x =((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd .x+ TempOrigin.x ;

            PEnd.y =((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd .y+ TempOrigin.y ;

            CPen pen(m_nLineStyle,m_nLineWidth,((CGraph*)m_ptrArray .GetAt(i))->clr);

            pDC->SelectObject (&pen);

            switch (((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType )

            {

            case 1:

                pDC ->SetPixel (PEnd,((CGraph*)m_ptrArray.GetAt(i))->clr);

                break;

            case 2:

                pDC ->MoveTo (PStart);

                pDC ->LineTo  (PEnd);

                break;

            case 3:

                pDC->Rectangle (CRect(PStart,PEnd ));

                break;

            case 4:

                pDC->Ellipse (CRect(PStart,PEnd ));

                break;

            }

        }

    }

0 0
原创粉丝点击