如何使用窗口客户区实现拖动窗口?

17

我有一个Win32 HWND,想要允许用户按住Ctrl键和鼠标左键来拖动窗口到屏幕上的其他位置。已知(1)我可以检测到用户按住Ctrl键、鼠标左键并移动鼠标的操作,和(2)新旧鼠标位置,如何使用Win32 API和我的HWND来改变窗口的位置?

2个回答

41

实现一个WM_NCHITTEST消息处理程序。调用DefWindowProc(),并检查返回值是否为HTCLIENT。如果是,则返回HTCAPTION,否则返回DefWindowProc的返回值。现在可以单击客户区域并拖动窗口,就像通过单击标题栏拖动窗口一样。

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..
}

1
不仅如此,例如您可以返回其中一个边缘值,如HTBOTTOMRIGHT,现在您将获得一个调整大小的光标,并可以通过拖动角落使其变大或变小。这就是力量。 - Hans Passant

2
抱歉回复有些晚,以下是你需要的代码:
首先声明这些全局变量:
bool mousedown = false;
POINT lastLocation;

bool mousedown表示用户是否按住鼠标左键

然后在回调函数中,您需要编写以下几行代码:

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;
}

很好,我正在寻找这样的答案。 - MMD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接