Autoscrolling on drag, part 5: Adding wiggle-to-scroll to escape velocity

Raymond Chen

Last time, we implemented autoscroll speed based on the mouse’s velocity. But our implementation didn’t support the popular bug-that-is-now-a-feature where wiggling the mouse makes the window scroll faster. Let’s bring that back.

void OnMouseMove(HWND hwnd, int x, int y, UINT keyFlags)
{
    if (g_fDragging) {
        if (g_dyAutoScroll == 0) {
            int direction = DetectAutoScroll({ x, y });
            if (direction) {
                DWORD tmTimer = GetDoubleClickTime() / 5;
                auto [distance, time] = GetMouseVelocity(hwnd, { x, y });
                if (time != 0) {
                    g_dyAutoScroll = MulDiv(distance, tmTimer, time);
                } else {
                    g_dyAutoScroll = 0;
                }
                if (g_dyAutoScroll > -g_cyLine && g_dyAutoScroll < g_cyLine) {
                    g_dyAutoScroll = direction * g_cyLine;
                }
                SetTimer(hwnd, IDT_AUTOSCROLL, tmTimer, OnAutoScroll);
            }
        } else {
            HandleDragMouseMove(hwnd, { x, y });
        }
    }
}

In the case where the mouse moved when autoscroll was already active (g_dyAutoScroll is nonzero), we let Handle­Drag­Mouse­Move do the work of processing the mouse movement. Recall that that function checks whether the mouse is in a place that activates autoscroll. If so, then it triggers an autoscroll immediately; otherwise, it cancels autoscroll.

And there you have it, scrolling faster by wiggling the mouse. The bug that’s now a feature.

1 comment

Discussion is closed. Login to edit/delete existing comments.

  • Piotr Siódmak 0

    Now make moving the cursor over progress bars speed up loading 🙂

Feedback usabilla icon