vc++大作业 mfc简单绘图程序

大作业要求:

一个绘图程序
使用VC++,MFC 能绘制至少4种图形;具备增,删、改、(查,可选,增加属性功能)等功能能没量填充,描边图形可保存、打开。

实在太忙了,但是还有人催我更这个。

分享结果可达到作业最低要求,具体实现如下:


1、创建项目

创建完成。

2、创建你自己的形状类

(1)创建头文件

class Yjjj0310Shape : public CObject
{
	DECLARE_SERIAL(Yjjj0310Shape)
private:
	double up;
	double down;
	double left;
	double right;
	int body;
	COLORREF col_area;
	COLORREF col_line;
	bool isOk;
public:
	Yjjj0310Shape();																									// 无参构造
	Yjjj0310Shape(double up, double down, double left, double right, int body, COLORREF col_area, COLORREF col_line);	// 构造函数
	virtual void Serialize(CArchive& ar);																			// 序列化函数
	void Draw(CDC* pDC);																							// 绘图函数
	void IsSelect(double x, double y);																				// 判断选择函数
	bool CD();																										// 返回选择状态函数
	void NoSelect();																								// 取消选择状态函数
	void MoveUP();																									// 向上移动
	void MoveDOWN();																								// 向下移动
	void MoveLEFT();																								// 向左移动
	void MoveRight();																								// 向右移动
	double GetUP();																									// 返回up值
	double GetDPWN();																								// 返回down值
	double GetLEFT();																								// 返回left值
	double GetRIGHT();																								// 返回right值
	int GetBODY();																									// 返回body值
	COLORREF GetCOL_AREA();																							// 返回填充颜色
	COLORREF GetCOL_LINE();																							// 返回描边颜色
	void ad();																										// 个数+
	void da();																										// 个数-
};

(2)创建源文件

#include "pch.h"
#include "windef.h"
#include "Yjjj0310Shape.h"

IMPLEMENT_SERIAL(Yjjj0310Shape, CObject, 1)
Yjjj0310Shape::Yjjj0310Shape() {}
Yjjj0310Shape::Yjjj0310Shape(double x, double y, double m, double n, int z, COLORREF c, COLORREF c0) // 构造
{
	up = x;
	down = y;
	left = m;
	right = n;
	body = z;
	col_area = c;
	col_line = c0;
	isOk = false;
}

void Yjjj0310Shape::Serialize(CArchive& ar)

{
	if (ar.IsStoring()) { //序列化,保存信息
		ar << up << down << left << right << body << col_area << col_line << isOk;
	}
	else //反序列化,读取信息
	{
		ar >> up >> down >> left >> right >> body >> col_area >> col_line >> isOk;
	}

}

void Yjjj0310Shape::Draw(CDC* pDC) // 绘画
{
	CBrush NBrush(col_area);
	CPen NPen(PS_SOLID, 0, col_line);
	pDC->SelectObject(NBrush);
	pDC->SelectObject(NPen);
	switch (body)
	{
	case 1:
	{
		pDC->MoveTo(left, up);
		pDC->LineTo(right, down);
		break;
	}
	case 2:
	{
		pDC->Ellipse(left, down, right, up);
		break;
	}
	case 3:
	{
		pDC->Rectangle(left, down, right, up);
		break;
	}
	case 4:
	{
		double r = sqrt(pow(up - down, 2) + pow(right - left, 2)) / 2;
		double o_x = (left + right) / 2, o_y = (up + down) / 2;
		pDC->Ellipse(o_x + r, o_y + r, o_x - r, o_y - r);
		break;
	}
	}
}
void Yjjj0310Shape::IsSelect(double x, double y) // 选择
{
	switch (body)
	{
	case 1: // 直线
	{
		double k = (up - down) / (left - right);
		double b = up - k * left;
		if (y == k * x + b)
			isOk = true;
		break;
	}
	case 2: // 椭圆
	{
		double a = abs(right - left) / 2, b = abs(up - down) / 2;
		double c, Clx, Cly, Crx, Cry, o_l;
		if (a > b)
		{
			c = sqrt(pow(a, 2) - pow(b, 2));
			Clx = (left + right) / 2 - c, Crx = (left + right) / 2 + c, Cly = Cry = (up + down) / 2;
			o_l = sqrt(pow(x - Clx, 2) + pow(y - Cly, 2)) + sqrt(pow(x - Crx, 2) + pow(y - Cry, 2));
			if (o_l <= 2 * a)
				isOk = true;
		}
		else
		{
			c = sqrt(pow(b, 2) - pow(a, 2));
			Cly = (up + down) / 2 - c, Cry = (up + down) / 2 + c, Clx = Crx = (left + right) / 2;
			o_l = sqrt(pow(x - Clx, 2) + pow(y - Cly, 2)) + sqrt(pow(x - Crx, 2) + pow(y - Cry, 2));
			if (o_l <= 2 * b)
				isOk = true;
		}
		break;
	}
	case 3: // 矩形
	{
		if (y >= up && y <= down && x >= left && x <= right)
			isOk = true;
		break;
	}
	case 4: // 正圆
	{
		double r = sqrt(pow(up - down, 2) + pow(right - left, 2)) / 2;
		double o_x = (left + right) / 2, o_y = (up + down) / 2;
		double o_l = sqrt(pow(x - o_x, 2) + pow(y - o_y, 2)) / 2;
		if (o_l <= r)
			isOk = true;
		break;
	}
	}

}

