4

I have two callbacks for WM_MOVE and WM_MOVING. Oddly enough, WM_MOVE is being called while dragging the window. I expected WM_MOVE to be called only when I'm done dragging the window.

MSDN says that WM_MOVE is sent after a window is moved, and WM_MOVING is when the window is moving. The docs don't show any changes for Windows 7/VS2010, which is what I'm using.

WM_MOVE: http://msdn.microsoft.com/en-us/library/windows/desktop/ms632631%28v=vs.85%29.aspx

Has anyone come across this before? On drag, WM_MOVE is called, which it shouldn't be as far as I understand it.

    case WM_MOVE:
        {
            int x = LOWORD(lParam);
            int y = HIWORD(lParam);

            if (win.m_onMoveCallback)
                win.m_onMoveCallback(x, y);

            return 0;
        }
        break;

    case WM_MOVING:
        {
            int x = LOWORD(lParam);
            int y = HIWORD(lParam);

            if (win.m_onMovingCallback)
                win.m_onMovingCallback(x, y);

            return 0;
        }
        break;
6

Back in the time of Windows 3.1, before Windows 95, you dragged the window, but it did not move. You were only moving an outline of the window, in form of semi-transparent frame. Only when you ended the drag, the window moved (jumping to final position; back then there were no graphics accelerators, so redraw of a window was expensive operation; resize worked similarly).

In Windows 95, one of the big things was, the window actually moved / resized while you were dragging it / its resizing border. Much nicer.

Well, those two WM_XXX messages are tied to dragging the movement frame (now invisible, but still present as a principle) vs. moving the actual window itself. I hope now it is clearer.

3

When you define a move completion as occurring at a microscopic level, then it makes sense that the WM_MOVE is sent following a WM_MOVING message. Windows determines a move based on a change in the location of the mouse over a very small time period (hundreds or thousands of times a second). Since it can't know if you are done moving, you get both messages.

Way back when the time period was bigger (about 18 times a second), it was easier to tell if you were still moving.

2

I found that WM_EXITSIZEMOVE is an alternative to WM_MOVE. It detects when I'm done dragging the window, but it passes no values in WPARAM and LPARAM, so you have to do some detection. Here's a rough example:

First, set these as static or global:

static int x = 0, y = 0;
static bool move = false, resize = false;

Second, do your detection in WM_MOVING:

case WM_MOVING:
        {
            move = true; 
            RECT *r = (LPRECT)lParam;

            x = r->left;
            y = r->top;

            if (win.m_onMovingCallback)
                win.m_onMovingCallback(x, y);

            return 0;
        }
        break;

Third, check the move state in WM_EXITSIZEMOVE:

    case WM_EXITSIZEMOVE:
        {
            if (move)
            {
                if (win.m_onMoveCallback)
                    win.m_onMoveCallback(x, y);

                move = false;
            }

            return 0;
        }
        break;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.