C++ easyx大一期末作业利器

这篇具有很好参考价值的文章主要介绍了C++ easyx大一期末作业利器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

yNodeGUI_v2.0

紧跟着1.0版本的完成,又到了激动人心的C++期末作业了。(上学期是C语言的),这学期,我仅仅改了一点点上学期的期末作业,然后很轻松的水…啊不,完成了这次的期末作业。

所以,大家一定要注重复用!!! 很快乐。

这个改一改就是你的…啊不是,我是说基于框架进行开发(滑稽)

  1. 定位:针对于简易C++管理系统开发,提供简单的基于easyx的GUI固定渲染和简单的无限层级菜单解决方案

  2. 使用基础:有一定面向对象基础和IMGUI使用经验,或者easyx的使用经验

  3. 使用方式:仅在VisualStudio导入yNodeGUIFrameowrk目录下的文件到项目内,并在easyx官网(https://easyx.cn/ ).安装easyx(仅支持VisualStudio),在项目设置里设置多字符集的编码!!!

  4. 打包方式: 将VS切换到Release分支,在项目Release设置内,代码生成选择MT,即可脱离C++和easyx环境运行,如果在过程中加载了资源,请在打包后的目录里相对exe文件进行补充,框架不支持VS的Resources

功能

1.现成的GUI组件
包含按钮,缩放框,网格,文本,图片等多种组件

2.极低学习成本
框架内实现了NodeGUI,无限层级菜单管理方便,同时简单的机制容易上手

4.高效的菜单管理器
将菜单抽象为N叉树,能高效处置多级深度菜单,自动实现全流程的固定形式菜单渲染

API使用

0.引入头文件

#include"yNodeGUI.h"

1.Main函数内创建图形界面

	//创建画布
	Canvas canvas = { 1000,600,90, RGB(255,255,255) }; 
	//展示GUI并阻塞程序
	canvas.Show(OnStart, OnUpdate, OnGUI,true); 

2.在Start内定义菜单节点

  	//创建根节点和节点菜单管理器
	Node* root = new Node();
	menu = new Menu(root, &canvas);

	//主菜单节点
	Node* m1 = new Node(root, "课程信息录入");
	Node* m2 = new Node(root, "课程信息浏览", browsing, true, fresh);
	Node* m3 = new Node(root, "课程信息查询", queryshow, true, fresh_query);
	Node* m4 = new Node(root, "学生自由选课");
	Node* m6 = new Node(root, "安全退出系统", exit_system, true);

	//主菜单选项1  一级菜单节点
	Node* x1 = new Node(m1, "录入课程信息", input, true);
	Node* x2 = new Node(m1, "修改课程信息", set_course, true);
	Node* x3 = new Node(m1, "删除课程信息", del_course, true);
	Node* x4 = new Node(m1, "返回", last_menu, true);

	//主菜单选项4  一级菜单节点
	Node* n1 = new Node(m4, "自由选课", choose, true);
	Node* n2 = new Node(m4, "已选课程查看", view_selected, true, fresh_selected);
	Node* n3 = new Node(m4, "返回", last_menu, true);
  1. 注册和渲染 /这些内容可以在不同的位置实现,具体请看Core.cpp文件内的示例
	//注册重绘机制
	//注册控件
	canvas.Env(0).Register(id, btn);
	//绘制控件
	canvas.Env(0).Draw(id);

demo展示 图书馆管理系统

demo仓库(点击了解更多信息):https://github.com/yueh0607/yNodeGUI_Sample_

C++ easyx大一期末作业利器,c++,数据库,java

easyx是什么?

easyx是一个简单的图形库,能让你从小黑窗转变成图形界面!!!
从此高人一等,赢取白富美,走上人生巅峰。
所以进入官网,硕大的下载按钮,让我局促不安。慌忙之中点击下载,傻瓜式的安装流程简单的让我不知所措。(事情真的这么简单吗?是的!)
easyx.cn
C++ easyx大一期末作业利器,c++,数据库,java

确定一些基本的结构

为了表示方便,我写了自己的Vector2,写了自己的Rect,写了自己Object基类,写了GUIComponent作为可图形化对象的基类

Object的唯一作用就是让每个对象有一个唯一的ID文章来源地址https://www.toymoban.com/news/detail-609085.html

#pragma region 基本结构
//二维向量
typedef struct
{
	int x;
	int y;
	
} Vector2;


//矩形,包含左上角,右下角,长宽等确定矩形的基本要素
typedef struct
{
	Vector2 origin;
	Vector2 end;
	Vector2 center;
	int width;
	int height;
} Rect;


//实例基类,框架内所有需要实例化的类都需要继承本类,分配唯一ID
class Object
{
private:
	static int instanceId; //全局实例id位置
	static set<int> ids;  //已被占用的实例id
	int instance_id;  //当前实例id
	//分配一个与其他实例不冲突的ID
	static int AssignInstanceID()
	{
		do { if (instanceId == INT_MIN)instanceId == INT_MAX; instanceId--; } while (ExistID(instanceId));
		RegisterId(instanceId);
		return instanceId;
	}
	//检测是否存在ID
	static bool ExistID(int id)
	{
		return ids.find(id) != ids.end();
	}
	//注册一个ID
	static void RegisterId(int id)
	{
		ids.insert(id);
	}
public:
	//实例创建时分配ID
	Object()
	{
		instance_id = AssignInstanceID();  //分配一个新的实例ID
	}  
	//实例销毁回收ID
	~Object()
	{
		ids.erase(instance_id);
	}
	//获取当前实例的ID并返回
	int InstanceId()
	{
		return instance_id;
	}
	
};
int Object::instanceId = INT_MAX;
set<int> Object::ids;

//GUI接口,所有GUI组件继承该接口 
class GUIComponent :public Object
{
public:
	//负责GUI渲染
	virtual void OnGUI() = 0;
	//负责消息处理与事件响应
	virtual void OnEvent(ExMessage* message) = 0;
};

搭建Canvas和游戏循环

//画布类,负责画布生命维护,不实现具体逻辑
class Canvas :public Object
{
private:
#pragma region 信息字段
	int width;//宽度
	int height;//高度
	int fps = 60;//帧率
	int frameStart = 0;//当前帧开始时间
	int frameTime;//每帧时长
	bool life = true;//是否存活
	int deltaTime;//上一帧消耗的时间 ms
	COLORREF bgc;//背景色
	ExMessage message;//消息临时内存
	HWND window;//窗口句柄
#pragma endregion
#pragma region 环境与队列
	//GUI注册环境
	map<int, GUIComponent*> gui0;
	map<int, GUIComponent*> gui1;
	map<int, GUIComponent*> gui2;
	map<int, GUIComponent*> gui3;
	map<int, map<int, GUIComponent*>> envs{ { 0,gui0 }, {1,gui1}, {2,gui2},{3,gui3} };

	//GUI临时回收环境
	vector<GUIComponent*> collection0;
	vector<GUIComponent*> collection1;
	vector<GUIComponent*> collection2;
	vector<GUIComponent*> collection3;
	map<int, vector<GUIComponent*>> cenvs{ {0,collection0},{1,collection1},{2,collection2},{3,collection3} };

	//渲染队列/消息队列
	queue <GUIComponent* > renderQueue;
	queue<GUIComponent*> eventQueue;

	//当前环境ID
	int envid = 0;
#pragma endregion
#pragma region 队列化GUI处理
	//渲染GUI并清空队列
	void RenderAll()
	{
		while (!renderQueue.empty())
		{
			renderQueue.front()->OnGUI();
			renderQueue.pop();
		}
	}
	//处理GUI消息并清空队列
	void BroadcastAll(ExMessage* message)
	{
		while (!eventQueue.empty())
		{
			eventQueue.front()->OnEvent(message);
			eventQueue.pop();
		}
	}
#pragma endregion
protected:
#pragma region 生命周期
	//开始时调用
	void (*OnStart)(Canvas& canvas);
	//GUI渲染时调用
	void (*OnGUI)(Canvas& canvas);
	//帧更新时调用
	void (*OnUpdate)(Canvas& canvas);
#pragma endregion
public:
#pragma region 画布属性-ReadOnly
	//中心点
	Vector2 Center() { return { width / 2,height / 2 }; }
	//宽度
	int Width() { return width; }
	//高度
	int Height() { return height; }
	//背景色
	COLORREF BackgroundColor() { return bgc; }
	//画布是否存活
	bool Life() { return life; }
	//每帧时间
	int FrameTime() { return frameTime; }
	//每秒帧数
	int FrameCount() { return fps; }
	//上一帧的时间,ms单位
	int DeltaTime() { return deltaTime; }
	HWND* Window()
	{
		return &window;
	}
#pragma endregion

#pragma region 构造与析构
	//传入xy长度,秒帧数,背景色
	Canvas(int xLen, int yLen, int frame = INT_MAX, COLORREF color = WHITE)
	{

		width = xLen;
		height = yLen;
		bgc = color;
		fps = frame;
		frameTime = 1000 / fps;
		deltaTime = 0;

		
	}
#pragma endregion

#pragma region GUI操作
	//切换环境并返回引用
	Canvas& Env(int env)
	{
		assert(env >= 0 && env < 4);
		envid = env;
		return *this;
	}
	//渲染某个已注册GUI
	void Draw(int id)
	{
		renderQueue.push(envs[envid][id]);
		eventQueue.push(envs[envid][id]);
	}
	//检查Canvas释放包含某个GUI
	bool ContainsKey(int id)
	{
		return envs[envid].find(id) != envs[envid].end();
	}
	//注册GUI到当前环境
	void Register(int id, GUIComponent* gui)
	{
		envs[envid].insert({ id,gui });
	}
	//移除某个GUI的注册,但不释放内存
	void RemoveGUI(int id)
	{
		envs[envid].erase(id);
	}
	//从Canvas获取某个GUI并返回指针,如果不存在则报错
	GUIComponent* GetGUI(int id)
	{
		return envs[envid][id];
	}
	//释放某个id的GUI所占用的内存并解除注册
	void ReleaseGUI(int id)
	{
		delete envs[envid][id];
		RemoveGUI(id);
	}
	//把GUI引用收集到Canvas内,作为一个Collection统一管理,失去单一管理权限
	void Collect(GUIComponent* gui1, GUIComponent* gui2 = nullptr, GUIComponent* gui3 = nullptr, GUIComponent* gui4 = nullptr)
	{
		cenvs[envid].push_back(gui1);
		if (gui2 != nullptr) cenvs[envid].push_back(gui2);
		else if (gui3 != nullptr) cenvs[envid].push_back(gui3);
		else if (gui4 != nullptr) cenvs[envid].push_back(gui4);
	}
#pragma endregion

#pragma region 批量释放资源

	//释放GUI所有的内存,并清除注册
	void ReleaseAllGUIS()
	{
		for (auto& i : envs[envid])
		{
			delete i.second;
		}
		envs[envid].clear();
	}
	//只从Canvas内移除注册
	void RemoveAllGUIS()
	{
		envs[envid].clear();
	}
	//只在Canvas内移除Collection的注册
	void RemoveAllCollections()
	{
		cenvs[envid].clear();
	}
	//释放所有Collection的内存,并清除注册
	void ReleaseAllCollections()
	{
		for (auto& i : cenvs[envid])
		{
			delete i;
		}
		cenvs[envid].clear();
	}
	//移除所有Collection和GUI的注册
	void RemoveAll()
	{
		RemoveAllGUIS();
		RemoveAllCollections();
	}
	//释放所有Coloection和GUI的内存
	void ReleaseAll()
	{
		ReleaseAllGUIS();
		ReleaseAllCollections();
	}

#pragma endregion

#pragma region 生命周期干涉操作
	//画布初始化
	void Show(void start(Canvas& canvas), void update(Canvas& canvas), void ongui(Canvas& canvas),bool showConsole=false)
	{



		//生命周期
		OnStart = start;
		OnUpdate = update;
		OnGUI = ongui;

		//设置背景颜色
		window = showConsole?initgraph(width, height, EW_SHOWCONSOLE): initgraph(width, height);
		setbkcolor(bgc);
		cleardevice();

		//生命周期:Start
		OnStart(*this);

		while (life && IsWindow(window))
		{
			//帧开始计时
			frameStart = GetTickCount();
			//渲染与消息队列(将生命周期GUI和持久化渲染GUI添加到渲染队列和消息队列)
			OnGUI(*this);

			//清空画布开始渲染
			BeginBatchDraw();
			cleardevice();
			RenderAll();
			EndBatchDraw();

			//生命周期--消息分发
			if (peekmessage(&message))
			{
				BroadcastAll(&message);
				message = {};
			}
			else while (!eventQueue.empty()) eventQueue.pop();


			//生命周期--帧更新
			OnUpdate(*this);

			//帧数控制
			deltaTime = GetTickCount() - frameStart;
			if (frameTime - deltaTime > 0)
			{
				Sleep(frameTime - deltaTime);
			}
			//打印帧信息
			//cout << "Frame:" << count++ << "  " << "FrameTime:" << frameTime << "  " << "DeltaTime:" << deltaTime<<"  SleepTime:"<< frameTime - deltaTime << endl;
		}
		closegraph();
	}
	//关闭画布
	void Close()
	{
		life = false;
	}
#pragma endregion
};
#pragma endregion

写点组件

#pragma region 矩形操作

//通过四个边界坐标创建矩形
inline Rect createRectbyPoint(int left, int top, int right, int bottom)
{
	Rect rect;
	rect.center = { (right + left) / 2,(top + bottom) / 2 };
	rect.origin = { left,top };
	rect.end = { right,bottom };
	rect.width = right - left;
	rect.height = bottom - top;
	return rect;
}
//通过中心点和长宽创建矩形
inline Rect createRectbyCenter(int x, int y, int width, int height)
{
	Rect rect;
	rect.center = { x,y };
	rect.origin = { x - width / 2,y - height / 2 };
	rect.end = { x + width / 2,y + height / 2 };
	rect.width = width;
	rect.height = height;
	return rect;
}
//通过中心点和长宽创建矩形创建矩形
inline Rect createRectbyCenter(Vector2 center, int width, int height)
{
	Rect rect;
	rect.center = center;
	rect.origin = { center.x - width / 2,center.y - height / 2 };
	rect.end = { center.x + width / 2,center.y + height / 2 };
	rect.width = width;
	rect.height = height;
	return rect;
}
//移动矩形位置到新的矩形并返回,不改变原矩形
inline Rect moveRect(Vector2 offset, Rect rect)
{
	return createRectbyPoint(rect.origin.x + offset.x, rect.origin.y + offset.y, rect.end.x + offset.x, rect.end.y + offset.y);
}
//判断某位置是否在矩形内
inline bool inRect(int x, int y, const Rect* rect)
{
	if (x >= rect->origin.x && x <= rect->end.x && y >= rect->origin.y && y <= rect->end.y)
	{
		return true;
	}
	return false;
}
#pragma endregion

#pragma region GUI组件

//可以缩放的方形边框
class LineBox :public GUIComponent
{
	Rect rect;  //原矩形大小,也是响应事件的矩形大小
	Rect temp;  //缩放后矩形大小
	COLORREF color;  //线框颜色
	bool state = false;  //当前是否缩放

public:

	void OnGUI() override
	{
		setlinecolor(color);  //设置线颜色
		if (!state)   
			rectangle(rect.origin.x, rect.origin.y, rect.end.x, rect.end.y);  //绘制原线框
		else rectangle(temp.origin.x, temp.origin.y, temp.end.x, temp.end.y);  //绘制放大后线框

	}
	void OnEvent(ExMessage* message) override
	{
		if (inRect(message->x, message->y, &rect))  //如果鼠标在原线框范围内,则修改状态
		{
			state = true;
		}
		else
		{
			state = false;
		}
	}
	//形参:原线框矩形,线框颜色,缩放长度
	LineBox(Rect rct, COLORREF c, int s = 10)
	{
		rect = rct;
		color = c;
		temp = createRectbyCenter(rect.center, rect.width + s, rect.height + s);
	}
};
//允许加载纯色和图片的矩形
class Image : public GUIComponent
{
	IMAGE img;  //图片数据
	bool pureColor = false;   //是否为纯色图片
	COLORREF color;  //如果是纯色图片,颜色是什么
public:
	Rect rect;  //图片的矩形
	void OnGUI() override
	{
		if (!pureColor)putimage(rect.origin.x, rect.origin.y, &img);  //如果不是纯色,则渲染到屏幕的是图片
		else  //如果是纯色
		{
			setfillcolor(color);  //设置填充颜色
			fillrectangle(rect.origin.x, rect.origin.y, rect.end.x, rect.end.y);  //填充矩形并渲染到屏幕
		}
	}
	void OnEvent(ExMessage* message) override{}
	Image(Rect rct, string path)
	{
		color = NULL;
		pureColor = false;
		rect = rct;
		loadimage(&img, path.c_str(), rect.width, rect.height);
	}
	Image(Rect rct, COLORREF c)
	{
		img = NULL;
		pureColor = true;
		rect = rct;
		color = c;
	}
	

};
//显示文字的box
class Text : public GUIComponent
{
	string style;  //字体名称
	COLORREF color;  //字体颜色
	RECT rr;   //系统使用的矩形
public:
	Rect rect;  //框架使用的矩形
	string text;  //文本框的内容
	bool center = true;  //是否水平居中显示
	void OnGUI()  override
	{
		setbkmode(TRANSPARENT);  //文本背景透明
		settextcolor(color);  //设置文本颜色
		settextstyle(16, 0, style.c_str());  //设置字体
		if (center)drawtext(text.c_str(), &rr, DT_CENTER | DT_VCENTER | DT_SINGLELINE);  //渲染文字
		else drawtext(text.c_str(), &rr, DT_VCENTER | DT_SINGLELINE);
	}
	void OnEvent(ExMessage* message)override {}
	void SetText(string str, string sty = "宋体", COLORREF col = -1)
	{
		if (col != -1)  color = col;
		if (sty != "宋体") style = sty;
		text = str;
	}
	Text(string txt, Rect rct, string st = "宋体", const COLORREF c = BLACK, bool hcenter = true)
	{
		color = c;
		text = txt;
		rect = rct;
		style = st;
		center = hcenter;
		rr = { rect.origin.x,rect.origin.y,rect.end.x,rect.end.y };
	}
	Text(string txt, Rect rct, bool hcenter = true)
	{
		color = BLACK;
		text = txt;
		rect = rct;
		style = "宋体";
		center = hcenter;
		rr = { rect.origin.x,rect.origin.y,rect.end.x,rect.end.y };
	}
};
//能点击的按钮
class Button : public GUIComponent
{
	Image* a = nullptr;  //按钮的图片指针
	Text* t = nullptr;  //按钮文字指针
	LineBox* box = nullptr;  //按钮线框指针
	vector<function<void(void)>> onclicks;  //消息列表
public:
	void OnGUI() override
	{
		//分别调用子对象的渲染函数
		if (a != nullptr)a->OnGUI();  
		if (t != nullptr)t->OnGUI();
		if (box != nullptr)box->OnGUI();
	}
	void OnEvent(ExMessage* message) override
	{
		//处理子对象消息
		if (a != nullptr)a->OnEvent(message);
		if (t != nullptr)t->OnEvent(message);
		if (box != nullptr) box->OnEvent(message);
		
		//处理按下消息
		if (a!=NULL&&message->message==WM_LBUTTONDOWN&& inRect(message->x, message->y, &(a->rect)))
		{	
			for (auto& i : onclicks) i();
		}
	}


	//添加监听事件
	void AddListener(function<void(void)> onclick)
	{
		onclicks.push_back(onclick);
	}
	//移除监听事件,效率较低
	void RemoveListener(function<void(void)> onclick)
	{
		for (auto i = onclicks.begin(); i != onclicks.end(); i++)
		{
			bool eq = *(onclick.target<void(*)(void)>()) == *(i->target<void(*)(void)>());
			if (eq)
			{
				onclicks.erase(i);
			}
		}
	}
	//根据id移除监听
	void RemoveListener(int id)
	{
		onclicks.erase(onclicks.begin() + id);
	}
	//移除全部监听
	void RemoveAllListener()
	{
		onclicks.clear();
	}
	//形参:图片指针,文本指针,线框指针,点击范围以图片指针范围为准
	Button(Image* img, Text* txt = nullptr, LineBox* edge = nullptr)
	{
		a = img;
		t = txt;
		box = edge;
	}
	Button(Rect rct,COLORREF imgColor, string txt, COLORREF fColor, COLORREF edgeColor)
	{
		Image* img = new Image(rct, imgColor);
		Text* t = new Text(txt, rct,"宋体",fColor, true);
		LineBox* lb = new LineBox(rct, edgeColor);
		a = img;
		t = t;
		box = lb;
	}
	~Button()
	{
		delete a;
		delete t;
		delete box;
	}
};
//可自定义的网格
class Gird : public GUIComponent
{
private:
	Text* (**units);  //网格的文本指针 二维数组
	Rect rect;  //矩形范围
	COLORREF color;  //网格线颜色
	COLORREF fontcolor;  //网格文本颜色
	string dstyle;  //网格字体名称
public:


	int xCount;  //列数
	int yCount;  //行数
	Rect unitRect;  //单元格大小,左上角为0,0
#pragma region 生命
	//初始化网格文本
	void initUnits()
	{
		units = new Text * *[yCount];
		for (int i = 0; i < yCount; i++)
			units[i] = new Text * [xCount] {0};

		for (int y = 0; y < yCount; y++)for (int x = 0; x < xCount; x++)
			units[y][x] = new Text("", moveRect({ rect.origin.x + x * unitRect.width,rect.origin.y + unitRect.height * y }, unitRect), dstyle, fontcolor);

	}
	//rct指总网格大小,xy是网格数量
	Gird(Rect rct, int xC, int yC, COLORREF c = BLACK, string style = "宋体", COLORREF fontc = BLACK)
	{
		rect = rct;
		xCount = xC;
		yCount = yC;
		dstyle = style;
		unitRect = createRectbyPoint(0, 0, rct.width / xC, rct.height / yC);
		color = c;
		fontcolor = fontc;
		initUnits();
	}
	//leftTop为左上角位置,xC,yC指网格数量,width,height指网格宽高
	Gird(Vector2 leftTop, int xC, int yC, int width, int height, COLORREF c = BLACK, string style = "宋体", COLORREF fontc = BLACK)
	{
		xCount = xC;
		yCount = yC;
		rect = createRectbyPoint(leftTop.x, leftTop.y, leftTop.x+xC * width,leftTop.y+ yC * height);
		dstyle = style;
		unitRect = createRectbyPoint(0, 0, width, height);
		color = c;
		fontcolor = fontc;
		initUnits();
	}
	//leftTop为左上角位置,xC,yC指网格数量,width,height指网格宽高
	Gird(const int left, int top, int xC, int yC, int width, int height, COLORREF c = BLACK, string style = "宋体", COLORREF fontc = BLACK)
	{
		xCount = xC;
		yCount = yC;
		rect = createRectbyPoint(left, top, left+ xC * width, top + yC * height);
		dstyle = style;
		unitRect = createRectbyPoint(0, 0, width, height);
		color = c;
		fontcolor = fontc;
		initUnits();
	}
	~Gird()
	{
		for (int x = 0; x < xCount; x++)for (int y = 0; y < yCount; y++) delete units[x][y];
		for (int i = 0; i < xCount; i++)
		{
			delete(units[i]);
		}
		delete units;
	}
	//仅在GUI渲染时回调
	void OnGUI() override
	{
		setlinecolor(color);
		//绘制网格线
		for (int x = 0; x < xCount + 1; x++)
		{
			line(rect.origin.x + x * unitRect.width, rect.origin.y, rect.origin.x + x * unitRect.width, rect.end.y);
		}
		for (int y = 0; y < yCount + 1; y++)
		{
			line(rect.origin.x, rect.origin.y + y * unitRect.height, rect.end.x, rect.origin.y + y * unitRect.height);
		}
		//绘制文字
		for (int y = 0; y < yCount; y++)
		{
			for (int x = 0; x < xCount; x++)
			{
				units[y][x]->OnGUI();
			}
		}
	}
	//仅在处理事件时回调
	void OnEvent(ExMessage* message) override
	{
		//处理子对象消息
		for (int y = 0; y < yCount; y++)
		{
			for (int x = 0; x < xCount; x++)
			{
				units[y][x]->OnEvent(message);
			}
		}

	}
#pragma endregion

#pragma region 单元格操作

	//设置单元格文字
	void SetUnit(int x, int y, string text, const COLORREF color = BLACK)
	{
		assert(x < yCount&& y < xCount);
		units[x][y]->SetText(text);
	}
#pragma endregion

};

template <typename T>
class GirdList : public GUIComponent
{
	Gird* gird;
	COLORREF fontColor;
	int rowCount, columnCount;
	vector<T*>* origin;
	
	
	int currentPage = 0;

	int getMaxPage()
	{
		auto x = origin;
		int count = origin->size();
		int per = rowCount - 1;
		return count / per + 1;
	}

	function<vector<string>(T*)> handle;
	
public: 
	void next_page()
	{
		int maxpg = this->getMaxPage();
		currentPage = min(currentPage+1, maxpg);
	}
	void last_page()
	{
		currentPage = max(currentPage-1, 0);
	}

	void top_page()
	{
		int maxpg = getMaxPage();
		currentPage = min(0, maxpg);
	}
	void end_page()
	{
		int maxpg = getMaxPage();
		currentPage = min(maxpg, maxpg);
	}


	GirdList(int rowCount, int columnCount,Vector2 lefttop, int width, int height,
		string font,COLORREF line_color,COLORREF fontColor,int buttonHeight,int buttonWidth
		):
		fontColor(fontColor),columnCount(columnCount),rowCount(rowCount)
	{
		gird = new Gird(lefttop, columnCount, rowCount, width, height, line_color,font,fontColor);

	}

	~GirdList()
	{
		delete gird;
	}

	void SetOrigin(vector<T*>* origin)
	{
		this->origin = origin;
	}
	void SetHeader(vector<string> head)
	{
		if (head.size() >columnCount)
		{
			cout << "错误列数!";
			return;
		}
		for (int i = 0; i < head.size(); i++)
		{
			gird->SetUnit(0, i, head[i], fontColor);
		}
	}
	void SetColumn(function<vector<string>(T*)> hd)
	{
		handle = hd;
	}

	void OnGUI() override
	{
		//每页的数据行数
		int per = rowCount - 1;
		//遍历起点
		int from = currentPage * per;
		//遍历终点
		int to = from + per;
		//从1 - rowcount遍历行
		for (int i = 1; i < rowCount; i++)
		{
			if (from+i-1>= (*origin).size())
			{
				for (int j = 0; j < columnCount; j++)
				{
					gird->SetUnit(i, j, "", fontColor);
				}
			}
			else
			{
				vector<string> head = handle((*origin)[from+i-1]);
				for (int j = 0; j < head.size(); j++)
				{
					gird->SetUnit(i, j, (head)[j], fontColor);
				}
			}
		}

		gird->OnGUI();
	}
	void OnEvent(ExMessage* message) override
	{
		gird->OnEvent(message);

	}
};

#pragma region MyRegion


到了这里,关于C++ easyx大一期末作业利器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据库期末复习(10)数据库规范化理论

     函数依赖(概念):FD 范式分解(评估准则): 模式分解(工具): 如何衡量一个数据库好不好:准确 高效 如果一个数据库设计的不好的话的,会带来哪些问题 删除异常 数据冗余 为什么会导致出现上方的问题:数据依赖 数据依赖的分类:完全依赖,部分依赖,传递依赖和相应的定义 A

    2024年02月08日
    浏览(55)
  • 数据库期末复习(SQL,范式,数据库设计例题)

    创表 视图 例题:建立一个视图V1,显示老师与学生的授课关系,包括年份,学期,课程名称,老师ID,老师姓名,学生ID,学生姓名 向表中添加或删除约束 添加信息 例题:给“Aufr”同学选上2010年秋季学期的所有课程 删除信息 例题:删除“Comp. Sci.”学院“Ploski”同学,所有

    2024年02月02日
    浏览(61)
  • ETLCloud:实现数据库快速输入输出的利器

    在当今大数据时代,数据的高效处理和管理成为企业发展的关键。而数据库作为数据存储和管理的核心,其输入输出效率的提升对于企业来说至关重要。ETLCloud数据集成工具,为企业提供了快速、灵活、稳定的数据库输入输出解决方案,极大地简化了数据处理流程,提高了工

    2024年01月23日
    浏览(35)
  • 【数据库原理】期末突击(1)

    下列关系运算中,(  C    )运算不属于专门的关系运算。      A.选择                            B.连接     C .广义笛卡尔积                D.投影 传统的集合运算有:并、差、交、笛卡尔积 专门的关系运算有:选择、投影、连接、除运算等 SQL语言具有( 

    2024年01月25日
    浏览(40)
  • 数据库系统原理题-期末

    1、数据库系统和文件系统的主要区别是( B )。 A. 数据库系统复杂,而文件系统简单 B. 文件系统不能解决数据冗余和数据独立性问题,而数据库系统能够解决 C. 文件系统只能管理文件,而数据库系统还能管理其他类型的数据 D. 文件系统只能用于小型、微型机,而数据库系

    2024年02月11日
    浏览(41)
  • 【数据库系统概论】期末复习4

    期末复习1 期末复习2 期末复习3 数据库的安全性是指保护数据库以防止不合法的使用所造成的数据泄露、更改或破坏。 数据库的完整性是指数据的正确性和相容性。 数据的完整性和安全性是两个不同的概念,但是有一定的联系。前者是为了防止数据库中存在不符合语义的数

    2024年02月02日
    浏览(48)
  • 【期末考试】数据库综合复习宝典

    目录 第一章 数据库系统概述 第二章 关系代数 第四章 关系数据库理论 第五章 数据库设计 第六章 数据库管理系统 第八章 事务管理 第一章 数据库系统概述 1.1 三级模式 ①外模式:它为特定的应用程序或用户群体提供了一个数据视图,这个视图是独立于数据库其他用户的。

    2024年01月20日
    浏览(52)
  • mysql 数据库 期末复习题库

    一、选择题 第 1 章 数据库系统概述 1 . DBS 是(   A )的简写。 A. 数据库系统   B. 数据库管理系统    C. 数据库    D. 操作系统 2.DBMS 是 (  B   ) 的简写 A. 数据库系统   B. 数据库管理系统    C. 数据库    D. 数据 3.DB 、 DBMS 和 DBS 之间的关系是   (  C  ) A. DB 包含 DBMS 和

    2024年02月08日
    浏览(47)
  • MySQL数据库索引优化指南:提升查询效率的利器

    本文将详细探讨MySQL数据库索引的概念、作用以及不同类型的索引,包括主键索引、唯一索引和普通索引。通过实际案例分析,我们将深入理解索引的工作原理,并提供实用的优化建议,帮助读者提升数据库性能。

    2024年02月09日
    浏览(86)
  • 数据库原理及应用期末复习汇总(附某高校期末真题试卷)

    一、选择题 1、数据库系统的基本特征是_________。 A、数据的统一控制 B、数据共享性和统一控制 C、数据共享性、独立性和冗余度小 D、数据共享性和数据独立性 正确答案:C 2、DB、DBMS和DBS三者之间的关系是_________。 A、DBS与DB和DBMS无关 B、DBMS包括DBS和DB C、DB包括DBMS和DBS D、

    2024年02月03日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包