怎样解决在多个函数内获取鼠标消息并实现不同功能的问题以及有关图形覆盖的问题

0

代码想实现的功能是:鼠标点击绘图区的”帮助“,显示相应内容(已实现,即调用HelpUser()函数),再次点击绘图区任意位置,退出”帮助“(即将显示的内容清空)。

经过的尝试(源代码HelpUser()函数后面被注释的代码)以及遇到的问题:在调用完HelpUser()函数之后,再使用peekmessage()函数获取一次鼠标消息,存在msg中,相应内容可以显示,但是再次点击鼠标,程序无响应,并且屏幕只出现矩形框,文字没有显示

win10,vs2022

#include <iostream>
#include <graphics.h>
#include <conio.h>
using namespace std;

class Canvas
{
private:
	ExMessage msg;

public:
	ExMessage* Get_message();
	void LMouseButtonDown();
	void HelpUser();
	void painting();
};

ExMessage* Canvas::Get_message()
{
	return &this->msg;
}

void Canvas::LMouseButtonDown()
{

	if (this->Get_message()->x >= 155 && this->Get_message()->x <= 205 && this->Get_message()->y >= 15 && this->Get_message()->y <= 45)
	{
		HelpUser();

		/*peekmessage(this->Get_message(), EX_MOUSE);
		if (this->Get_message()->x >= 155 && this->Get_message()->x <= 205 && this->Get_message()->y >= 15 && this->Get_message()->y <= 45)
		{
			clearrectangle(300, 200, 800, 450);
		}*/
	}
}

void Canvas::HelpUser()
{
	setfillcolor(RGB(150, 150, 150));
	fillrectangle(300, 200, 800, 450);
	settextcolor(WHITE);
	settextstyle(20, 0, _T("黑体"));
	outtextxy(320, 220, _T("鼠标点击绘图区任意位置退出帮助"));
}

void Canvas::painting()
{
	while (true)
	{
		while (peekmessage(this->Get_message(), EX_MOUSE))
		{
			switch (this->Get_message()->message)
			{
			case WM_LBUTTONDOWN:
				this->LMouseButtonDown();
				break;
			}
		}
	}
}

//界面显示
void SetWindow()
{
	initgraph(1080, 750);  //创建窗口
	//设置背景
	setbkcolor(RGB(150, 150, 150));
	cleardevice();
	//绘制画图板
	setfillcolor(WHITE);
	fillrectangle(15, 70, 1060, 800);
	//工具栏
	setlinecolor(RGB(10, 10, 10));
	setlinestyle(PS_SOLID, 1);
	rectangle(155, 15, 205, 45);
	settextstyle(18, 11, _T("黑体"));
	outtextxy(160, 23, _T("帮助"));
}

int main()
{
	SetWindow();

	Canvas canvas;
	canvas.painting();

	_getch();
	return 0;
}
ava
白瓷梅子汤

2022-11-13

对了我还顺便把你的提示框和消息一直消除了 -  Margoo  2022-11-14
@Margoo 完美解决,感谢感谢,另外就是,能不能把第一处修改else if那部分放进和HelpUser()函数所在的if语句里?我是想这样实现,首先获取鼠标左键按下消息,显示提示框,然后在if语句里再次获取鼠标消息,而不是通过外部painting()中的while语句获取。我试过在HelpUser()后加上peekmessage(),但是并没有解决 -  白瓷梅子汤  2022-11-17
@Margoo 但是我发现如果提示框下面原本就有其他图形的话 也会一起被清空,怎么避免这种情况啊 -  白瓷梅子汤  2022-11-17
@白瓷梅子汤 你把其他的图形放到循环里就可以了可能通过循环不断的刷新,重要的是刷新 -  Margoo  2022-11-18
@白瓷梅子汤 你这怎么说呢,好好的框架不用,偏要在麻婆的麻bili找妈bili,就像马胯里扯到牛胯里 逻辑上的牛头不对马尾,又像起的大楼不楼,偏在把大楼顶当地基再再大楼头上起大楼,但有邪道的方法,可以实现,你的那个 peekmessage() 是不能重复叠加的会失效的, 那个while(1)可以去掉没关系程序正常能运行,逻辑上是保证程序稳定, -  Margoo  2022-11-18
@白瓷梅子汤 就是关于下面原本有就其他图形的话会被清空的问题,你把那个绘图加到 while 循环中,包插设置线条的颜色和填充的颜色相关的函数也加进云,否则会被点击编辑按钮外的,填充函数和线条 函数复盖,变得和背景一样了。 -  Margoo  2022-11-18
1

