VC++ mfc制作简易画图板要求可以画基本形状,并具有填充功能,可以画线段,圆,方,三角形,能改变颜色,线条粗细代码
时间: 2023-08-14 11:08:16 浏览: 47
以下是一个简单的VC++ MFC制作画图板的代码,包含基本形状和填充功能,可以画线段,圆,方,三角形,能改变颜色,线条粗细。
首先是头文件和全局变量的声明:
```cpp
#pragma once
#include "afxwin.h"
#include "afxext.h"
class CMyPaintView : public CView
{
protected:
CMyPaintView();
DECLARE_DYNCREATE(CMyPaintView)
public:
virtual ~CMyPaintView();
virtual void OnDraw(CDC* pDC);
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
afx_msg void OnSize(UINT nType, int cx, int cy);
afx_msg void OnColor();
afx_msg void OnLineWidth();
afx_msg void OnFill();
DECLARE_MESSAGE_MAP()
private:
CDC m_dcMem;
CBitmap m_bmpMem;
CPoint m_ptStart;
CPoint m_ptEnd;
BOOL m_bDrawing;
BOOL m_bFill;
COLORREF m_clr;
int m_nLineWidth;
int m_nShape;
};
```
接下来是实现代码:
```cpp
#include "stdafx.h"
#include "MyPaint.h"
#include "MyPaintDoc.h"
#include "MyPaintView.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
IMPLEMENT_DYNCREATE(CMyPaintView, CView)
BEGIN_MESSAGE_MAP(CMyPaintView, CView)
ON_WM_LBUTTONDOWN()
ON_WM_MOUSEMOVE()
ON_WM_LBUTTONUP()
ON_WM_SIZE()
ON_COMMAND(ID_COLOR, &CMyPaintView::OnColor)
ON_COMMAND(ID_LINEWIDTH, &CMyPaintView::OnLineWidth)
ON_COMMAND(ID_FILL, &CMyPaintView::OnFill)
END_MESSAGE_MAP()
CMyPaintView::CMyPaintView()
{
m_bDrawing = FALSE;
m_bFill = FALSE;
m_clr = RGB(0, 0, 0);
m_nLineWidth = 1;
m_nShape = 0;
}
CMyPaintView::~CMyPaintView()
{
}
BOOL CMyPaintView::PreCreateWindow(CREATESTRUCT& cs)
{
return CView::PreCreateWindow(cs);
}
void CMyPaintView::OnDraw(CDC* pDC)
{
CMyPaintDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
pDC->BitBlt(0, 0, pDoc->m_nWidth, pDoc->m_nHeight, &m_dcMem, 0, 0, SRCCOPY);
}
void CMyPaintView::OnLButtonDown(UINT nFlags, CPoint point)
{
if (!m_bDrawing)
{
m_ptStart = point;
m_ptEnd = point;
m_bDrawing = TRUE;
}
}
void CMyPaintView::OnMouseMove(UINT nFlags, CPoint point)
{
if (m_bDrawing)
{
CDC* pDC = GetDC();
m_dcMem.SelectObject(&m_bmpMem);
m_dcMem.BitBlt(0, 0, m_bmpMem.GetBitmapDimension().cx, m_bmpMem.GetBitmapDimension().cy, pDC, 0, 0, SRCCOPY);
CPen pen;
pen.CreatePen(PS_SOLID, m_nLineWidth, m_clr);
CBrush brush;
brush.CreateSolidBrush(m_clr);
CPen* pOldPen = m_dcMem.SelectObject(&pen);
CBrush* pOldBrush = m_dcMem.SelectObject(&brush);
switch (m_nShape)
{
case 0: // 线段
m_dcMem.MoveTo(m_ptStart);
m_dcMem.LineTo(point);
break;
case 1: // 圆
m_dcMem.Ellipse(m_ptStart.x, m_ptStart.y, point.x, point.y);
break;
case 2: // 方
m_dcMem.Rectangle(m_ptStart.x, m_ptStart.y, point.x, point.y);
break;
case 3: // 三角形
{
POINT pts[3];
pts[0] = m_ptStart;
pts[1].x = m_ptStart.x;
pts[1].y = point.y;
pts[2] = point;
m_dcMem.Polygon(pts, 3);
}
break;
default:
break;
}
if (m_bFill)
{
m_dcMem.SelectObject(&brush);
m_dcMem.FillSolidRect(CRect(m_ptStart, point), m_clr);
}
m_dcMem.SelectObject(pOldPen);
m_dcMem.SelectObject(pOldBrush);
ReleaseDC(pDC);
m_ptEnd = point;
Invalidate(FALSE);
}
}
void CMyPaintView::OnLButtonUp(UINT nFlags, CPoint point)
{
if (m_bDrawing)
{
CDC* pDC = GetDC();
m_dcMem.SelectObject(&m_bmpMem);
m_dcMem.BitBlt(0, 0, m_bmpMem.GetBitmapDimension().cx, m_bmpMem.GetBitmapDimension().cy, pDC, 0, 0, SRCCOPY);
CPen pen;
pen.CreatePen(PS_SOLID, m_nLineWidth, m_clr);
CBrush brush;
brush.CreateSolidBrush(m_clr);
CPen* pOldPen = m_dcMem.SelectObject(&pen);
CBrush* pOldBrush = m_dcMem.SelectObject(&brush);
switch (m_nShape)
{
case 0: // 线段
m_dcMem.MoveTo(m_ptStart);
m_dcMem.LineTo(point);
break;
case 1: // 圆
m_dcMem.Ellipse(m_ptStart.x, m_ptStart.y, point.x, point.y);
break;
case 2: // 方
m_dcMem.Rectangle(m_ptStart.x, m_ptStart.y, point.x, point.y);
break;
case 3: // 三角形
{
POINT pts[3];
pts[0] = m_ptStart;
pts[1].x = m_ptStart.x;
pts[1].y = point.y;
pts[2] = point;
m_dcMem.Polygon(pts, 3);
}
break;
default:
break;
}
if (m_bFill)
{
m_dcMem.SelectObject(&brush);
m_dcMem.FillSolidRect(CRect(m_ptStart, point), m_clr);
}
m_dcMem.SelectObject(pOldPen);
m_dcMem.SelectObject(pOldBrush);
ReleaseDC(pDC);
m_ptEnd = point;
m_bDrawing = FALSE;
}
}
void CMyPaintView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
if (cx > 0 && cy > 0)
{
m_dcMem.DeleteDC();
m_bmpMem.DeleteObject();
CDC* pDC = GetDC();
m_dcMem.CreateCompatibleDC(pDC);
m_bmpMem.CreateCompatibleBitmap(pDC, cx, cy);
m_dcMem.SelectObject(&m_bmpMem);
ReleaseDC(pDC);
}
}
void CMyPaintView::OnColor()
{
CColorDialog dlg(m_clr);
if (dlg.DoModal() == IDOK)
{
m_clr = dlg.GetColor();
}
}
void CMyPaintView::OnLineWidth()
{
CInputDialog dlg(_T("请输入线条宽度:"), m_nLineWidth);
if (dlg.DoModal() == IDOK)
{
m_nLineWidth = dlg.GetValue();
}
}
void CMyPaintView::OnFill()
{
m_bFill = !m_bFill;
}
#ifdef _DEBUG
void CMyPaintView::AssertValid() const
{
CView::AssertValid();
}
void CMyPaintView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CMyPaintDoc* CMyPaintView::GetDocument() const // 非调试版本是内联的
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyPaintDoc)));
return (CMyPaintDoc*)m_pDocument;
}
#endif //_DEBUG
```
这里使用了一个自定义的输入框类CInputDialog,用于获取用户输入的线条宽度。
```cpp
#pragma once
#include "afxwin.h"
// CInputDialog 对话框
class CInputDialog : public CDialogEx
{
DECLARE_DYNAMIC(CInputDialog)
public:
CInputDialog(CString strPrompt, int nDefaultVal, CWnd* pParent = NULL); // 标准构造函数
virtual ~CInputDialog();
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_INPUT_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
DECLARE_MESSAGE_MAP()
public:
int m_nValue;
CString m_strPrompt;
afx_msg void OnBnClickedOk();
virtual BOOL OnInitDialog();
};
```
```cpp
#include "stdafx.h"
#include "InputDialog.h"
#include "afxdialogex.h"
// CInputDialog 对话框
IMPLEMENT_DYNAMIC(CInputDialog, CDialogEx)
CInputDialog::CInputDialog(CString strPrompt, int nDefaultVal, CWnd* pParent /*=NULL*/)
: CDialogEx(IDD_INPUT_DIALOG, pParent)
{
m_strPrompt = strPrompt;
m_nValue = nDefaultVal;
}
CInputDialog::~CInputDialog()
{
}
void CInputDialog::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Text(pDX, IDC_EDIT_VALUE, m_nValue);
DDX_Text(pDX, IDC_STATIC_PROMPT, m_strPrompt);
}
BEGIN_MESSAGE_MAP(CInputDialog, CDialogEx)
ON_BN_CLICKED(IDOK, &CInputDialog::OnBnClickedOk)
END_MESSAGE_MAP()
// CInputDialog 消息处理程序
void CInputDialog::OnBnClickedOk()
{
UpdateData(TRUE);
CDialogEx::OnOK();
}
BOOL CInputDialog::OnInitDialog()
{
CDialogEx::OnInitDialog();
CEdit* pEditValue = (CEdit*)GetDlgItem(IDC_EDIT_VALUE);
if (pEditValue)
{
pEditValue->SetLimitText(2);
}
return TRUE; // return TRUE unless you set the focus to a control
// 异常: OCX 属性页应返回 FALSE
}
```
最后,在资源文件中添加菜单项和工具栏,具体操作可以参考MFC官方文档。