How do I find position of a Win32 control/window relative to its parent window?

时光怂恿深爱的人放手 提交于 2019-11-27 21:54:53

The solution is using the combined power of GetWindowRect() and MapWindowPoints().

GetWindowRect() retrieves the coordinates of a window relative to the entire screen area you see on your monitor. We need to convert these absolute coordinates into relative coordinates of our main window area. The MapWindowPoints() transforms the coordinates given relative to one window into relative to another. So we need a "handle" of the screen area and the handle of the parent window of the control which we are trying to find coordinates of. The screen are is a "window" in Windows terminology and it is called "Desktop". We can access the handle of Desktop by the constant HWND_DESKTOP defined in WinUser.h (including Windows.h is enough). And we can get the handle of our parent window simply by calling the Win32 function GetParent(). Now we have all the parameters required to call the MapWindowPoints() function.

RECT YourClass::GetLocalCoordinates(HWND hWnd) const
{
    RECT Rect;
    GetWindowRect(hWnd, &Rect);
    MapWindowPoints(HWND_DESKTOP, GetParent(hWnd), (LPPOINT) &Rect, 2);
    return Rect;
}

MapWindowPoints() is defined as:

int MapWindowPoints(
  _In_     HWND hWndFrom,
  _In_     HWND hWndTo,
  _Inout_  LPPOINT lpPoints,
  _In_     UINT cPoints
);

MapWindowPoints() transform the coordinates relatively from hWndFrom to hWndTo. In our case, we do the transformation from Desktop (HWND_DESKTOP) to our parent window (GetParent(hWnd)). Therefore, the resulting RECT structure holds the relative coordinates of our child window (hWnd) relative to its parent window.

that is the solution I am using either for windows or for controls (child windows)

RECT rc;
GetClientRect(hWnd,&rc);
MapWindowPoints(hWnd,GetParent(hWnd),(LPPOINT)&rc,2);

Here's a function that takes elements of both answers into something usable- particularly for move/resizing control co-ordinates.
It accepts as parameters an integral control ID from a resource, and a handle for its container.
One should also consider whether ownerHwnd is minimized before calling the function by listening for SIZE_MINIMIZED in WM_SIZE.

BOOL ProcCtrl(int ctrlID, HWND ownerHwnd)
{
    RECT rcClient = {0};        
    HWND hwndCtrl = GetDlgItem(ownerHwnd, ctrlID);
    if (hwndCtrl)
    {
    GetWindowRect(hwndCtrl, &rcClient); //get window rect of control relative to screen
    MapWindowPoints(NULL, ownerHwnd, (LPPOINT)&rcClient,2);

    // Set scaling parameters to suit in either of the following functions
    //if (!MoveWindow(hwndCtrl, rcClient.left, rcClient.top, 
    //rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, TRUE))
    {
        //Error;
        //return FALSE;
    }
    //if (!SetWindowPos(hwndCtrl, NULL, (int)rcClient.left, (int)(rcClient.top),
    //(int)(rcClient.right - rcClient.left), (int)(rcClient.bottom - rcClient.top), SWP_NOZORDER))
    {
        //Error;
        //return FALSE;
    }
    }
    else
    {
        //hwndCtrl Error;
        //return FALSE;
    }
    return TRUE;
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!