基于C++的绘图板

//2021年3月12日12:23:33
C++项目[绘图板]
结合easyx图形库
这个是效果图
C++写的,适合刚刚入门C++,需要巩固基础语法的朋友

一.分析需求

鼠标左键:拖动即可画线
鼠标右键:清屏
鼠标滚轮:切换画笔大小
界面布局分为绘画区和工具栏(含有各种颜色按钮)
具体分为
class Window//窗口类
class Point//坐标类
class Paint//画家类
class Tools//所有空间的基类
class Canvas//Tools的派生类画布类
class Button//Tools的派生类按钮类

二.具体类的实现

Window类
class Window
{
	typedef int EW_WINDOWMODE ;					//窗口标记
public:
	Window(int w, int h, EW_WINDOWMODE flag = 0) :_width(w), _height(h)
	{
		initgraph(w, h, flag);
	}
	~Window()
	{
		closegraph();
	}
	int exec()
	{
		return system("pause");
	}
public:
	void setWindowTitle(const char * title)
	{
		SetWindowText(GetHWnd(), title);
	}
	static int getW()
	{
		return getwidth();
	}
	static int getH()
	{
		return getheight();
	}
private:
	int _width;
	int _height;
};
Point类
class Point
{
public:
	Point() {};
	Point(int x, int y) :x(x), y(y) {};
	int x;
	int y;

	static Point ZERO;
};
Point Point::ZERO = Point(0, 0);//因为本程序中重复用到原点,即(0,0),这里直接定义为静态变量,便于调用
Paint类
class Paint
{
public:
	static void drawRect(const Point& p, int w, int h, COLORREF color = getfillcolor())
	{
		setfillcolor(color);
		solidrectangle(p.x, p.y, p.x+w, p.y+h);
	}
	static void drawLine(const Point& p1, const Point& p2, COLORREF color = getlinecolor(),int lineSize = 1)
	{
		setlinestyle(PS_COSMETIC, lineSize);
		setlinecolor(color);
		line(p1.x, p1.y, p2.x, p2.y);
	}
	static void drawText(int x, int y, const char* text,COLORREF color = gettextcolor(),int textSize = 26)
	{
		setbkmode(TRANSPARENT);
		settextcolor(color);
		settextstyle(textSize, 0,"黑体");
		outtextxy(x, y, text);
	}
	static void drawText(int x, int y, int text, COLORREF color = gettextcolor(), int textSize = 26)
	{
		char lineSizeStr[10] = "";
		sprintf_s(lineSizeStr, "%d", text);
		Paint::drawText(x, y, lineSizeStr, color, textSize);
	}
	static void drawCircle(const Point& p,int w,int h, COLORREF color = getfillcolor())//画椭圆,即矩形的内接圆
	{
		setfillcolor(color);
		solidellipse(p.x, p.y, p.x + w, p.y + h);
	}
};
Tools类
class Tools
{
public:
	Tools() {};
	Tools(int x, int y, int w, int h)
		:leftTop(x, y), width(w), height(h)
	{
	}
	//鼠标是否在控件上
	bool isIn(const Point& p)
	{
		if (p.x >= leftTop.x && p.x <= leftTop.x + width &&
			p.y >= leftTop.y && p.y <= leftTop.y + height)
		{
			return true;
		}
		return false;
	}

	//处理鼠标消息,需要继承自己实现
	bool ProcessMsg(MOUSEMSG& msg)
	{
		return 0;
	}

