gpt4 book ai didi

c# - 窗体在 Windows 8 上显示错误的大小——如何获得实际大小?

转载 作者:太空狗 更新时间:2023-10-29 23:23:38 25 4
gpt4 key购买 nike

在 Windows 8 上将窗体边框样式设置为 Sizable 的 WinForms 窗体,DesktopBounds property告诉正确的值:

enter image description here

相比之下,当表单边框样式为 FixedDialog 时,值是错误的:

enter image description here

在 Windows XP 上,值总是正确的:

enter image description here

enter image description here

我的问题是:

如何获取一个Window的真实大小,包括完整的非客户区?

更新 1:

似乎与this SO question有关.我会尝试看看这是否也能解决我的问题。

更新 2:

为了完整起见,以下是 VMware Windows 7 的结果:

enter image description here

enter image description here

更新 3:

最终找到了一个涉及使用 DwmGetWindowAttribute function 的解决方案连同 DWMWA_EXTENDED_FRAME_BOUNDS value .我将在下面发布答案。

最佳答案

为了回答我自己的问题,我终于找到了一个涉及使用 DwmGetWindowAttribute function 的解决方案连同 DWMWA_EXTENDED_FRAME_BOUNDS value

答案的灵感来自 this source code它提供了一个似乎适用于所有系统的功能。核心是一个函数:

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

完整代码如下:

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

关于c# - 窗体在 Windows 8 上显示错误的大小——如何获得实际大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16484894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com