18

I have a Win32 HWND and I'd like to allow the user to hold control and the left mouse button to drag the window around the screen. Given (1) that I can detect when the user holds control, the left mouse button, and moves the mouse, and (2) I have the new and the old mouse position, how do I use the Win32 API and my HWND to change the position of the window?

2 Answers 2

44

Implement a message handler for WM_NCHITTEST. Call DefWindowProc() and check if the return value is HTCLIENT. Return HTCAPTION if it is, otherwise return the DefWindowProc return value. You can now click the client area and drag the window, just like you'd drag a window by clicking on the caption.

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_NCHITTEST: {
        LRESULT hit = DefWindowProc(hWnd, message, wParam, lParam);
        if (hit == HTCLIENT) hit = HTCAPTION;
        return hit;
    }
    // etc..
}
Sign up to request clarification or add additional context in comments.

1 Comment

Not only that, you can for example return one of the edge values like HTBOTTOMRIGHT and now you get a resize cursor and can make it bigger or smaller by dragging the corner. The power.
2

Sorry for being a little late to answer but here is the code you desire

First you declare these global variables:

bool mousedown = false;
POINT lastLocation;

bool mousedown tells us if user is holding left button on their mouse or not

Then in callback funtion you write these lines of code

case WM_LBUTTONDOWN: {
    mousedown = true;
    GetCursorPos(&lastLocation);
    RECT rect;
    GetWindowRect(hwnd, &rect);
    lastLocation.x = lastLocation.x - rect.left;
    lastLocation.y = lastLocation.y - rect.top;
    break;
}
case WM_LBUTTONUP: {
    mousedown = false;
    break;
}
case WM_MOUSEMOVE: {
    if (mousedown) {
        POINT currentpos;
        GetCursorPos(&currentpos);
        int x =  currentpos.x - lastLocation.x;
        int y =  currentpos.y - lastLocation.y;
        MoveWindow(hwnd, x, y, window_lenght, window_height, false);
    }
    break;
}

2 Comments

good; I was looking for such answer
A few comments regarding this solution: it is more jagged compared WM_NCHITTEST, it doesn't support Windows docking (if you move window to left border of the screen - it will snap and resize by OS), it doesn't account for cursor moving outside of the window (this happened easy for me during testing, you need to call SetCapture\ReleaseCapture on mouse down).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.