Comment trouver la position D'un Win32 control / window par rapport à sa fenêtre parent?
poignée D'une fenêtre Win32, je dois trouver sa position par rapport à sa fenêtre mère.
je connais plusieurs fonctions (e.g.; GetWindowRect()
et GetClientRect()
), mais aucun d'eux ne renvoie explicitement les coordonnées désirées.
comment je fais ça?
3 réponses
la solution utilise la puissance combinée de GetWindowRect()
et MapWindowPoints()
.
GetWindowRect()
récupère les coordonnées d'une fenêtre par rapport à la zone entière de l'écran que vous voyez sur votre moniteur. Nous devons convertir ces coordonnées absolues en coordonnées relatives de notre fenêtre principale. MapWindowPoints()
transforme les coordonnées données par rapport à une fenêtre par rapport à l'autre. Nous avons donc besoin d'une "poignée" de la zone de l'écran et le handle de la fenêtre parent de la contrôle dont nous essayons de trouver les coordonnées. L'écran est une "fenêtre" dans la terminologie Windows et il est appelé "Bureau". Nous pouvons accéder à la poignée de Bureau par la constante HWND_DESKTOP
définie dans WinUser.h
(Windows.h
est suffisant). Et nous pouvons obtenir la poignée de notre fenêtre parent simplement en appelant la fonction Win32 GetParent()
. Maintenant nous avons tous les paramètres nécessaires pour appeler le MapWindowPoints()
fonction.
RECT YourClass::GetLocalCoordinates(HWND hWnd) const
{
RECT Rect;
GetWindowRect(hWnd, &Rect);
MapWindowPoints(HWND_DESKTOP, GetParent(hWnd), (LPPOINT) &Rect, 2);
return Rect;
}
MapWindowPoints()
est défini comme:
int MapWindowPoints(
_In_ HWND hWndFrom,
_In_ HWND hWndTo,
_Inout_ LPPOINT lpPoints,
_In_ UINT cPoints
);
MapWindowPoints()
transformer les coordonnées relativement à partir de hWndFrom
hWndTo
. Dans notre cas, nous effectuons la transformation depuis le bureau (HWND_DESKTOP
) à notre fenêtre parent (GetParent(hWnd)
). Par conséquent, le résultat RECT
structure détient les coordonnées relatives de notre fenêtre enfant (hWnd
) par rapport à sa fenêtre mère.
c'est la solution que j'utilise pour windows ou pour les commandes (child windows)
RECT rc;
GetClientRect(hWnd,&rc);
MapWindowPoints(hWnd,GetParent(hWnd),(LPPOINT)&rc,2);
Voici une fonction qui prend les éléments des deux réponses dans quelque chose d'utilisable - particulièrement pour les coordonnées de contrôle de déplacement/redimensionnement.
Il accepte comme paramètres un identifiant de contrôle intégral d'une ressource, et une poignée pour son conteneur.
Il faut aussi considérer que ownerHwnd
est minimisé avant d'appeler la fonction en écoutant 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;
}