	Point leftTop;
	int width;
	int height;
};
Canvas类
class Canvas :public Tools
{
public:
	Canvas() {}
	Canvas(int x, int y, int w, int h) 
		:Tools(x, y, w, h),color(BLACK),lineSize(1)
	{
		this->isDown = false;
		this->begPos = Point(0, 0);
	}
	bool ProcessMsg(MOUSEMSG& msg)
	{
		switch (msg.uMsg)
		{
		case WM_LBUTTONDOWN:
			if (isIn(Point(msg.x,msg.y)))
			{
				isDown = true;
				begPos = Point(msg.x, msg.y);
			}
			break;
		case WM_LBUTTONUP:
			isDown = false;
			break;
		case WM_MOUSEWHEEL:						//滚轮调整字体大小
			lineSize = msg.wheel > 0 ? lineSize + 1 : lineSize - 1;
			if (lineSize <= 0)
			{
				lineSize = 1;
			}
			break;
		case WM_MOUSEMOVE:						//画线
			if (isDown)
			{
				if (isIn(begPos) && isIn(Point(msg.x, msg.y)))		// 起始点和结束点都在区域内
				{
					Paint::drawLine(begPos, Point(msg.x, msg.y), color, lineSize);
				}
				begPos = Point(msg.x, msg.y);
			}
			break;
		case WM_RBUTTONDOWN:					//清屏
			Paint::drawRect(Point::ZERO, Window::getW()-100, Window::getH(), WHITE);				//绘图区域
			break;
		}
		return false;
	}
public:
	int getLineSize()
	{
		return lineSize;
	}
	void setColor(COLORREF color)
	{
		this->color = color;
	}
private:
	int lineSize;	//线条宽度
	COLORREF color;	//线条颜色

	bool isDown;	//鼠标是否按下
	Point begPos;	//记录上一个点的坐标
};
Button类
class Button:public Tools
{	
public:
	enum ButtonStyle { CIRCLE, RECT };
	Button():style(ButtonStyle::CIRCLE) {}
	Button(int x, int y, int w, int h, ButtonStyle style = ButtonStyle::CIRCLE)
		:Tools(x, y, w, h), style(style)
	{
		isClick = false;
	}
	bool ProcessMsg(MOUSEMSG& msg, Canvas& canvas)
	{
		switch (msg.uMsg)
		{
		case WM_LBUTTONDOWN:
			if (isIn(Point(msg.x,msg.y)))
			{
				printf("leftTop(%d,%d)  %#X \n",leftTop.x,leftTop.y, color);
				canvas.setColor(color);
				isClick = true;
			}
			break;
		case WM_LBUTTONUP:
			isClick = false;
			break;
		}
		if (style == ButtonStyle::CIRCLE)
		{
			Paint::drawCircle(leftTop, width, height, color);
		}
		else if (style == ButtonStyle::RECT)
		{
			Paint::drawRect(leftTop, width, height, color);
		}
		
		return false;
	}
public:
	void setPos(const Point&p)
	{
		this->leftTop = p;
	}
	void setSize(int w,int h)
	{
		this->width = w;
		this->height = h;
	}
	void setColor(COLORREF color)
	{
		this->color = color;
	}
	void setStyle(ButtonStyle style)
	{
		this->style = style;
	}
private:
	bool isClick;	//按钮是否被点击
	COLORREF color;	//按钮颜色
	ButtonStyle style;	//按钮样式
};

三.主函数

int main()
{
	Window w(1100, 768,EW_SHOWCONSOLE);
	w.setWindowTitle("绘图板");
	Paint::drawRect(Point::ZERO, w.getW(), w.getH(), WHITE);				//绘图区域
	Paint::drawRect(Point(w.getW()-100, 0), w.getW(), w.getH(), 0xEFEFEF);	//工具栏
	Canvas canvas(0, 0, w.getW()-100, w.getH());

	//颜色按钮
	Button btns[9];
	for (int i = 0; i < 9; i++)
	{
		btns[i].setSize(50, 50);
		btns[i].setPos(Point(Window::getW() - 100 + 26, 50 + i * 60));
		btns[i].setColor(RGB(rand() % 256, rand() % 256, rand() % 256));
		//btns[i].setStyle(Button::RECT);
	}


	BeginBatchDraw();
	while (true)
	{
		MOUSEMSG msg = GetMouseMsg();
		canvas.ProcessMsg(msg);

		Paint::drawRect(Point(1050, 700), 50, 50, 0xEFEFEF);
		Paint::drawText(1000, 700, "字体大小:", BLACK,15);
		Paint::drawText(1080,700, canvas.getLineSize(),BLACK,15);
		for (int i = 0; i < 9; i++)
		{
			btns[i].ProcessMsg(msg, canvas);
		}
		FlushBatchDraw();
	}

	return w.exec();
}

这是版本1.0,随后我还会补充新的功能进去(橡皮擦,取色器,快速画形状等等)
最后感谢顽石哥!!!

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值