邪门的方法按你的要求修正版,并且把消息框底下的绘图加到刷新中,就不会丢失了:

增加邪门的方法和增加底层绘图的运行的效果视屏网站:https://www.bilibili.com/read/cv19753023?spm_id_from=333.999.0.0

1修改部分:

	if (this->Get_message()->x >= 155 && this->Get_message()->x <= 205 && this->Get_message()->y >= 15 && this->Get_message()->y <= 45)
	{
		HelpUser();
		
		HWND hwnd = GetHWnd();
		POINT point;
		BOOL af = true;
		while (af)
		{
			GetCursorPos(&point);			// 获取鼠标指针位置(屏幕坐标)
			ScreenToClient(hwnd, &point);
			while ((GetAsyncKeyState(VK_LBUTTON)))
			{
				if (point.x <= 155 || point.x >= 205 || point.y <= 15 || point.y >= 45)
				{
					setfillcolor(WHITE);
					setlinecolor(WHITE);
					clearrectangle(300, 200, 800, 450);
					fillrectangle(300, 200, 800, 450);
					af = false;
					break;
				}
			}
		}		
	}
}

2.修改部分2:

		Canvas canvas;
		canvas.painting();

3.邪门完整代码:

#include <iostream>
#include <graphics.h>
#include <conio.h>
#include<math.h>
using namespace std;

int PI = 3.14;
void paintstar(double x, double y, double r, double a)
{
	int pt[10];
	for (int n = 0; n < 5; ++n)
	{
		pt[n * 2] = (int)(-cos(PI * 4 / 5 * n + a) * r + x);
		pt[n * 2 + 1] = (int)(sin(PI * 4 / 5 * n + a) * r + y);
	}
	fillpoly(5, pt);
}
class Canvas
{
private:
	ExMessage msg;

public:
	ExMessage* Get_message();
	void LMouseButtonDown();
	void HelpUser();
	void painting();
};

ExMessage* Canvas::Get_message()
{
	return &this->msg;
}

void Canvas::LMouseButtonDown()
{

	

	if (this->Get_message()->x >= 155 && this->Get_message()->x <= 205 && this->Get_message()->y >= 15 && this->Get_message()->y <= 45)
	{
		HelpUser();
		
		HWND hwnd = GetHWnd();
		POINT point;
		BOOL af = true;
		while (af)
		{
			GetCursorPos(&point);			// 获取鼠标指针位置(屏幕坐标)
			ScreenToClient(hwnd, &point);
			while ((GetAsyncKeyState(VK_LBUTTON)))
			{
				if (point.x <= 155 || point.x >= 205 || point.y <= 15 || point.y >= 45)
				{
					setfillcolor(WHITE);
					setlinecolor(WHITE);
					clearrectangle(300, 200, 800, 450);
					fillrectangle(300, 200, 800, 450);
					af = false;
					break;
				}
			}
		}		
	}
}

void Canvas::HelpUser()
{
	setfillcolor(RGB(150, 150, 150));
	fillrectangle(300, 200, 800, 450);
	settextcolor(WHITE);
	settextstyle(20, 0, _T("黑体"));
	outtextxy(320, 220, _T("鼠标点击绘图区任意位置退出帮助"));

}

void Canvas::painting()
{
	double r = 0;
	while (true)
	{
		r += 0.02;
		if (r > PI * 2) r -= PI * 2;

		setcolor(RGB(0xff, 0xff, 0xff));
		setfillcolor(RGB(0, 0, 0xff));
		paintstar(400, 300, 100, r);

		while (peekmessage(this->Get_message(), EX_MOUSE))
		{
		
		
			switch (this->Get_message()->message)
			{
			case WM_LBUTTONDOWN:
				this->	LMouseButtonDown();
				break;
			}
		}
	}
}

