【发布时间】:2014-03-29 03:56:54
【问题描述】:
在我正在开发的应用程序中,在某些情况下应用程序运行速度很慢,在这些情况下,我发现我的鼠标移动、计时器/绘画消息没有得到处理。如果我慢速移动鼠标,我可以无限期地阻止重新绘制窗口!
我发现这是expected behaviour:
除了 WM_PAINT 消息、WM_TIMER 消息和 WM_QUIT 消息,系统总是在一个结束时发布消息 消息队列。这确保了一个窗口接收到它的输入消息 以正确的先进先出 (FIFO) 顺序。 WM_PAINT 消息、WM_TIMER 消息和 WM_QUIT 消息是 保留在队列中并仅在以下情况下转发到窗口过程 队列不包含其他消息。此外,多个 WM_PAINT 同一窗口的消息组合成一个 WM_PAINT 消息,将客户区的所有无效部分合并到一个 单一区域。组合 WM_PAINT 消息可减少 窗口必须重绘其客户区的内容。
但是,我能做些什么呢?有时为了直接响应鼠标移动,我需要尽快重新绘制。
我通过这样的方法在我的 CWnd 派生类上捕获消息:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
【问题讨论】:
-
如果您需要立即重新绘制,请致电
InvalidateRect,然后拨打UpdateWindow,或使用RedrawWindow标记RDW_UPDATENOW。 -
我想知道当收到
WM_MOUSEMOVE时,是否可以像while(msg == WM_MOUSEMOVE)一样轮询消息队列,只处理最后一条WM_MOUSEMOVE消息,避免类似消息的堆叠。 -
简单的解决方案是让您更快地处理
WM_MOUSEMOVE -
遗憾的是,这不是一个简单的解决方案。
-
您可以在循环中调用
PeekMessage()以检索队列中的任何WM_MOUSEMOVE消息。如果您忽略WM_MOUSEMOVE中的坐标并使用GetCursorPos()自己读取光标位置,您可能还会发现获得更好的结果。