RECT rcCurrent; ::GetWindowRect (hwndChild, &rcCurrent);
::MapWindowPoints (NULL, hWnd, reinterpret_cast<LPPOINT>(&rcCurrent), 2);
這段代碼做的是得到的邊框(rcCurrent)子窗口(hwndChild)相對於大概父窗口(hWnd)的客戶區 - 或者確定子窗口在其父窗口內的位置。
第一行獲取子項,邊框和全部的完整矩形,但它會返回到屏幕座標中。
第二行將這些點從屏幕座標(由第一個NULL參數指示)映射到相對於hWnd客戶區的座標。
Win32沒有「獲取父母內的位置」調用,所以這是最接近的迴旋等效。
什麼演員陣容在這裏做,走的是一個事實,即一個Win32 RECT有確切相同的內存佈局兩回至後端的積分優勢,因此調用與cPoints MapWindowPoints = 2將映射在整個RECT一個去。這個用法實際上是documented in MSDN,甚至在從右到左鏡像模式中得到特殊處理以確保當從左到右佈局桌面映射到從右到左應用程序時整個矩形被正確映射,並且惡意-versa! (如果你不打算使用R-到-L鏡像,因此您的應用是本地化版本可以在希伯來文或阿拉伯文運行,你不需要擔心這個。)
-
將此轉換爲C#的正確方法取決於您從哪裏開始,以及您想要實現的目標。如果您將應用程序批量從C++轉換爲C#,並且您有父級和子級的Control派生對象,則可以使用child.Location來獲取相對於父級的位置。
-
在另一方面,如果你正在移植上所寫的HWNDs方面,具有代碼保持,即使移植到C#(如,那是因爲它的工作對HWNDs從另一個進程或不知道HWND的底層框架),那麼最好的辦法是定義RECT和POINT的P/Invoke版本,這裏的關鍵是定義一個可以在RECT上工作的MapWindowPoints的P/Invoke版本。 (我假設你有點熟悉的P/Invoke這裏...)通常MapWindowPoints被定義爲(從pinvoke.net):
[DllImport("user32.dll", SetLastError=true)]
public static extern int MapWindowPoints(IntPtr hwndFrom, IntPtr hwndTo, ref POINT lpPoints, [MarshalAs(UnmanagedType.U4)] int cPoints);
...你可以使用此版本地圖的單點(總是將c點傳遞爲1)。然後,您也可以定義與RECT工作的版本:
[DllImport("user32.dll", SetLastError=true)]
public static extern int MapWindowPoints(IntPtr hwndFrom, IntPtr hwndTo, ref RECT lpPoints, [MarshalAs(UnmanagedType.U4)] int cPoints);
,並呼籲後者的版本時,總是傳中cPoints爲2調用此則是準確的C#相當於原來的C++ MapWindowPoints通話。
你想如何改變它們?一個描述了一個矩形,另一個描述了一個點。實際上,矩形應該描述什麼?如果沒有這些信息,就不可能說出你可能想如何映射它們。 – Chris 2012-02-29 09:23:49