1.创建图形
新建一个MFC单文档应用程序,仍然增加一个菜单,命名绘图,再添加几个菜单项:
IDM_POINT(点)、IDM_LINE(直线)、IDM_ RECTANGLE(矩形)、IDM_ ELLIPSE
(椭圆),并分别对这四个菜单项添加命令响应,并在CGraphic2View类中添加一个私有的成员变量UINT
m_nDrawType;
并在构造方法中初始化:
CGraphic2View::CGraphic2View()
{
// TODO: add construction code here
m_nDrawType=0;
m_ptOrigin=0;
m_dcMetaFile.Create();//创建一个内存的CMetaFileDC对象
}
再编辑四个菜单项的命令响应:
void CGraphic2View::OnPoint()
{
// TODO: Add your command handler code here
m_nDrawType=1;
}
void CGraphic2View::OnLine()
{
m_nDrawType=2;
}
void CGraphic2View::OnRectangle()
{
m_nDrawType=3;
}
void CGraphic2View::OnEllipse()
{
m_nDrawType=4;
}
再在CGraphic2View类中添加一个私有的成员变量m_ptOrigin用来保存原点坐标,并在构造函数中初始化,上面已列出。
接着再给CGraphic2View类添加两个WM_LBUTTONDOWN和WM_LBUTTONUP消息响应函数,编辑:
void CGraphic2View::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptOrigin=point;//将这个点保存起来
CView::OnLButtonDown(nFlags, point);
}
void CGraphic2View::OnLButtonUp(UINT nFlags, CPoint point)
{
CClientDC dc(this);
CBrush *pBrush=CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
//创建透明画刷
dc.SelectObject(pBrush);
}
switch(m_nDrawType)
{
case 1:
dc.SetPixel(point,RGB(0,0,0)); break;
case 2:
dc.MoveTo(m_ptOrigin);
dc.LineTo(point); break;
case 3:
dc.Rectangle(CRect(m_ptOrigin,point)); break;
case 4:
dc.Ellipse(CRect(m_ptOrigin,point)); break;
}
CView::OnLButtonUp(nFlags, point);
}
运行可以发现当窗口尺寸发现变化是,所绘制的图形也消失了!
2.图形重绘
新建一个Generic
Class (name:CGraph),并在这个类当中增加3个成员变量,同时为了对这3个成员进行赋值,定义一个带参数的构造函数,如下:
public:
CPoint m_ptOrigin;
CPoint m_ptEnd;
UINT m_nDrawType;
CGraph();
CGraph(UINT m_nDrawType,CPoint m_ptOrigin,CPoint m_ptEnd);
并在源文件Graph.cpp当中,对这个类的成员变量赋值:
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;//图形终点
}
在CGraphic2View类当中,新增加一个成员变量CPtrArray
m_ptrArray; 这个集合类型的变量用来保存CGraph对象,并在CGraphic2View::OnLButtonUp添加:
CGraph graph(m_nDrawType,m_ptOrigin,point);//构造一个对象
//注:此时graph是一个局部变量,为它分配的内存在栈中,当这个函数结束时,对象也会被析构
m_ptrArray.Add(&graph);//将graph对象保存到集合类的对象m_ptArray当中
接下来在CGraphic2View::OnDraw函数中添加:
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,RGB(0,0,0));
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;