2013-08-03 64 views

回答

34

該解決方案使用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()變換的座標相對從hWndFromhWndTo到。在我們的例子中,我們從Desktop(HWND_DESKTOP)轉換到我們的父窗口(GetParent(hWnd))。因此,結果RECT結構保存我們的子窗口(hWnd)相對於其父窗口的相對座標。

+1

今天我用了相當長的時間來找到解決這個問題的方法。在互聯網甚至是在這個網站上有很多關於這件事的錯誤和誤導性的信息。 Win32沒有明確的功能來收集這些信息是一個很大的悲劇,也很難找到解決這個簡單問題的好解釋和示例代碼。我在此分享解決方案,以幫助其他用戶在將來尋找它。 – hkBattousai

+1

你確定,這項工作在多個顯示器? – Xearinox

+0

@Xearinox我意識到我在這裏提高死亡率,但是......是的。在多個監視器上,根據哪個是主顯示器,該方法將返回高負值或高正值以表示相對於主顯示器的座標。使用'SetCursorPos'自己嘗試一下,看看鼠標光標所在的位置。 – RectangleEquals

11

這是我使用無論是窗口或控件的解決方案(子窗口)

RECT rc; 
GetClientRect(hWnd,&rc); 
MapWindowPoints(hWnd,GetParent(hWnd),(LPPOINT)&rc,2); 
+0

不應該說,它是MapWindowPoints(HWND,的getParent(HWND),(LPPOINT)&rc,1); –

+0

爲什麼會不會是這樣,@Erdinc?有一個矩形*兩個*百分點。 –

+0

我想你1個對象連得2分。 –

0

這裏是一個函數,它接受兩個答案的元素融入東西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; 
} 
相關問題