这一次快速而简单。我有一个子类的制表符控件,可以处理WM_WINDOWPOSCHANGED
,而不是SWP_NOSIZE
时,会调整其内容的大小。它会将WINDOWPOS
lParam
的{{1}}和cx
字段传递给cy
,以获取内容的矩形。
我也需要在命令上执行此操作(例如,在更改选项卡之后)。但是,我不能只做一个相同大小的虚拟调整大小;即使有明确的TCM_ADJUSTRECT
,如果大小没有改变,真正的Windows似乎也会添加SetWindowPos()
。所以我想把类似的代码写到我的SWP_NOSIZE
处理程序。
我的问题是:给定的WM_WINDOWPOSCHANGED
坐标,父坐标或屏幕坐标是什么坐标系? WM_WINDOWPOSCHANGED
返回屏幕坐标,因此我想知道是否需要转换坐标以获得与GetWindowRect()
中相同的值。 WM_WINDOWPOSCHANGED
的文档没有说明; WM_WINDOWPOSCHANGED
。
感谢。
答案 0 :(得分:0)
WINDOWPOS, GetWindowRect, GetCursorPos
等给出屏幕坐标。当您使用SetWindowPos
时,您必须提供与父级相关的坐标。对于使用屏幕坐标的主窗口和弹出窗口,这是直截了当的。对于移动子窗口,您可以使用ScreenToClient
和ClientToScreen
进行转换。
例如,这将找到与对话框左上角相关的OK按钮的坐标:
RECT rcOK;
HWND hitem = ::GetDlgItem(m_hWnd, IDOK);
GetWndRect(rcOK, hitem, m_hWnd);
void GetWndRect(RECT &rect, HWND item, HWND parent)
{
::GetWindowRect(item, &rect);//screen coordinates of OK button
POINT offset{ 0 };
ClientToScreen(parent, &offset); //Top-left (0,0) of client area of dialog -> screen coordinates
rect.left -= offset.x;
rect.right -= offset.x;
rect.top -= offset.y;
rect.bottom -= offset.y;
//client coordinates of OK button in relation to Dialog's Top-Right
}
现在我们可以将OK按钮向上移动10px:
rc.top -= 10;
rc.bottom -= 10;
::SetWindowPos(hitem, 0, rc.left, rc.top, 0, 0, SWP_NOSIZE);