0

我已经阅读了很多关于这个主题的内容,但要么

A. 我不太确定如何使用该解决方案,或 B. 该解决方案不起作用。

为了我自己的学习,我正在尝试在 C++ 窗口中制作一个可拖动的框。WM_PAINT我最初通过以下消息绘制矩形LRESULT CALLBACK WndProc

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);

    DrawRect(hdc, 0, 0, width, 20, RGB(60, 60, 60));

    DrawRect(hdc, boxx, boxy, boxx + 100, boxy + 20, RGB(0, 100, 255));

    EndPaint(hWnd, &ps);
    break;

我很确定我的 DrawRect 函数工作得很好,因为它确实绘制了盒子。

为了使框可拖动,我放置了一个方法,我首先定义了光标相对于窗口的点:

POINT pt;
pt.x = ((int)(short)LOWORD(lParam));
pt.y = ((int)(short)HIWORD(lParam));
ScreenToClient(hWnd, &pt);

然后,在消息 WM_LBUTTONDOWN: 我设置框 x 和 y 坐标:

case WM_LBUTTONDOWN:
    boxx = pt.x;
    boxy = pt.y;
    break;

尽管这确实设置了框 x 和 y 坐标,但我开始意识到窗口永远不会尝试再次绘制框。所以为了解决这个问题,我尝试添加InvalidateRect(hWnd, 0, NULL);到我的代码中,但无济于事。

所以我的问题仍然存在,如何让程序重绘或重绘窗口?

编辑:我已经改变了我的代码来处理两者WM_MOUSEMOVEWM_LBUTTONUP就像这样:

case WM_LBUTTONDOWN:
    boxdragmode = true;
    break;
case WM_MOUSEMOVE:
    if(boxdragmode)
    {
        boxx = pt.x;
        boxy = pt.y;
    }
    break;
case WM_LBUTTONUP:
    boxdragmode = false;
    InvalidateRect(hWnd, 0, TRUE);
    break;

它仍然不会更新窗口,或者它可能不会更新框坐标。我通过这个得到坐标:

POINT pt;
pt.x = ((int)(short)LOWORD(lParam));
pt.y = ((int)(short)HIWORD(lParam));
ScreenToClient(hWnd, &pt);

非常感谢您的帮助

4

1 回答 1

3

当我基本上使用您编写的代码尝试它时,它对我有用。不过,有几件事。目前尚不清楚您在哪里设置 POINT 值。不过,你真的不需要打扰。包括 windowsx.h 和使用GET_X_LPARAMand GET_Y_LPARAM.

case WM_LBUTTONDOWN:
    boxdragmode = true;
    break;

case WM_MOUSEMOVE:
    if(boxdragmode)
    {
        boxx = GET_X_LPARAM(lParam);
        boxy = GET_Y_LPARAM(lParam);
    }
    break;

case WM_LBUTTONUP:
    boxdragmode = false;
    InvalidateRect(hWnd, 0, TRUE);
    break;

您不需要调用,因为来自、或消息ScreenToClient的鼠标坐标已经在客户端坐标中。只要、和被定义为它们将在调用之间持续存在,那将起作用。但是,因为在框不会用鼠标拖动之前,您不会使客户区无效。当您放手时,它只会绘制。WM_LBUTTONDOWNWM_MOUSEMOVEWM_LBUTTONUPboxdragmodeboxxboxyWndProcWM_LBUTTONUP

于 2013-07-23T00:57:56.330 回答