To answer my own question, I finally found a solution that includes the DwmGetWindowAttribute function along with a DWMWA_EXTENDED_FRAME_BOUNDS value
The answer was inspired by this source code , which represents a function that seems to work on the entire system. The core is the function:
public static Rectangle GetWindowRectangle(IntPtr handle) { if (Environment.OSVersion.Version.Major < 6) { return GetWindowRect(handle); } else { Rectangle rectangle; return DWMWA_EXTENDED_FRAME_BOUNDS(handle, out rectangle) ? rectangle : GetWindowRect(handle); } }
The full code is below:
public static class WindowHelper { // https://code.google.com/p/zscreen/source/browse/trunk/ZScreenLib/Global/GraphicsCore.cs?r=1349 /// <summary> /// Get real window size, no matter whether Win XP, Win Vista, 7 or 8. /// </summary> public static Rectangle GetWindowRectangle(IntPtr handle) { if (Environment.OSVersion.Version.Major < 6) { return GetWindowRect(handle); } else { Rectangle rectangle; return DWMWA_EXTENDED_FRAME_BOUNDS(handle, out rectangle) ? rectangle : GetWindowRect(handle); } } [DllImport(@"dwmapi.dll")] private static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out Rect pvAttribute, int cbAttribute); private enum Dwmwindowattribute { DwmwaExtendedFrameBounds = 9 } [Serializable, StructLayout(LayoutKind.Sequential)] private struct Rect { // ReSharper disable MemberCanBePrivate.Local // ReSharper disable FieldCanBeMadeReadOnly.Local public int Left; public int Top; public int Right; public int Bottom; // ReSharper restore FieldCanBeMadeReadOnly.Local // ReSharper restore MemberCanBePrivate.Local public Rectangle ToRectangle() { return Rectangle.FromLTRB(Left, Top, Right, Bottom); } } private static bool DWMWA_EXTENDED_FRAME_BOUNDS(IntPtr handle, out Rectangle rectangle) { Rect rect; var result = DwmGetWindowAttribute(handle, (int)Dwmwindowattribute.DwmwaExtendedFrameBounds, out rect, Marshal.SizeOf(typeof(Rect))); rectangle = rect.ToRectangle(); return result >= 0; } [DllImport(@"user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetWindowRect(IntPtr hWnd, out Rect lpRect); private static Rectangle GetWindowRect(IntPtr handle) { Rect rect; GetWindowRect(handle, out rect); return rect.ToRectangle(); } }
source share