winapi - conclase - ¿Cómo encuentro la posición de un control/ventana Win32 en relación con su ventana principal?
api de windows (3)
Aquí hay una función que toma elementos de ambas respuestas en algo utilizable, particularmente para mover / cambiar el tamaño de las coordenadas de control.
Acepta como parámetros un ID de control integral de un recurso y un identificador para su contenedor.
También se debe considerar si ownerHwnd
se minimiza antes de llamar a la función escuchando SIZE_MINIMIZED
en 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;
}
Dado el manejo de una ventana de Win32, necesito encontrar su posición relativa a su ventana principal.
Conozco varias funciones (por ejemplo, GetWindowRect()
y GetClientRect()
), pero ninguna de ellas devuelve explícitamente las coordenadas deseadas.
¿Cómo hago esto?
La solución está utilizando la potencia combinada de GetWindowRect()
y MapWindowPoints()
.
GetWindowRect()
recupera las coordenadas de una ventana en relación con el área de pantalla completa que ve en su monitor. Necesitamos convertir estas coordenadas absolutas en coordenadas relativas de nuestra área de ventana principal. MapWindowPoints()
transforma las coordenadas dadas en relación a una ventana en relación a otra. Entonces, necesitamos un "control" del área de la pantalla y el manejador de la ventana principal del control con el que estamos tratando de encontrar las coordenadas. La pantalla es una "ventana" en la terminología de Windows y se llama "Escritorio". Podemos acceder al control del Escritorio mediante la constante HWND_DESKTOP
definida en WinUser.h
(incluido Windows.h
es suficiente). Y podemos obtener el control de nuestra ventana principal simplemente llamando a la función GetParent()
Win32. Ahora tenemos todos los parámetros necesarios para llamar a la función MapWindowPoints()
.
RECT YourClass::GetLocalCoordinates(HWND hWnd) const
{
RECT Rect;
GetWindowRect(hWnd, &Rect);
MapWindowPoints(HWND_DESKTOP, GetParent(hWnd), (LPPOINT) &Rect, 2);
return Rect;
}
MapWindowPoints()
se define como:
int MapWindowPoints(
_In_ HWND hWndFrom,
_In_ HWND hWndTo,
_Inout_ LPPOINT lpPoints,
_In_ UINT cPoints
);
MapWindowPoints()
transforma las coordenadas relativamente de hWndFrom
a hWndTo
. En nuestro caso, hacemos la transformación desde el escritorio ( HWND_DESKTOP
) a nuestra ventana principal ( GetParent(hWnd)
). Por lo tanto, la estructura RECT
resultante contiene las coordenadas relativas de nuestra ventana secundaria ( hWnd
) en relación con su ventana principal.
esa es la solución que estoy usando ya sea para Windows o para controles (ventanas hijas)
RECT rc;
GetClientRect(hWnd,&rc);
MapWindowPoints(hWnd,GetParent(hWnd),(LPPOINT)&rc,2);