表格显示Windows 8的尺寸错误-如何获取实际尺寸? [英] Form tells wrong size on Windows 8 — how to get real size?

查看:152
本文介绍了表格显示Windows 8的尺寸错误-如何获取实际尺寸?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Windows 8上,将WinForms窗体的窗体边框样式设置为可更改 c $ c>,。我会尝试看看这是否也可以解决我的问题。



更新2:



仅出于完整性考虑,以下是VMware Windows 7的结果:







更新3:



最终找到了一个解决方案,其中涉及使用 DwmGetWindowAttribute 函数以及 DWMWA_EXTENDED_FRAME_BOUNDS 。我将在下面发布答案。

解决方案

为了回答我自己的问题,我终于找到了一种解决方案,其中涉及使用 DwmGetWindowAttribute 函数以及 DWMWA_EXTENDED_FRAME_BOUNDS



答案受此源代码似乎提供了一个函数在所有系统上工作。核心是一个函数:

  public static Rectangle GetWindowRectangle(IntPtr handle)
{
if(Environment .OSVersion.Version.Major< 6)
{
return GetWindowRect(handle);
}
其他
{
矩形;
返回DWMWA_EXTENDED_FRAME_BOUNDS(手柄,矩形)
吗?矩形
:GetWindowRect(handle);
}
}

完整代码如下:

 公共静态类WindowHelper 
{
// https://code.google.com/p/zscreen/source/浏览/trunk/ZScreenLib/Global/GraphicsCore.cs?r=1349

///< summary>
///获取实际的窗口大小,无论是Win XP,Win Vista,7还是8。
///< / summary>
public static Rectangle GetWindowRectangle(IntPtr handle)
{
if(Environment.OSVersion.Version.Major< 6)
{
return GetWindowRect(handle);
}
其他
{
矩形;
返回DWMWA_EXTENDED_FRAME_BOUNDS(句柄,矩形)?矩形:GetWindowRect(handle);
}
}

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

私有枚举Dwmwindowattribute
{
DwmwaExtendedFrameBounds = 9
}

[Serializable,StructLayout(LayoutKind.Sequential)]
私有结构Rect
{
// ReSharper禁用MemberCanBePrivate.Local
// ReSharper禁用FieldCanBeMadeReadOnly.Local
public int;
public int页首;
public int权利;
public int底部;
// ReSharper恢复FieldCanBeMadeReadOnly.Local
// ReSharper恢复MemberCanBePrivate.Local

public Rectangle ToRectangle()
{
return Rectangle.FromLTRB(Left ,顶部,右侧,底部);
}
}

私有静态布尔DWMWA_EXTENDED_FRAME_BOUNDS(IntPtr句柄,矩形矩形)
{
rect rect;
var result = DwmGetWindowAttribute(handle,(int)Dwmwindowattribute.DwmwaExtendedFrameBounds,
rect,Marshal.SizeOf(typeof(Rect)));
矩形= rect.ToRectangle();
返回结果> = 0;
}

[DllImport(@ user32.dll)]
[返回:MarshalAs(UnmanagedType.Bool)]
private static extern bool GetWindowRect(IntPtr hWnd ,在Rect lpRect中);

私有静态Rectangle GetWindowRect(IntPtr handle)
{
Rect rect;
GetWindowRect(handle,out rect);
return rect.ToRectangle();
}
}


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

In contrast, when having a form border style of FixedDialog, the values are wrong:

On Windows XP, the values are always correct:

My question is:

How to get the real size of a Window including the complete non-client area?

Update 1:

Seems that it is related to this SO question. I'll try and see whether this would solve my issue here, too.

Update 2:

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

Update 3:

Finally found a solution which involves using the DwmGetWindowAttribute function together with the DWMWA_EXTENDED_FRAME_BOUNDS value. I'll post an answer below.

解决方案

To answer my own question, I finally found a solution which involves using the DwmGetWindowAttribute function together with the DWMWA_EXTENDED_FRAME_BOUNDS value

The answer was inspired by this source code which presents a function that seems to work on all system. The core is a 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);
    }
}

Full code is provided 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();
    }
}

这篇关于表格显示Windows 8的尺寸错误-如何获取实际尺寸?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