bool Yjjj0310Shape::CD() // 返回选中状态
{
	return isOk;
}

void Yjjj0310Shape::NoSelect() // 取消选中状态
{
	isOk = false;
}

void Yjjj0310Shape::MoveUP()
{
	up -= 10;
	down -= 10;
}

void Yjjj0310Shape::MoveDOWN()
{
	up += 10;
	down += 10;
}

void Yjjj0310Shape::MoveLEFT()
{
	left -= 10;
	right -= 10;
}

void Yjjj0310Shape::MoveRight()
{
	left += 10;
	right += 10;
}

double Yjjj0310Shape::GetUP() { return up; }
double Yjjj0310Shape::GetDPWN() { return down; }
double Yjjj0310Shape::GetLEFT() { return left; }
double Yjjj0310Shape::GetRIGHT() { return right; }
int Yjjj0310Shape::GetBODY() { return body; }
COLORREF Yjjj0310Shape::GetCOL_AREA() { return col_area; }
COLORREF Yjjj0310Shape::GetCOL_LINE() { return col_line; }
void Yjjj0310Shape::ad() { up++; }
void Yjjj0310Shape::da() { up--; }

3、Doc类

(1)头文件

(2)源文件

	

    for (int i = 0; i < ShapeArray.GetSize(); ++i)
	{
		Yjjj0310Shape* pShape = ShapeArray.GetAt(i);
		delete pShape;
	}

截图上有点错,以下面为准

	if (ar.IsStoring())
	{
		// TODO: 在此添加存储代码

		for (int i = 0; i < ShapeArray.GetSize(); i++)
		{
			Yjjj0310Shape* CS = ShapeArray[i];
			CS->Serialize(ar);

		}

	}
	else
	{
		// TODO: 在此添加加载代码
		ShapeArray.RemoveAll(); // 清空数组
		Yjjj0310Shape* CS = new Yjjj0310Shape();
		CS->Serialize(ar);
		ShapeArray.Add(CS); // 添加元素到数组
		int num = ShapeArray[0]->GetUP();
		for (int i = 0; i < num; i++)
		{
			Yjjj0310Shape* CS2 = new Yjjj0310Shape();
			CS2->Serialize(ar);
			ShapeArray.Add(CS2); // 添加元素到数组
		}
	}

4、View类

(1)头文件

int num = 0;
	bool ff = false;
	double m_u;
	double m_d;
	double m_l;
	double m_r;
	double m_x;
	double m_y;
	COLORREF col_in = RGB(0, 0, 0);
	COLORREF col_out = RGB(0, 0, 0);
	Yjjj0310Shape* CS;
	void DeleteSelect(double x, double y); // 删除选择函数
	Yjjj0310Shape* Choose(double x, double y); // 选择函数

(2)添加按钮

完事保存一下

(3)源文件

如果没有或者少几个,重新打开VS

完成就OK了。(12.27更新,这里右边少了一个消息,WM_CREATE这个消息也要添加)

void CYjjj0310View::CreateLine()
{
	// TODO: 在此添加命令处理程序代码
	num = 1;

}


void CYjjj0310View::CreateCircle()
{
	// TODO: 在此添加命令处理程序代码
	num = 2;

}


void CYjjj0310View::CreateRectangle()
{
	// TODO: 在此添加命令处理程序代码
	num = 3;

}


void CYjjj0310View::CreateRCircle()
{
	// TODO: 在此添加命令处理程序代码
	num = 4;

}


void CYjjj0310View::ChooseColor()
{
	// TODO: 在此添加命令处理程序代码
	CColorDialog dlg;

	dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;

	if (IDOK == dlg.DoModal())
	{
		col_in = dlg.m_cc.rgbResult;    // 将 dlg.m_cc.rgbResult 获取到的颜色对话框中的颜色保存到变量 m_clr 中
	}
}


void CYjjj0310View::ChooseColorOut()
{
	// TODO: 在此添加命令处理程序代码
	CColorDialog dlg;

	dlg.m_cc.Flags |= CC_RGBINIT | CC_FULLOPEN;

	if (IDOK == dlg.DoModal())
	{
		col_out = dlg.m_cc.rgbResult;    // 将 dlg.m_cc.rgbResult 获取到的颜色对话框中的颜色保存到变量 m_clr 中
	}
}


void CYjjj0310View::OnFileOpen()
{
	// TODO: 在此添加命令处理程序代码
	CFileDialog dlg(TRUE, _T("dat"), NULL, OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, _T("Data Files (*.dat)|*.dat|All Files (*.*)|*.*||"), this);

	if (dlg.DoModal() == IDOK) {
		CFile file(dlg.GetPathName(), CFile::modeRead);
		CArchive ar(&file, CArchive::load);

		GetDocument()->Serialize(ar); // 调用文档类的序列化方法

		ar.Close();
		file.Close();

		// 加载完数据后,如果需要更新视图,可以在此处进行刷新操作
		Invalidate(NULL); // 重新绘制视图
	}
}


