Как найти положение элемента управления/окна Win32 относительно родительского окна?
учитывая дескриптор окна Win32, мне нужно найти его положение относительно родительского окна.
Я знаю нескольких функций (например,GetWindowRect()
и GetClientRect()
), но ни один из них явно не возвращает нужные координаты.
Как мне это сделать?
3 ответов
решение использует силу GetWindowRect()
и MapWindowPoints()
.
GetWindowRect()
получает координаты окна относительно всей области экрана, которую вы видите на мониторе. Нам нужно преобразовать эти абсолютные координаты в относительные координаты нашей области главного окна. The MapWindowPoints()
преобразование координат относительно одного окна относительно другого. Поэтому нам нужна "ручка" области экрана и ручка родительского окна контроль, координаты которого мы пытаемся найти. Экран - это " окно "в терминологии Windows, и он называется"Рабочий стол". Мы можем получить доступ к дескриптору Desktop с помощью константы HWND_DESKTOP
определена в WinUser.h
(включая Windows.h
достаточно). И мы можем получить дескриптор нашего родительского окна, просто вызвав функцию Win32 GetParent()
. Теперь у нас есть все параметры, необходимые для вызова .
RECT YourClass::GetLocalCoordinates(HWND hWnd) const
{
RECT Rect;
GetWindowRect(hWnd, &Rect);
MapWindowPoints(HWND_DESKTOP, GetParent(hWnd), (LPPOINT) &Rect, 2);
return Rect;
}
MapWindowPoints()
определяется as:
int MapWindowPoints(
_In_ HWND hWndFrom,
_In_ HWND hWndTo,
_Inout_ LPPOINT lpPoints,
_In_ UINT cPoints
);
MapWindowPoints()
преобразование координат относительно из hWndFrom
to hWndTo
. В нашем случае мы делаем преобразование с рабочего стола (HWND_DESKTOP
) к нашему родительскому окну (GetParent(hWnd)
). Следовательно, в результате RECT
структура содержит относительные координаты нашего дочернего окна (hWnd
) относительно родительского окна.
это решение, которое я использую либо для windows, либо для элементов управления (дочерние окна)
RECT rc;
GetClientRect(hWnd,&rc);
MapWindowPoints(hWnd,GetParent(hWnd),(LPPOINT)&rc,2);
вот функция, которая принимает элементы обоих ответов во что-то полезное-особенно для перемещения / изменения координат управления.
Он принимает в качестве параметров интегральный идентификатор элемента управления из ресурса и дескриптор для его контейнера.
Следует также рассмотреть, является ли ownerHwnd
минимизируется перед вызовом функции путем прослушивания SIZE_MINIMIZED
на 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;
}