給定一個Win32窗口的句柄,我需要找到它相對於其父窗口的位置。我知道幾個函數(例如GetWindowRect()
和GetClientRect()
),但他們都沒有顯式返回所需的座標。如何找到Win32控件/窗口相對於其父窗口的位置?
我該怎麼做?
給定一個Win32窗口的句柄,我需要找到它相對於其父窗口的位置。我知道幾個函數(例如GetWindowRect()
和GetClientRect()
),但他們都沒有顯式返回所需的座標。如何找到Win32控件/窗口相對於其父窗口的位置?
我該怎麼做?
該解決方案使用GetWindowRect()
和MapWindowPoints()
的組合功率。
GetWindowRect()
檢索相對於您在顯示器上看到的整個屏幕區域的窗口座標。我們需要將這些絕對座標轉換爲我們主窗口區域的相對座標。 MapWindowPoints()
將給定的座標相對於另一個窗口轉換爲相對於另一個窗口。所以我們需要屏幕區域的「句柄」以及我們試圖找到座標的控件的父窗口的句柄。屏幕是Windows術語中的「窗口」,它被稱爲「桌面」。我們可以通過WinUser.h
中定義的常量HWND_DESKTOP
訪問桌面的句柄(包括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
到。在我們的例子中,我們從Desktop(HWND_DESKTOP
)轉換到我們的父窗口(GetParent(hWnd)
)。因此,結果RECT
結構保存我們的子窗口(hWnd
)相對於其父窗口的相對座標。
這是我使用無論是窗口或控件的解決方案(子窗口)
RECT rc;
GetClientRect(hWnd,&rc);
MapWindowPoints(hWnd,GetParent(hWnd),(LPPOINT)&rc,2);
不應該說,它是MapWindowPoints(HWND,的getParent(HWND),(LPPOINT)&rc,1); –
爲什麼會不會是這樣,@Erdinc?有一個矩形*兩個*百分點。 –
我想你1個對象連得2分。 –
這裏是一個函數,它接受兩個答案的元素融入東西usable-特別是對移動/調整控制座標。
它接受來自資源的集成控制ID和其容器的句柄作爲參數。
還應該考慮ownerHwnd
是否通過在WM_SIZE
中偵聽SIZE_MINIMIZED
調用函數之前最小化。
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;
}
今天我用了相當長的時間來找到解決這個問題的方法。在互聯網甚至是在這個網站上有很多關於這件事的錯誤和誤導性的信息。 Win32沒有明確的功能來收集這些信息是一個很大的悲劇,也很難找到解決這個簡單問題的好解釋和示例代碼。我在此分享解決方案,以幫助其他用戶在將來尋找它。 – hkBattousai
你確定,這項工作在多個顯示器? – Xearinox
@Xearinox我意識到我在這裏提高死亡率,但是......是的。在多個監視器上,根據哪個是主顯示器,該方法將返回高負值或高正值以表示相對於主顯示器的座標。使用'SetCursorPos'自己嘗試一下,看看鼠標光標所在的位置。 – RectangleEquals