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?

26
demandé sur hkBattousai 2013-08-03 20:32:15

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 hWndFromhWndTo. 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.

36
répondu hkBattousai 2013-08-03 16:32:15

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);
10
répondu thinlizzy 2013-12-12 05:34:24

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_MINIMIZEDWM_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;
}
-1
répondu Laurie Stearn 2018-03-11 02:07:55