Getting Window Rect Using Handle on Windows 8 and Other


During developing GUI applications for windows many time we need to get window rect/size using window handle. For this Windows provides native api GetWindowRect and this is enough for getting window rect. But on Windows 8 in many scenario this api not gives correct rectangle.C# example to get window rect using window handle on Windows 8 and other using GetWindowRect and DwmGetWindowAttribute function.

For getting window attributes Microsoft introduced some new Dwmapi.dll api’s and that can be used to get window size and position.

Minimum supported client – Windows Vista [desktop apps only]
Minimum supported server – Windows Server 2008 [desktop apps only]

DwmGetWindowAttribute function of Dwmapi.dll is used to get window attributes.

For getting window rect on all Windows platforms, i found good sample which you can use for getting window rect by window handle. You can use this in C# winform applications.

    public static class WindowHelper
    {
        [DllImport(@"dwmapi.dll")]
        private static extern int DwmGetWindowAttribute(IntPtr hwnd, int dwAttribute, out Rect pvAttribute, int cbAttribute);

        [Serializable, StructLayout(LayoutKind.Sequential)]
        private struct Rect
        {
            public int Left;
            public int Top;
            public int Right;
            public int Bottom;

            public Rectangle ToRectangle()
            {
                return Rectangle.FromLTRB(Left, Top, Right, Bottom);
            }
        }

        [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();
        }
        /// <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);
            }
        }

        private enum Dwmwindowattribute
        {
            DwmwaExtendedFrameBounds = 9
        }

        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;
        }
    }