MFC实现鼠标绘制基本图形(点、线、折线、矩形、圆)

1 实验目的和要求

  • 熟悉开发环境,使用MFC封装函数绘制简单图形;
  • 在OnDraw中,使用MFC封装函数(MoveTo,LineTo,Rectangle,Ellipse等)绘制点、线、矩形、椭圆/圆。
  • 最终完成鼠标绘制图形

2 基本原理

MFC是微软基础类库

3 主要仪器与设备

Window10,Visual Studio 2019

4 实验步骤/数据处理与结果

4.1点击自动生成图案版本

  • (1)设计窗口
    在这里插入图片描述

  • (2)使用类向导快速建立消息映射
    在这里插入图片描述

  • (3)点击跳转编写处理函数

①点函数

void CEXP1View::OnDrawPoint()
{
	// TODO: 在此添加命令处理程序代码
	CDC* pDC = GetDC();
	pDC->SetPixel(200, 200, RGB(255, 0, 0));
}

②直线函数

void CEXP1View::OnDrawLinear()
{
	// TODO: 在此添加命令处理程序代码
	CClientDC dc(this);
	dc.MoveTo(20, 20);
	dc.LineTo(100, 100);
}

③折线函数

void CEXP1View::OnDrawLine()
{
	// TODO: 在此添加命令处理程序代码
	CClientDC dc(this);
	POINT p[4];

	p[0].x = 400;
	p[0].y = 300;

	p[1].x = 500;
	p[1].y = 500;

	p[2].x = 300;
	p[2].y = 200;

	p[3].x = 200;
	p[3].y = 500;

	dc.Polyline(p, 4);
}}

④矩形函数

void CEXP1View::OnDrawRectangular()
{
	// TODO: 在此添加命令处理程序代码
	CClientDC dc(this);
	dc.Rectangle(500, 500, 800, 700);

⑤椭圆函数

void CEXP1View::OnDrawElliptic()
{
	// TODO: 在此添加命令处理程序代码
	CClientDC dc(this);
	dc.Ellipse(400, 300, 500,500);
}
  • (4)运行结果:
    在这里插入图片描述

4.2鼠标绘制生成

  • (1)修改CEXP1View.h,声明绘图函数需要的参数变量
#pragma once
#include<afxtempl.h>
class CEXP1View : public CView
{
protected: // 仅从序列化创建
	CEXP1View() noexcept;
	DECLARE_DYNCREATE(CEXP1View)
// 特性
public:
	CEXP1Doc* GetDocument() const;
	//起始点与终点
	CPoint m_ptStart, m_ptEnd;
	//制图类型
	UINT m_Type;
	//数组
	CArray<CPoint, CPoint> m_ptArray;

// 操作
public:
……
}
  • (2)修改4.1中(3)中的绘图函数:
void CEXP1View::OnDrawPoint()
{
	// TODO: 在此添加命令处理程序代码

	//CDC* pDC = GetDC();
	//pDC->SetPixel(200, 200, RGB(0, 0, 255));
	
	m_Type = 0;
}

void CEXP1View::OnDrawLinear()
{
	// TODO: 在此添加命令处理程序代码
	//CClientDC dc(this);
	//dc.MoveTo(20, 20);
	//dc.LineTo(100, 100);
	
	m_Type = 1;
}

void CEXP1View::OnDrawLine()
{
	// TODO: 在此添加命令处理程序代码
	//CClientDC dc(this);
	//POINT p[4];

	//p[0].x = 200;
	//p[0].y = 300;

	//p[1].x = 300;
	//p[1].y = 400;

	//p[2].x = 300;
	//p[2].y = 450;

	//p[3].x = 200;
	//p[3].y = 500;

	//dc.Polyline(p, 4);
	m_Type = 4;
}

void CEXP1View::OnDrawRectangular()
{
	// TODO: 在此添加命令处理程序代码
	/*CClientDC dc(this);
	dc.Rectangle(400, 400, 500, 500);*/
	m_Type = 2;
}

void CEXP1View::OnDrawRound()
{
	// TODO: 在此添加命令处理程序代码
	//CClientDC dc(this);
	//dc.Ellipse(200, 200, 300, 300);
	m_Type = 3;
}
  • (3)编写鼠标左键按下与抬起,以及左键双击的处理函数(这个函数是用来取消折线的绘制)

左键抬起

void CEXP1View::OnLButtonUp(UINT nFlags, CPoint point){
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CView::OnLButtonUp(nFlags, point);
	ReleaseCapture();
	//记鼠标录抬起位置
	m_ptEnd = point;
	m_ptArray[1] = point;
	/*m_ptArray.Add(point);*/
    //设备环境对象
	CClientDC dc(this);
	CDC* pDC = GetDC();
	//使用case流程语句实现跳转
	switch (m_Type){
		case 0: //点
			pDC->SetPixel(m_ptStart.x,m_ptStart.y, RGB(0, 0, 255));
			break;
		case 1: //直线
			dc.MoveTo(m_ptStart);
			dc.LineTo(m_ptEnd);
			break;
		case 2: //矩形
			dc.Rectangle(m_ptStart.x, m_ptStart.y, m_ptEnd.x, m_ptEnd.y);
			break;	
		case 3: //椭圆和圆
			dc.Ellipse(m_ptStart.x, m_ptStart.y, m_ptEnd.x, m_ptEnd.y);
			break;
		case 4: //折线
			if (mask == 1) {
				dc.Polyline(m_ptArray, 2);
			}
			else{
				m_ptArray[0].x = 0;
				m_ptArray[1].x = 0;
			}
			m_ptArray[0] = m_ptArray[1];
			break;
		default:
			break;
	}
	//释放
	ReleaseDC(pDC);
}

左键按下

void CEXP1View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	SetCapture();
	//记录按下位置的坐标
	m_ptStart = point;
	//添加按下位置到数组中
	//注意起始点的位置是x与y一样!!!
	
	mask = 1;
	if ((m_ptArray[0].x != 0 )& (m_ptArray[0].y != 0) &(m_ptArray[1].x != 0) &(m_ptArray[1].y != 0))
	{
		m_ptArray[1] = point;
	}
	else
	{
		m_ptArray[0] = point;
	}
	//m_ptArray.Add(point);
	CView::OnLButtonDown(nFlags, point);
}

左键双击

void CEXP1View::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	//用于清空数组,结束折线绘制
	mask = 0;
	m_ptArray[0].x = 0;
	m_ptArray[1].x = 0;
	CView::OnLButtonDblClk(nFlags, point);
}
  • 结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_45549336/article/details/109043530