The form reports the wrong size in Windows 8 - how to get the actual size?

Having a WinForms form with the form border type set to Sizable on Windows 8, the DesktopBounds property reports the correct values:

enter image description here

In contrast, if you have a FixedDialog form frame style, the values ​​are incorrect:

enter image description here

In Windows XP, the values ​​are always true:

enter image description here

enter image description here

My question is:

How to get the actual window size, including the full non-client area?

Update 1:

This seems to be related to this SO issue . I will try to see if this helps solve my problem here.

Update 2:

Just for completeness, here are the results from VMware Windows 7:

enter image description here

enter image description here

Update 3:

Finally, a solution was found that includes the DwmGetWindowAttribute function along with the DWMWA_EXTENDED_FRAME_BOUNDS value . I will post an answer below.

+5
source share
2 answers

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(); } } 
+7
source

I don’t think that β€œwrong” is the right way to express it. You see values ​​that you do not understand, but this is not always the same as wrong. The real question is: what is the actual problem that you are trying to solve by getting the borders of the window?

Have you tried the Win32 GetWindowRect method? Interestingly, this shows.

One hack you could try is to detect the OS and take them into account.

To determine the OS in C #: http://support.microsoft.com/kb/304283 (Windows 8 is not specifically mentioned in this example, but I assume that the SDK has been updated for it)

-3
source

All Articles