您的位置:首页 > 其它

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

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

(1)图形的临时保存

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

//重载构造函数

CGraph::CGraph(UINT
m_nDrawType,CPoint
m_ptOrigin,CPoint
m_ptEnd,CPoint
bmpOrigin,UINT
LineWidth,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;

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: