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