1、图形在窗体变化(如放大、缩小等操作)的时候,会有重绘现象,那样会擦除掉View上面所绘制的图形。这样,我们需要在View类的OnDraw()函数中写上相应的绘制代码。当然了,对于CDC类的绘制,我们就是需要将绘制的实现代码放在OnDraw()类里面。绘制里面,我们需要保存绘制的如"判定布尔值"、"起点"、"终点"这些数据,于是我们想到了用“集合类”来进行保存。实现方法如下:
①、定义一个类,一个普通的类(非MFC类),然后写一个构造函数,这个构造函数的参数是我们需要保存的元素:
声明如下:
class CGraph
{
public:
CGraph(void);
~CGraph(void);
UINT m_nDrawType;
CPoint m_ptOrigin;
CPoint m_ptEnd;
CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd); //构造函数,注意里面所传递的参数是我们要保存的
};
构造函数代码如下:
CGraph::CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd)
{
this->m_nDrawType=m_nDrawType;
this->m_ptOrigin=m_ptOrigin;
this->m_ptEnd=m_ptEnd;
}
②、定义一个集合类,并且保存之。注意这里有一个知识点:我们可以用集合类来保存相应的对象数据。我们可以new一个指针变量来传递给该指针对象
集合类定义:
private:
CPtrArray m_ptrArray;
用集合类的Add函数保存元素:
//这段代码放在绘制函数里面
CGraph *pGraph=new CGraph(m_nDrawType,m_ptOrigin,point);
m_ptrArray.Add(pGraph);
//-------------------这里就算保存完毕,下面我们就可以在OnDraw中使用集合类的GetAt()函数来取出集合类中保存的元素;当然,事先我们需要知道集合类的总元素个数,这个函数是GetSize().主要代码如下:
void CtenView::OnDraw(CDC* pDC)
{
CtenDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
CPen pn(m_nLineStyle,m_nLineWidth,m_clr);
CPen *pPen=pDC->SelectObject(&pn);
//dc.SelectObject(pBrush);
// TODO: add draw code for native data here
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
pDC->SelectObject(pBrush);
for(int i=0;i<m_ptrArray.GetSize();i++)
//取出集合类的元素
{
switch(((CGraph*)m_ptrArray.GetAt(i))->m_nDrawType) //使用集合类的元素
{
case 1:
pDC->SetPixel(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd,m_clr);
break;
case 2:
pDC->MoveTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin);
pDC->LineTo(((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd);
break;
case 3:
pDC->Rectangle(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
break;
case 4:
pDC->Ellipse(CRect(((CGraph*)m_ptrArray.GetAt(i))->m_ptOrigin,((CGraph*)m_ptrArray.GetAt(i))->m_ptEnd));
break;
default:
break;
}
}
}
2、MFC框架中的OnPaint()函数,会调用OnDraw()函数。负责重绘的是WM_PAINT消息的OnPaint()函数,其中它调用了OnDraw()函数。当然,要重绘的时候,我们一样也可以自己重写WM_PAINT消息的OnPaint()函数。
要注意,在OnPaint()函数中的OnPrepareDC(&dc)函数是用来定义程序的映射方式。
3、对于OnPrepareDC()函数,我们可以将设备单位转换为逻辑单位,相关程序代码如下:
OnPrepareDC(&dc); // dc是当前的DC
dc.DPtoLP(&m_ptOrigin); //起点
dc.DPtoLP(&point); //终点
4、将CView类修改为CScrollView类,那么就可以使得窗体有滚动条了。在之前一定要在CScrollView类中的OnInitialUpdate函数中,写上SetScrollSizes函数。要注意,一个窗体完全创建并调用OnDraw函数之前,要调用OnInitialUpdate函数
void CtenView::OnInitialUpdate()
{
CScrollView::OnInitialUpdate();
SetScrollSizes(MM_TEXT,CSize(800,600)); //在OnInitialUpdate中,对滚动条窗体写SetScrollSizes函数
// TODO: Add your specialized code here and/or call the base class
}