【发布时间】:2013-07-22 20:48:43
【问题描述】:
我已经阅读了很多关于这个主题的文章,但要么
A.我不太确定如何使用该解决方案,或者 B. 解决方案不起作用。
为了我自己的学习,我正在尝试在 C++ 窗口中制作一个可拖动的框。我最初通过LRESULT CALLBACK WndProc中的WM_PAINT消息绘制矩形:
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_MOUSEMOVE 和WM_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);
非常感谢您的帮助
【问题讨论】:
-
您是否也在处理
WM_MOUSEMOVE,以跟踪实际拖动?和WM_LBUTTONUP释放按钮时停止拖动?InvalidateRect是强制重新绘制窗口的正确方法,但您需要根据正确的输入来执行此操作。 -
不,这两个我都没有处理。我的日志是,它何时被移动或释放并不重要,如果按钮被按下,它希望它将窗口设置到该位置
-
还是不行....
-
您似乎只设置了一次
pt的值,来自lParam- 但响应哪条消息?lParam仅在鼠标消息时包含鼠标坐标。每次收到WM_LBUTTONDOWN和WM_MOUSEMOVE时,您都应该更新pt。 -
我每次收到 a 消息时都会更新 pt。
标签: c++ winapi visual-c++ user-interface