flushmessage()执行之后下一帧lbutton仍然为true

0

如下代码,在点击窗口的同时拖动鼠标,会不断触发lbutton的左键事件,即使已经清空了

提供一个复现的方法,在窗口内边移动鼠标边点击左键,会发现输出次数明显高于实际点击次数

请问是我的写法有问题吗

#include<easyx.h>
#include <iostream>

using namespace std;
int main()
{

	initgraph(1000, 600);
	ExMessage message={};
	int x = 0;
	while (true)
	{
		//如果有新消息
		if (peekmessage(&message))
		{
			//处理一次
			if (message.lbutton)
			{
				cout << ++x<<endl;
			}	
			//清空
			message = {};
			flushmessage();
		}
	}
	closegraph();
}

请问和win的消息队列有关吗?是否是我更新的太快而消息仍然存在于win的消息队列里

ava
有风来~

2023-1-2

0

关于 lbutton,文档中有描述:

lbutton:鼠标左键是否按下。仅当消息所属类别为 EX_MOUSE 时有效。
你收到的消息可能不是鼠标消息,也就导致 lbutton 无效。

修改建议:

1. 你需要判断 message 是否是 WM_LBUTTONDOWN,来判断是否有左键按下的消息。

2. 这里不适合调用 flushmessage,这可能会让没有来得及处理的消息被清理掉。

3. 在循环中增加 Sleep,可以降低 CPU 占用率。

  1. peekmessage 时,用 while 替代 if,防止消息速度超过 Sleep 延时。详细可以参考 https://codebus.cn/zhaoh/handle-mouse-messages-correctly

你的代码可以这样修改:

#include <graphics.h>
#include <iostream>

using namespace std;

int main()
{

	initgraph(640, 400, EX_SHOWCONSOLE);
	ExMessage msg;
	int x = 0;

	while (true)
	{
		//如果有新消息
		while (peekmessage(&msg))
		{
			//处理一次
			if (msg.message == WM_LBUTTONDOWN)
			{
				cout << ++x <<endl;
			}	
		}
		Sleep(20);
	}
	closegraph();
	return 0;
}
ava
慢羊羊

2023-1-3

技术讨论社区