Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ Win32 C++;重新粉刷窗户_C++_Winapi_Visual C++_User Interface - Fatal编程技术网

C++ Win32 C++;重新粉刷窗户

C++ Win32 C++;重新粉刷窗户,c++,winapi,visual-c++,user-interface,C++,Winapi,Visual C++,User Interface,关于这个问题我读了不少书,但是 答:我不太确定如何使用该解决方案,或者 这个解决方案不起作用 为了我自己的学习,我试着在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,

关于这个问题我读了不少书,但是

答:我不太确定如何使用该解决方案,或者 这个解决方案不起作用

为了我自己的学习,我试着在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:I中设置框x和y坐标:

case WM_LBUTTONDOWN:
    boxx = pt.x;
    boxy = pt.y;
    break;
虽然这确实设置了长方体的x和y坐标,但我逐渐意识到窗口不再试图绘制长方体。所以为了解决这个问题,我尝试添加
invalidate(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);

非常感谢您的帮助

当我尝试使用您编写的代码时,它对我很有效。不过有几件事。不清楚在哪里设置点值。不过,你真的不需要麻烦。包括windowsx.h并使用
GET\u X\u LPARAM
GET\u Y\u 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\u LBUTTONDOWN
WM\u MOUSEMOVE
WM\u LBUTTONUP
消息中的鼠标坐标已经在客户端坐标中。只要定义了
boxdragmode
boxx
boxy
以便它们在
WndProc
调用之间保持不变,就可以工作。但是,由于在
WM_LBUTTONUP
之前不会使客户端区域无效,因此该框不会用鼠标拖动。当你放手的时候,它就会画出来。

当我使用你写的基本代码尝试它时,它对我很有效。不过有几件事。不清楚在哪里设置点值。不过,你真的不需要麻烦。包括windowsx.h并使用
GET\u X\u LPARAM
GET\u Y\u 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\u LBUTTONDOWN
WM\u MOUSEMOVE
WM\u LBUTTONUP
消息中的鼠标坐标已经在客户端坐标中。只要定义了
boxdragmode
boxx
boxy
以便它们在
WndProc
调用之间保持不变,就可以工作。但是,由于在
WM_LBUTTONUP
之前不会使客户端区域无效,因此该框不会用鼠标拖动。当你放手时,它只会画图。

你是否也在处理
WM\u MOUSEMOVE
来跟踪实际的拖动?和
WM_LBUTTONUP
在松开按钮时停止拖动
invalidate
是强制重新绘制窗口的正确方法,但您需要根据正确的输入进行重新绘制。不,我没有处理这两种情况。我的日志是,无论何时移动或释放,如果按钮按下,它希望它将窗口设置到该位置,但仍然不起作用……看起来您只在
lParam
中设置了一次
pt
的值,但响应的是哪条消息
lParam
仅在作为鼠标消息时包含鼠标坐标。每次收到
WM\u LBUTTONDOWN
WM\u MOUSEMOVE
时,您都应该更新pt。每次收到消息时,我都会更新pt。您是否也在处理
WM\u MOUSEMOVE
来跟踪实际拖动?和
WM_LBUTTONUP
在松开按钮时停止拖动
invalidate
是强制重新绘制窗口的正确方法,但您需要根据正确的输入进行重新绘制。不,我没有处理这两种情况。我的日志是,无论何时移动或释放,如果按钮按下,它希望它将窗口设置到该位置,但仍然不起作用……看起来您只在
lParam
中设置了一次
pt
的值,但响应的是哪条消息
lParam
仅在作为鼠标消息时包含鼠标坐标。每次收到
WM\u LBUTTONDOWN
WM\u MOUSEMOVE
时,您都应该更新
pt
。每次收到消息时,我都会更新pt。哈哈!显然,当我调用
case WM\u nchitest:
并返回
HTCAPTION
时,如果它在标题栏中,我应该返回
HTCLIENT
。这就引出了我的下一个问题。当我询问点击
WM\u nchitest
的坐标时,我必须执行
ScreenToClient(hWnd,&ps)
,否则它无法正常工作。为什么
WM\u-NCHITTEST
需要
ScreenToClient
而其他任何消息都不需要呢?
WM\u-NC*
鼠标消息(如
WM\u-ncbuttondown
)也会给出屏幕坐标。“NC”部分代表非客户。在客户坐标中提供非客户信息没有多大意义。乔尔-非常感谢。这非常有帮助。乔纳森-那没用。哈哈!显然,当我调用
case WM\u nchitest:
并返回
HTCAPTION
时,如果它在标题栏中,我应该返回
HTCLIENT
。这就引出了我的下一个问题。当我询问点击
WM\u nchitest
的坐标时,我必须执行
ScreenToClient(hWnd,&ps)
,否则它无法正常工作。为什么
WM\u NCHITTEST
需要
ScreenToClient
ho