vs2019用mfc单个文档绘制简单图形
时间: 2023-11-20 13:06:34 浏览: 115
可以通过在 MFC 的文档/视图结构中添加绘图功能来实现在单个文档中绘制简单图形。下面是一个示例,该示例展示了如何在 MFC 应用程序中创建一个简单的绘图工具,该工具允许用户在文档视图中绘制直线和矩形。
1. 创建一个 MFC 单文档应用程序。
2. 在资源视图中添加两个按钮和一个编辑框,分别用于选择绘制直线或矩形,设置线条颜色和宽度。
3. 在文档类中添加以下成员变量:
```
// 用于保存当前绘制的图形类型
enum ShapeType { LINE, RECTANGLE };
ShapeType m_shapeType;
// 用于保存当前线条颜色和宽度
COLORREF m_lineColor;
int m_lineWidth;
```
4. 在文档类中添加以下成员函数:
```
void SetShapeType(ShapeType type);
void SetLineColor(COLORREF color);
void SetLineWidth(int width);
```
5. 在文档类实现文件中实现这些函数。例如,SetShapeType 函数可以实现如下:
```
void CMyDoc::SetShapeType(ShapeType type)
{
m_shapeType = type;
}
```
6. 在视图类的头文件中添加以下成员函数:
```
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
```
7. 在视图类的实现文件中添加以下代码:
```
void CMyView::OnLButtonDown(UINT nFlags, CPoint point)
{
// 记录鼠标按下的位置
m_startPoint = point;
// 根据文档类中保存的图形类型,创建一个新的图形对象
switch (GetDocument()->m_shapeType)
{
case CMyDoc::LINE:
m_currentShape = new CLineShape(m_startPoint, m_startPoint);
break;
case CMyDoc::RECTANGLE:
m_currentShape = new CRectShape(m_startPoint, m_startPoint);
break;
}
CScrollView::OnLButtonDown(nFlags, point);
}
void CMyView::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_currentShape != NULL)
{
// 更新当前图形对象的结束位置
m_currentShape->SetEndPoint(point);
// 强制重绘视图
Invalidate();
}
CScrollView::OnMouseMove(nFlags, point);
}
void CMyView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_currentShape != NULL)
{
// 更新当前图形对象的结束位置
m_currentShape->SetEndPoint(point);
// 将当前图形对象添加到文档中
GetDocument()->AddShape(m_currentShape);
// 释放当前图形对象
m_currentShape = NULL;
// 强制重绘视图
Invalidate();
}
CScrollView::OnLButtonUp(nFlags, point);
}
```
8. 在文档类中添加以下成员变量和成员函数:
```
// 用于保存所有图形对象的列表
CList<CShape*, CShape*> m_shapeList;
void AddShape(CShape* shape);
void RemoveAllShapes();
```
9. 在文档类实现文件中实现这些函数。例如,AddShape 函数可以实现如下:
```
void CMyDoc::AddShape(CShape* shape)
{
m_shapeList.AddTail(shape);
}
```
10. 在视图类的头文件中添加以下成员函数:
```
afx_msg void OnDraw(CDC* pDC);
```
11. 在视图类的实现文件中添加以下代码:
```
void CMyView::OnDraw(CDC* pDC)
{
// 遍历文档中保存的所有图形对象,绘制它们
POSITION pos = GetDocument()->m_shapeList.GetHeadPosition();
while (pos != NULL)
{
CShape* shape = GetDocument()->m_shapeList.GetNext(pos);
shape->Draw(pDC);
}
// 如果当前有正在绘制的图形对象,也绘制它
if (m_currentShape != NULL)
{
m_currentShape->Draw(pDC);
}
}
```
12. 在文档类中添加以下成员函数:
```
void Serialize(CArchive& ar);
```
13. 在文档类实现文件中实现 Serialize 函数,以便保存和加载文档中的图形数据。例如,可以将函数实现为:
```
void CMyDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// 存储图形数据
ar << (DWORD)m_shapeList.GetCount();
POSITION pos = m_shapeList.GetHeadPosition();
while (pos != NULL)
{
CShape* shape = m_shapeList.GetNext(pos);
shape->Serialize(ar);
}
}
else
{
// 加载图形数据
RemoveAllShapes();
DWORD count;
ar >> count;
for (DWORD i = 0; i < count; i++)
{
CShape* shape = NULL;
UINT type;
ar >> type;
switch (type)
{
case CShape::LINE:
shape = new CLineShape();
break;
case CShape::RECTANGLE:
shape = new CRectShape();
break;
}
if (shape != NULL)
{
shape->Serialize(ar);
m_shapeList.AddTail(shape);
}
}
}
}
```
14. 创建一个基类为 CShape 的图形类,包括以下成员变量和成员函数:
```
// 用于保存起点和终点
CPoint m_startPoint;
CPoint m_endPoint;
// 用于序列化
enum { LINE, RECTANGLE };
virtual void Serialize(CArchive& ar);
// 用于绘制
virtual void Draw(CDC* pDC) = 0;
// 用于设置起点和终点
void SetStartPoint(const CPoint& point);
void SetEndPoint(const CPoint& point);
```
15. 在 CShape 类实现文件中实现这些函数。例如,SetStartPoint 函数可以实现如下:
```
void CShape::SetStartPoint(const CPoint& point)
{
m_startPoint = point;
}
```
16. 创建一个基类为 CLineShape 的直线类,继承自 CShape 类,包括以下成员变量和成员函数:
```
// 用于设置起点和终点
CLineShape(const CPoint& startPoint = CPoint(0, 0), const CPoint& endPoint = CPoint(0, 0));
virtual void SetEndPoint(const CPoint& point);
virtual void Draw(CDC* pDC);
```
17. 在 CLineShape 类实现文件中实现这些函数。例如,Draw 函数可以实现如下:
```
void CLineShape::Draw(CDC* pDC)
{
CPen pen(PS_SOLID, GetLineWidth(), GetLineColor());
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(m_startPoint);
pDC->LineTo(m_endPoint);
pDC->SelectObject(pOldPen);
}
```
18. 创建一个基类为 CRectShape 的矩形类,继承自 CShape 类,包括以下成员变量和成员函数:
```
// 用于设置起点和终点
CRectShape(const CPoint& startPoint = CPoint(0, 0), const CPoint& endPoint = CPoint(0, 0));
virtual void SetEndPoint(const CPoint& point);
virtual void Draw(CDC* pDC);
```
19. 在 CRectShape 类实现文件中实现这些函数。例如,Draw 函数可以实现如下:
```
void CRectShape::Draw(CDC* pDC)
{
CPen pen(PS_SOLID, GetLineWidth(), GetLineColor());
CPen* pOldPen = pDC->SelectObject(&pen);
CBrush brush(GetLineColor());
CBrush* pOldBrush = pDC->SelectObject(&brush);
pDC->Rectangle(CRect(m_startPoint, m_endPoint));
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
}
```
这样,就可以在 MFC 单文档应用程序中创建一个简单的绘图工具,允许用户在文档视图中绘制直线和矩形。
阅读全文