如果你刚回来就会遇到麻烦HTCAPTION
回应all WM_NCHITTEST
消息。你会破坏诸如滚动条、关闭按钮、调整边框大小等都是通过不同的方式实现的HT*
values.
不过,你的想法是正确的。您希望使窗口的客户区域可拖动,因此您需要欺骗 Windows 认为您的客户区域实际上是标题区域(正如您所知,它是可拖动的)。该代码如下所示:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// ...
case WM_NCHITTEST:
{
// Call the default window procedure for default handling.
const LRESULT result = ::DefWindowProc(hWnd, uMsg, wParam, lParam);
// You want to change HTCLIENT into HTCAPTION.
// Everything else should be left alone.
return (result == HTCLIENT) ? HTCAPTION : result;
}
// ...
}
但是,根据您问题中的图像,您似乎只想将其限制为窗口的某个区域。您需要准确定义该区域是什么,然后进行点击测试以查看用户是否单击了该区域。假如说rcDraggable
is a RECT
包含边界的结构图像中显示的红色框 https://i.stack.imgur.com/ylh0R.png(在屏幕坐标中),您可以使用以下代码:
static RECT rcDraggable = ...
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
// ...
case WM_NCHITTEST:
{
// Call the default window procedure for default handling.
const LRESULT result = ::DefWindowProc(hWnd, uMsg, wParam, lParam);
// Get the location of the mouse click, which is packed into lParam.
POINT pt;
pt.x = GET_X_LPARAM(lParam);
pt.y = GET_Y_LPARAM(lParam);
// You want to change HTCLIENT into HTCAPTION for a certain rectangle, rcDraggable.
// Everything else should be left alone.
if ((result == HTCLIENT) && (PtInRect(&rcDraggable, pt))
{
return HTCAPTION;
}
return result;
}
// ...
}
如果你定义rcDraggable
就客户端坐标而言,您需要先将其转换为屏幕坐标,然后再进行命中测试以响应WM_NCHITTEST
。为此,请致电MapWindowPoints功能 https://msdn.microsoft.com/en-us/library/windows/desktop/dd145046.aspx,像这样:
RECT rc = rcDraggable;
MapWindowPoints(hWnd, /* a handle to your window */
NULL, /* convert to screen coordinates */
reinterpret_cast<POINT*>(&rc),
(sizeof(RECT) / sizeof(POINT)));