如何获取控件相对于窗口客户区的位置?

17

我想要能够编写像这样的代码:

HWND hwnd = <the hwnd of a button in a window>;
int positionX;
int positionY;
GetWindowPos(hwnd, &positionX, &positionY);
SetWindowPos(hwnd, 0, positionX, positionY, 0, 0, SWP_NOZORDER | SWP_NOSIZE);

我希望让函数什么也不做。但是,我不知道该如何编写一个 GetWindowPos() 函数,使它能给我以正确的单位为答案:

void GetWindowPos(HWND hWnd, int *x, int *y)
{
    HWND hWndParent = GetParent(hWnd);

    RECT parentScreenRect;
    RECT itemScreenRect;
    GetWindowRect(hWndParent, &parentScreenRect);
    GetWindowRect(hWnd, &itemScreenRect);

    (*x) = itemScreenRect.left - parentScreenRect.left;
    (*y) = itemScreenRect.top - parentScreenRect.top;
}

如果我使用这个函数,我得到的坐标是相对于父窗口左上角的,但是SetWindowPos()需要相对于标题栏下面的区域的坐标(我假设这就是“客户端区域”,但win32术语对我来说都有点新鲜)。

解决方案 这是有效的GetWindowPos()函数(感谢Sergius):

void GetWindowPos(HWND hWnd, int *x, int *y)
{
    HWND hWndParent = GetParent(hWnd);
    POINT p = {0};

    MapWindowPoints(hWnd, hWndParent, &p, 1);

    (*x) = p.x;
    (*y) = p.y;
}

它是如何工作的?DirectX有什么用途?我是DirectX的新手。我编写了自己的函数来完成这个任务。 - Shantanu Gupta
是的,它是一个Windows应用程序,因此使用了Win32 API。 - Andy
2个回答

18

尝试使用 GetClientRect 获取坐标,然后使用 MapWindowPoints 进行转换。


1

我觉得你想要这样的东西。我不知道如何找到控件。 这段代码将标签的位置根据窗体大小居中对齐。

AllignLabelToCenter(lblCompanyName, frmObj)


 Public Sub AllignLabelToCenter(ByRef lbl As Label, ByVal objFrm As Form)
        Dim CenterOfForm As Short = GetCenter(objFrm.Size.Width)
        Dim CenterOfLabel As Short = GetCenter(lbl.Size.Width)
        lbl.Location = New System.Drawing.Point(CenterOfForm - CenterOfLabel, lbl.Location.Y)
    End Sub
    Private ReadOnly Property GetCenter(ByVal obj As Short)
        Get
            Return obj / 2
        End Get
    End Property

这并不是很有用,因为在win32中没有与您正在使用的“.Location”属性相当的东西(或者至少我没有找到)。 - Andy
我从未使用过Win32。如果您找到了解决方案,请也告诉我一声。 - Shantanu Gupta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接