在 Windows X 按钮上单击并按住鼠标时抑制 WM_TIMER 消息
我正在开发一款游戏,客户端需要继续处理 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
某些系统事件(例如系统菜单(如您的情况)或窗口大小调整)会暂时停止处理常规窗口消息。您需要重新考虑您的架构,并且可能在辅助线程中运行定期操作。在那里您可以使用 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.
我可以想到几种可能性。
当按钮按下发生在非客户区域时,系统代码可能会运行自己的消息循环,直到按钮被释放。此消息循环可能不会调度 WM_TIMER 消息。
我认为 WM_TIMER 很特殊,因为它是优先级较低的消息。仅当没有其他内容可检索时,才会从队列中检索 WM_TIMER(有点类似于 WM_PAINT)。 Windows 计时器最终会触发,并且永远不会早于指定的时间段,但如果您需要定期检测信号,它们就不太可靠。
正如另一个人所建议的,您可能需要依靠第二个线程来保持事物的活力。
I can think of a couple possibilities.
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.
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.
考虑使用定期等待计时器。它将在单独的线程中独立运行。
Consider using periodical waitable timer. It will run independently, in a separate thread.