mfc完成简单画板程序的设计,要求有:利用 MFC/QT 的向导,创建基于单文档的应用程序;图像互相重叠时,能正确显示图像。给出详细代码
时间: 2024-03-15 13:46:42 浏览: 96
基于MFC开发的基于单文档画图应用程序
4星 · 用户满意度95%
以下是一个基于 MFC 的简单画板程序设计的代码,实现了绘制直线、矩形和椭圆三种基本图形的功能。在图形重叠时,采用了透明度的方式来显示图形。
首先,使用 MFC/QT 的向导创建一个基于单文档的应用程序,然后在 CMyPaintDoc 类中添加以下成员变量和函数:
```c++
class CMyPaintDoc : public CDocument
{
protected:
CObArray m_arrShapes; // 保存图形的数组
int m_nPenWidth; // 画笔宽度
COLORREF m_clrPenColor; // 画笔颜色
public:
// 添加图形的函数
void AddShape(CShape* pShape);
// 获取图形数组的大小
int GetShapeCount() const;
// 获取指定索引处的图形
CShape* GetShape(int nIndex) const;
// 清空图形数组
void ClearShapes();
// 设置画笔宽度
void SetPenWidth(int nWidth);
// 获取画笔宽度
int GetPenWidth() const;
// 设置画笔颜色
void SetPenColor(COLORREF clr);
// 获取画笔颜色
COLORREF GetPenColor() const;
};
```
在 CMyPaintDoc 类的实现文件中,添加以下代码:
```c++
void CMyPaintDoc::AddShape(CShape* pShape)
{
m_arrShapes.Add(pShape);
SetModifiedFlag(); // 文档已被修改,需要保存
}
int CMyPaintDoc::GetShapeCount() const
{
return m_arrShapes.GetSize();
}
CShape* CMyPaintDoc::GetShape(int nIndex) const
{
return (CShape*)m_arrShapes.GetAt(nIndex);
}
void CMyPaintDoc::ClearShapes()
{
for (int i = 0; i < GetShapeCount(); i++)
delete GetShape(i);
m_arrShapes.RemoveAll();
SetModifiedFlag(); // 文档已被修改,需要保存
}
void CMyPaintDoc::SetPenWidth(int nWidth)
{
m_nPenWidth = nWidth;
}
int CMyPaintDoc::GetPenWidth() const
{
return m_nPenWidth;
}
void CMyPaintDoc::SetPenColor(COLORREF clr)
{
m_clrPenColor = clr;
}
COLORREF CMyPaintDoc::GetPenColor() const
{
return m_clrPenColor;
}
```
接下来,在 CMyPaintView 类中添加以下成员变量和函数:
```c++
class CMyPaintView : public CView
{
protected:
CPoint m_ptPrev; // 前一个点
int m_nDrawMode; // 绘制模式
CShape* m_pCurShape; // 当前绘制的图形
public:
CMyPaintDoc* GetDocument() const;
// 绘制直线
void DrawLine(const CPoint& ptFrom, const CPoint& ptTo);
// 绘制矩形
void DrawRect(const CPoint& ptFrom, const CPoint& ptTo);
// 绘制椭圆
void DrawEllipse(const CPoint& ptFrom, const CPoint& ptTo);
// 设置绘制模式
void SetDrawMode(int nMode);
// 获取绘制模式
int GetDrawMode() const;
};
```
在 CMyPaintView 类的实现文件中,添加以下代码:
```c++
CMyPaintDoc* CMyPaintView::GetDocument() const
{
return reinterpret_cast<CMyPaintDoc*>(m_pDocument);
}
void CMyPaintView::DrawLine(const CPoint& ptFrom, const CPoint& ptTo)
{
CDC* pDC = GetDC();
CPen pen(PS_SOLID, GetDocument()->GetPenWidth(), GetDocument()->GetPenColor());
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->MoveTo(ptFrom);
pDC->LineTo(ptTo);
pDC->SelectObject(pOldPen);
ReleaseDC(pDC);
}
void CMyPaintView::DrawRect(const CPoint& ptFrom, const CPoint& ptTo)
{
CDC* pDC = GetDC();
CPen pen(PS_SOLID, GetDocument()->GetPenWidth(), GetDocument()->GetPenColor());
CBrush brush(GetDocument()->GetPenColor());
CBrush* pOldBrush = pDC->SelectObject(&brush);
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->Rectangle(CRect(ptFrom, ptTo));
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
ReleaseDC(pDC);
}
void CMyPaintView::DrawEllipse(const CPoint& ptFrom, const CPoint& ptTo)
{
CDC* pDC = GetDC();
CPen pen(PS_SOLID, GetDocument()->GetPenWidth(), GetDocument()->GetPenColor());
CBrush brush(GetDocument()->GetPenColor());
CBrush* pOldBrush = pDC->SelectObject(&brush);
CPen* pOldPen = pDC->SelectObject(&pen);
pDC->Ellipse(CRect(ptFrom, ptTo));
pDC->SelectObject(pOldBrush);
pDC->SelectObject(pOldPen);
ReleaseDC(pDC);
}
void CMyPaintView::SetDrawMode(int nMode)
{
m_nDrawMode = nMode;
}
int CMyPaintView::GetDrawMode() const
{
return m_nDrawMode;
}
```
最后,在 CShape 类中添加以下成员变量和函数:
```c++
class CShape
{
protected:
CPoint m_ptFrom; // 起点
CPoint m_ptTo; // 终点
int m_nPenWidth; // 画笔宽度
COLORREF m_clrPenColor; // 画笔颜色
public:
CShape(const CPoint& ptFrom, const CPoint& ptTo, int nPenWidth, COLORREF clrPenColor);
virtual ~CShape();
CPoint GetFromPoint() const;
CPoint GetToPoint() const;
int GetPenWidth() const;
COLORREF GetPenColor() const;
virtual void Draw(CDC* pDC) = 0; // 纯虚函数,绘制图形
};
```
在 CShape 类的实现文件中,添加以下代码:
```c++
CShape::CShape(const CPoint& ptFrom, const CPoint& ptTo, int nPenWidth, COLORREF clrPenColor)
{
m_ptFrom = ptFrom;
m_ptTo = ptTo;
m_nPenWidth = nPenWidth;
m_clrPenColor = clrPenColor;
}
CShape::~CShape()
{
}
CPoint CShape::GetFromPoint() const
{
return m_ptFrom;
}
CPoint CShape::GetToPoint() const
{
return m_ptTo;
}
int CShape::GetPenWidth() const
{
return m_nPenWidth;
}
COLORREF CShape::GetPenColor() const
{
return m_clrPenColor;
}
```
然后,分别创建 CLineShape、CRectShape 和 CEllipseShape 类,继承自 CShape 类,实现 Draw 函数,绘制直线、矩形和椭圆图形。
最后,在 CMyPaintView 类中添加以下代码,实现绘制图形和鼠标事件的处理:
```c++
void CMyPaintView::OnDraw(CDC* pDC)
{
CMyPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
for (int i = 0; i < pDoc->GetShapeCount(); i++)
{
CShape* pShape = pDoc->GetShape(i);
ASSERT_VALID(pShape);
if (pShape)
pShape->Draw(pDC);
}
}
void CMyPaintView::OnLButtonDown(UINT nFlags, CPoint point)
{
m_ptPrev = point;
switch (GetDrawMode())
{
case DRAW_LINE:
m_pCurShape = new CLineShape(point, point, GetDocument()->GetPenWidth(), GetDocument()->GetPenColor());
break;
case DRAW_RECT:
m_pCurShape = new CRectShape(point, point, GetDocument()->GetPenWidth(), GetDocument()->GetPenColor());
break;
case DRAW_ELLIPSE:
m_pCurShape = new CEllipseShape(point, point, GetDocument()->GetPenWidth(), GetDocument()->GetPenColor());
break;
}
CView::OnLButtonDown(nFlags, point);
}
void CMyPaintView::OnMouseMove(UINT nFlags, CPoint point)
{
if (nFlags & MK_LBUTTON && m_pCurShape)
{
CClientDC dc(this);
dc.SetROP2(R2_NOTXORPEN);
m_pCurShape->Draw(&dc);
switch (GetDrawMode())
{
case DRAW_LINE:
m_pCurShape->GetToPoint() = point;
break;
case DRAW_RECT:
case DRAW_ELLIPSE:
m_pCurShape->GetToPoint().x = point.x;
m_pCurShape->GetToPoint().y = point.y;
break;
}
m_pCurShape->Draw(&dc);
}
CView::OnMouseMove(nFlags, point);
}
void CMyPaintView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_pCurShape)
{
CClientDC dc(this);
m_pCurShape->Draw(&dc);
GetDocument()->AddShape(m_pCurShape);
m_pCurShape = NULL;
}
CView::OnLButtonUp(nFlags, point);
}
void CMyPaintView::OnInitialUpdate()
{
CView::OnInitialUpdate();
SetDrawMode(DRAW_LINE); // 默认绘制直线
SetScrollSizes(MM_TEXT, GetDocument()->GetDocSize());
}
void CMyPaintView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
CMyPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
if (lHint == NULL) // 全部更新
{
SetScrollSizes(MM_TEXT, pDoc->GetDocSize());
Invalidate();
}
else // 部分更新
{
CRect* pRect = (CRect*)lHint;
InvalidateRect(pRect);
}
}
```
最后,在 CShape 类中添加以下代码,实现透明度的方式显示图形:
```c++
void CShape::Draw(CDC* pDC)
{
CRect rc(m_ptFrom, m_ptTo);
CBitmap bmp;
bmp.CreateCompatibleBitmap(pDC, rc.Width(), rc.Height());
CDC dcMem;
dcMem.CreateCompatibleDC(pDC);
CBitmap* pOldBitmap = dcMem.SelectObject(&bmp);
dcMem.FillSolidRect(0, 0, rc.Width(), rc.Height(), RGB(255, 255, 255)); // 白色背景
dcMem.SetBkMode(TRANSPARENT);
CPen pen(PS_SOLID, m_nPenWidth, m_clrPenColor);
CPen* pOldPen = dcMem.SelectObject(&pen);
CBrush brush(m_clrPenColor);
CBrush* pOldBrush = dcMem.SelectObject(&brush);
DrawShape(&dcMem); // 绘制图形
dcMem.SelectObject(pOldBrush);
dcMem.SelectObject(pOldPen);
dcMem.SelectObject(pOldBitmap);
pDC->BitBlt(m_ptFrom.x, m_ptFrom.y, rc.Width(), rc.Height(), &dcMem, 0, 0, SRCCOPY);
}
void CLineShape::DrawShape(CDC* pDC)
{
pDC->MoveTo(m_ptFrom);
pDC->LineTo(m_ptTo);
}
void CRectShape::DrawShape(CDC* pDC)
{
pDC->Rectangle(CRect(m_ptFrom, m_ptTo));
}
void CEllipseShape::DrawShape(CDC* pDC)
{
pDC->Ellipse(CRect(m_ptFrom, m_ptTo));
}
```
至此,一个基于 MFC 的简单画板程序就完成了。完整的代码如下:
阅读全文