web-dev-qa-db-ja.com

親ウィンドウに対するWin32コントロール/ウィンドウの位置を見つけるにはどうすればよいですか?

Win32ウィンドウのハンドルを指定すると、親ウィンドウに対する相対的な位置を見つける必要があります。

私はいくつかの関数を知っています(例: GetWindowRect() および GetClientRect() )、それらのどれも明示的に目的の座標を返しません。

どうすればいいですか?

26
hkBattousai

解決策は、GetWindowRect()MapWindowPoints() を組み合わせた機能を使用することです。

GetWindowRect()は、モニターに表示される画面領域全体に対するウィンドウの座標を取得します。これらの絶対座標をメインウィンドウ領域の相対座標に変換する必要があります。 MapWindowPoints()は、あるウィンドウに対して指定された座標を別のウィンドウに対して相対的に変換します。したがって、画面領域の「ハンドル」と、座標を見つけようとしているコントロールの親ウィンドウのハンドルが必要です。画面は、Windowsの用語では「ウィンドウ」であり、「デスクトップ」と呼ばれます。 _HWND_DESKTOP_で定義されている定数_WinUser.h_でデスクトップのハンドルにアクセスできます(_Windows.h_を含めれば十分です)。そして、Win32関数 GetParent() を呼び出すだけで、親ウィンドウのハンドルを取得できます。これで、MapWindowPoints()関数を呼び出すために必要なすべてのパラメーターが用意されました。

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

MapWindowPoints()は次のように定義されます:

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

MapWindowPoints()は、座標をhWndFromからhWndToに相対的に変換します。この場合、デスクトップ(_HWND_DESKTOP_)から親ウィンドウ(GetParent(hWnd))への変換を行います。したがって、結果のRECT構造体は、親ウィンドウに対する子ウィンドウ(hWnd)の相対座標を保持します。

36
hkBattousai

それは私がウィンドウまたはコントロール(子ウィンドウ)のいずれかに使用しているソリューションです

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