RECT rcCurrent; ::GetWindowRect ( hwndChild, &rcCurrent );
::MapWindowPoints ( NULL, hWnd, reinterpret_cast<LPPOINT>(&rcCurrent), 2);
Что этот код делает, так это получает ограничивающий прямоугольник (rcCurrent) дочернего окна (hwndChild) относительно клиентской области предположительно родительского окна (hWnd) - или определяет, где дочернее окно находится внутри егородитель.
Первая строка получает полный прямоугольник дочернего элемента, границ и всего, но возвращается в экранных координатах.
Вторая строка отображает эти точки из экранных координат (обозначается первой NULLПараметр) к координатам относительно клиентской области hWnd.
У Win32 нет вызова «получить местоположение внутри родителя», поэтому это ближайший окольный эквивалент.
Что такое приведениездесь используется преимущество того факта, что Win32 RECT имеет точную ту же схему памяти, что и два параллельных POINT, поэтому вызов MapWindowPoints с cPoints = 2 отобразит целый RECT за один раз.Это использование на самом деле задокументировано в MSDN , и даже получает специальную обработку в режимах зеркального отображения справа налево, чтобы гарантировать, что целые прямоугольники отображаются правильно при сопоставлении с рабочего стола слева направо с правым расположением.-второе приложение, и наоборот!(Если вы не планируете использовать зеркальное отображение R-to-L, чтобы локализованные версии ваших приложений могли работать на иврите или арабском языке, вам не нужно об этом беспокоиться.)
-
Правильный способ перевести это на C # зависит от того, откуда вы начинаете и чего пытаетесь достичь.Если вы конвертируете приложение оптом из C ++ в C #, и у вас есть производные от Control объекты для родителя и потомка, вы можете просто использовать child.Location , чтобы получить позицию относительно родителя.
-
С другой стороны, если вы переносите код, который написан в терминах HWND и должен оставаться таким даже при переносе в C # (например, потому что он работает против HWND издругой процесс или не знает, что лежит в основе HWND), тогда лучше всего было бы определить версии RECT и POINT для P / Invoke, а главное здесь - определить версию MapWindowPoints для P / Invoke, которая будет работатьна RECT.(Я предполагаю, что вы немного знакомы с 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);
... иВы можете использовать эту версию для отображения одного POINT (всегда передавая cPoints как 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.