Search code examples
cwindowswinapigdi

Drawing in WM_MOUSEMOVE


Good day,

What is best practice for drawing in mouse movement? I see many examples (at MSDN also) when drawing is performed in WM_MOUSEMOVE. But I think that better approach is all drawing in WM_PAINT.

Example:

Version 1

case WM_MOUSEMOVE:
{
     DummyFunctionForClientCoords();
     DummyFunctionForDrawing();
}
break;

Version 2

    case WM_MOUSEMOVE:
    {
         DummyFunctionForClientCoords();
         InvalidateRect(hwnd, &rc, TRUE); /* For sake of simplicity, update region is all area. */
    }
    break;

case WM_PAINT:
    {
         DummyFunctionForDrawing();
    }
    break;

Maybe this question is opinion based, but I want know advantages and disadvantages Version 1 vs. Version 2.


Solution

  • Unless you have a striking reason not to, rendering should always be performed in a WM_PAINT handler. A WM_PAINT message is generated on demand, if the update region is non-empty and there are no other higher priority messages in the message queue. This has two immediate consequences:

    • Input messages are handled before (potentially costly) rendering happens. This leads to a more responsive UI.
    • Multiple calls to InvalidateRect are coalesced into a single WM_PAINT message. This reduces overall cost of rendering.

    The code you posted under Version 2 is able to profit from the system provided optimizations.

    A disadvantage of Version 1 is, that whatever it renders to the screen will be overwritten, when the system decides to generate a WM_PAINT message. It is both more wasteful, and potentially doesn't render the desired result.


    Not specifically asked in the question, but if you need higher-precision mouse move events than those coalesced into a single WM_MOUSEMOVE message, you can call GetMouseMovePointsEx to get up to 64 previous (intermediate) mouse pointer positions.