void CYjjj0310View::OnFileSave()
{
	// TODO: 在此添加命令处理程序代码
	CFileDialog dlg(FALSE, _T("dat"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Data Files (*.dat)|*.dat|All Files (*.*)|*.*||"), this);

	if (dlg.DoModal() == IDOK) {
		CFile file(dlg.GetPathName(), CFile::modeCreate | CFile::modeWrite);
		CArchive ar(&file, CArchive::store);

		GetDocument()->Serialize(ar); // 调用文档类的序列化方法

		ar.Close();
		file.Close();
	}
}


void CYjjj0310View::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nChar)
	{
	case VK_DELETE:
	{
		DeleteSelect(m_x, m_y);
		InvalidateRect(NULL);
		break;
	}
	case VK_CONTROL:
	{
		CS = Choose(m_x, m_y);
		ff = true;
		break;
	}
	case VK_UP:
	{
		if (ff)
		{
			CS->MoveUP();
			CS->NoSelect();
			InvalidateRect(NULL);

		}
		break;
	}
	case VK_DOWN:
	{
		if (ff)
		{
			CS->MoveDOWN();
			CS->NoSelect();
			InvalidateRect(NULL);
		}
		break;
	}
	case VK_LEFT:
	{
		if (ff)
		{
			CS->MoveLEFT();
			CS->NoSelect();
			InvalidateRect(NULL);
		}
		break;
	}
	case VK_RIGHT:
	{
		if (ff)
		{
			CS->MoveRight();
			CS->NoSelect();
			InvalidateRect(NULL);
		}
		break;
	}
	}
	CView::OnKeyDown(nChar, nRepCnt, nFlags);
}


void CYjjj0310View::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	switch (nChar)
	{
	case VK_CONTROL:
	{
		ff = false;
		break;
	}

	}
	CView::OnKeyUp(nChar, nRepCnt, nFlags);
}


void CYjjj0310View::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_u = point.y;
	m_l = point.x;
	CView::OnLButtonDown(nFlags, point);
}


void CYjjj0310View::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_d = point.y;
	m_r = point.x;
	if (num != 0)
	{
		CYjjj0310Doc* pDoc = GetDocument();
		Yjjj0310Shape* pShape;
		if (num == 1)
			pShape = new Yjjj0310Shape(m_u, m_d, m_l, m_r, num, col_in, col_out);
		else
			pShape = new Yjjj0310Shape(min(m_u, m_d), max(m_u, m_d), min(m_l, m_r), max(m_l, m_r), num, col_in, col_out);
		pDoc->ShapeArray.Add(pShape);
		pDoc->ShapeArray[0]->ad();
		InvalidateRect(NULL);
	}
	CView::OnLButtonUp(nFlags, point);
}


void CYjjj0310View::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	m_x = point.x;
	m_y = point.y;
	CView::OnMouseMove(nFlags, point);
}


int CYjjj0310View::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CView::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	Yjjj0310Shape* pShape = new Yjjj0310Shape(0, 0, 0, 0, 99999, col_in, col_out);
	CYjjj0310Doc* pDoc = GetDocument();
	pDoc->ShapeArray.Add(pShape);
	return 0;
}

void CYjjj0310View::DeleteSelect(double x, double y)
{
	CYjjj0310Doc* pDoc = GetDocument();
	for (int i = 0; i < pDoc->ShapeArray.GetSize(); ++i)
	{
		Yjjj0310Shape* pShape = pDoc->ShapeArray.GetAt(i);
		pShape->IsSelect(x, y);
		if (pShape->CD())
		{
			pDoc->ShapeArray.RemoveAt(i);
			pDoc->ShapeArray[0]->da();
		}
	}
}
Yjjj0310Shape* CYjjj0310View::Choose(double x, double y)
{
	CYjjj0310Doc* pDoc = GetDocument();
	Yjjj0310Shape* pShape = NULL;
	for (int i = 0; i < pDoc->ShapeArray.GetSize(); ++i)
	{
		pShape = pDoc->ShapeArray.GetAt(i);
		pShape->IsSelect(x, y);
	}
	return pShape;
}
void CYjjj0310View::OnDraw(CDC* pDC)
{
	CYjjj0310Doc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;

	// TODO: 在此处为本机数据添加绘制代码
	for (int i = 0; i < pDoc->ShapeArray.GetSize(); ++i)
	{
		Yjjj0310Shape* pShape = (pDoc->ShapeArray).GetAt(i);
		pShape->Draw(pDC);
	}
}

效果大概这样。(12.27更新,如果遇到abs()函数错误的情况,可以将那一句换成下面的,应该没有其他错误了)

double a = (right - left) / 2, b = (up - down) / 2;
a = a > 0 ? a : a * -1;
b = b > 0 ? b : b * -1;

结束,运行即可,本学期VC++课程作业应该更完了,上次留的几道题我做了但是他没让交,,,,。

完结撒花,感谢陪伴,如果以后有其他需求私聊我或者评论也行。

  • 16
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值