//界面显示
void SetWindow()
{
	initgraph(1080, 750);  //创建窗口
	//设置背景
	setbkcolor(RGB(150, 150, 150));
	cleardevice();
	//绘制画图板
	setfillcolor(WHITE);
	fillrectangle(15, 70, 1060, 800);
	//工具栏
	setlinecolor(RGB(10, 10, 10));
	setlinestyle(PS_SOLID, 1);
	rectangle(155, 15, 205, 45);
	settextstyle(18, 11, _T("黑体"));
	outtextxy(160, 23, _T("帮助"));
	outtextxy(160, 23, _T("帮助"));
}
int main()
{
	SetWindow();

	
		Canvas canvas;
		canvas.painting();

	_getch();
	return 0;
}

你看看这是不是你要的效果,点击按钮弹出提示框,点击按钮消除提示框的内容。

运行的效果视屏网站:https://www.bilibili.com/read/cv19753023?spm_id_from=333.999.0.0

1.实例问题

你的点击按钮外区域就关闭提示的算法算法有问题。

正常的点击按钮算法判断是:

if (this->Get_message()->x >= 155 && this->Get_message()->x <= 205 && this->Get_message()->y >= 15 && this->Get_message()->y <= 45)

但是点击按钮区域外的算法是反过来的如下:

if (this->Get_message()->x <= 155 || this->Get_message()->x >= 205 || this->Get_message()->y <= 15 || this->Get_message()->y >= 45)

所以你的代码无效果

2.修改代码完整版:

第一修改区域为:


void Canvas::LMouseButtonDown()
{

	if (this->Get_message()->x >= 155 && this->Get_message()->x <= 205 && this->Get_message()->y >= 15 && this->Get_message()->y <= 45)
	{
		HelpUser();

		
		
	}
	else	if (this->Get_message()->x <= 155 || this->Get_message()->x >= 205 || this->Get_message()->y <= 15 || this->Get_message()->y >= 45)
	{
		setfillcolor(WHITE);
		setlinecolor(WHITE);
		clearrectangle(300, 200, 800, 450);
		fillrectangle(300, 200, 800, 450);
	}
}

第二修改区域为:

while (1)
	{
	
	Canvas canvas;
	canvas.painting();
	}

3.修改代码如下:

#include <iostream>
#include <graphics.h>
#include <conio.h>
using namespace std;

class Canvas
{
private:
	ExMessage msg;

public:
	ExMessage* Get_message();
	void LMouseButtonDown();
	void HelpUser();
	void painting();
};

ExMessage* Canvas::Get_message()
{
	return &this->msg;
}

void Canvas::LMouseButtonDown()
{

	if (this->Get_message()->x >= 155 && this->Get_message()->x <= 205 && this->Get_message()->y >= 15 && this->Get_message()->y <= 45)
	{
		HelpUser();

		
		
	}
	else	if (this->Get_message()->x <= 155 || this->Get_message()->x >= 205 || this->Get_message()->y <= 15 || this->Get_message()->y >= 45)
	{
		setfillcolor(WHITE);
		setlinecolor(WHITE);
		clearrectangle(300, 200, 800, 450);
		fillrectangle(300, 200, 800, 450);
	}
}

void Canvas::HelpUser()
{
	setfillcolor(RGB(150, 150, 150));
	fillrectangle(300, 200, 800, 450);
	settextcolor(WHITE);
	settextstyle(20, 0, _T("黑体"));
	outtextxy(320, 220, _T("鼠标点击绘图区任意位置退出帮助"));

}

void Canvas::painting()
{
	while (true)
	{
		while (peekmessage(this->Get_message(), EX_MOUSE))
		{
			switch (this->Get_message()->message)
			{
			case WM_LBUTTONDOWN:
				this->LMouseButtonDown();
				break;
			}
		}
	}
}

//界面显示
void SetWindow()
{
	initgraph(1080, 750);  //创建窗口
	//设置背景
	setbkcolor(RGB(150, 150, 150));
	cleardevice();
	//绘制画图板
	setfillcolor(WHITE);
	fillrectangle(15, 70, 1060, 800);
	//工具栏
	setlinecolor(RGB(10, 10, 10));
	setlinestyle(PS_SOLID, 1);
	rectangle(155, 15, 205, 45);
	settextstyle(18, 11, _T("黑体"));
	outtextxy(160, 23, _T("帮助"));
}

int main()
{
	SetWindow();
	
	
	Canvas canvas;
	canvas.painting();
	_getch();
	return 0;
}
ava
Margoo

2022-11-14

技术讨论社区