在 Windows X 按钮上单击并按住鼠标时抑制 WM_TIMER 消息

发布于 2024-12-14 10:55:57 字数 570 浏览 0 评论 0原文

我正在开发一款游戏,客户端需要继续处理 Windows 消息,否则游戏可能会被利用。为了解决窗口调整大小和拖动事件期间的这个问题,我们有一个 WM_TIMER 消息,每 50 毫秒触发一次,这将重新启动主事件循环。

问题在于,当用户单击并按住窗口客户端的 X 或最小化按钮时,此技术不起作用。 (所以他们没有完成点击,他们只是停止客户端。)

使用 Spy++,我看到的最后消息是:

<00731> 00160D3C P WM_NCLBUTTONDOWN nHittest:HTCLOSE xPos:1150 yPos:178
<00732> 00160D3C P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:1014 yPos:-23

在我移动鼠标之前没有任何内容,并且在我允许之前没有 WM_TIMER 消息按下鼠标按钮。

所以问题是,当我将鼠标悬停在窗口的 X 按钮上时,是否可以关闭某些内容以使客户端再次移动?或者我可以做些什么来触发我们的“看门狗”WM_TIMER 消息?

I'm working on a game where the client needs to continue processing windows messages or else the game can be exploited. In order to solve this problem during window re-size and drag events, we have a WM_TIMER message that fires every 50ms which will restart the main event loop.

The problem is that this technique is not working when a user clicks and holds over the X or minimize button of a windowed client. (So they don't complete the click, they just halt the client.)

Using Spy++, the last messages I see are:

<00731> 00160D3C P WM_NCLBUTTONDOWN nHittest:HTCLOSE xPos:1150 yPos:178
<00732> 00160D3C P WM_MOUSEMOVE fwKeys:MK_LBUTTON xPos:1014 yPos:-23

Followed by nothing until I move the mouse, and no WM_TIMER messages until I let go the mouse button.

So the question is, while I'm in the state of having my mouse down over the window's X button is there something I could key off of to get the client moving again? Or something I could do so our "watchdog" WM_TIMER messages fire?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙女 2024-12-21 10:55:57

某些系统事件(例如系统菜单(如您的情况)或窗口大小调整)会暂时停止处理常规窗口消息。您需要重新考虑您的架构,并且可能在辅助线程中运行定期操作。在那里您可以使用 WaitForSingleObject 或仅使用 Sleep() 而不是基于消息的计时器。

Some system events such as system menu (as in your case) or window resizing stop regular window messages from being processed for a while. You need to re-think your architecture and maybe run a periodical operation in a secondary thread. There you can use WaitForSingleObject or just Sleep() instead of message-based timer.

Hello爱情风 2024-12-21 10:55:57

我可以想到几种可能性。

  1. 当按钮按下发生在非客户区域时,系统代码可能会运行自己的消息循环,直到按钮被释放。此消息循环可能不会调度 WM_TIMER 消息。

  2. 我认为 WM_TIMER 很特殊,因为它是优先级较低的消息。仅当没有其他内容可检索时,才会从队列中检索 WM_TIMER(有点类似于 WM_PAINT)。 Windows 计时器最终会触发,并且永远不会早于指定的时间段,但如果您需要定期检测信号,它们就不太可靠。

正如另一个人所建议的,您可能需要依靠第二个线程来保持事物的活力。

I can think of a couple possibilities.

  1. When the button down happens on the non-client area, the system code may be running its own message loop until the button is released. This message loop might not dispatch WM_TIMER messages.

  2. I believe WM_TIMER is special in that it's a lower priority message. WM_TIMER is only retrieved from the queue when there's nothing else to retrieve (sort of similar to WM_PAINT). Windows timers eventually fire, and never sooner than the specified period, but they're not very reliable if you need a regular heartbeat.

As another person suggested, you might need to rely on a second thread to keep things alive.

羁拥 2024-12-21 10:55:57

Consider using periodical waitable timer. It will run independently, in a separate thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文