在我正在开发的应用程序中,有些情况下应用程序运行非常缓慢,在这些情况下,我发现我的鼠标移动、定时器/绘制消息没有被处理。如果我以缓慢的圆形移动鼠标,我可以无限期地防止窗口被重新绘制!我发现这是预期行为:
我通过类似于以下的方法在我的CWnd派生类中捕获消息:
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
然而,我该怎么办呢?有时候需要在鼠标移动时立即重新绘制。除了 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
,或使用带有RDW_UPDATENOW
标志的RedrawWindow
。 - Jonathan PotterWM_MOUSEMOVE
时,是否可以像这样轮询消息队列while(msg == WM_MOUSEMOVE)
并且只处理最后一个WM_MOUSEMOVE
消息,避免类似消息的堆积。 - Mr. BoyWM_MOUSEMOVE
的速度更快。 - David HeffernanPeekMessage()
以检索队列中的任何WM_MOUSEMOVE
消息。如果您忽略WM_MOUSEMOVE
中的坐标并使用GetCursorPos()
自己读取光标位置,可能会获得更好的结果。 - Jonathan Potter