在父坐标或屏幕坐标中,WM_WINDOWPOSCHANGED上的WINDOWPOS中的坐标是?

时间:2015-04-13 05:21:03

标签: winapi

这一次快速而简单。我有一个子类的制表符控件,可以处理WM_WINDOWPOSCHANGED,而不是SWP_NOSIZE时,会调整其内容的大小。它会将WINDOWPOS lParam的{​​{1}}和cx字段传递给cy,以获取内容的矩形。

我也需要在命令上执行此操作(例如,在更改选项卡之后)。但是,我不能只做一个相同大小的虚拟调整大小;即使有明确的TCM_ADJUSTRECT,如果大小没有改变,真正的Windows似乎也会添加SetWindowPos()。所以我想把类似的代码写到我的SWP_NOSIZE处理程序。

我的问题是:给定的WM_WINDOWPOSCHANGED坐标,父坐标或屏幕坐标是什么坐标系? WM_WINDOWPOSCHANGED返回屏幕坐标,因此我想知道是否需要转换坐标以获得与GetWindowRect()中相同的值。 WM_WINDOWPOSCHANGED的文档没有说明; WM_WINDOWPOSCHANGED

的文档也没有

感谢。

1 个答案:

答案 0 :(得分:0)

WINDOWPOS, GetWindowRect, GetCursorPos等给出屏幕坐标。当您使用SetWindowPos时,您必须提供与父级相关的坐标。对于使用屏幕坐标的主窗口和弹出窗口,这是直截了当的。对于移动子窗口,您可以使用ScreenToClientClientToScreen进行转换。

例如,这将找到与对话框左上角相关的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);