GetSystemMetrics()为.NET 4.5&;返回不同的结果.NET 4.0

本文关键字:NET 返回 结果 GetSystemMetrics amp | 更新日期: 2023-09-27 17:58:01

在.NET 4.0->.NET 4.5应用程序迁移过程中,我发现了一个非常奇怪的行为。我已经能够跟踪这个问题,直到这个简短的代码片段:

class Program
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    public static extern int GetSystemMetrics(int nIndex);
    static void Main(string[] args)
    {
        const int CXFRAME = 0x20;
        const int CYFRAME = 0x21;
        var dx = GetSystemMetrics(CXFRAME);
        var dy = GetSystemMetrics(CYFRAME);
        Console.WriteLine("{0}x{1}", dx, dy);
        Console.ReadKey();
    }
}

当使用Target Framework = 4.0(以及2.0、3.0、3.5)编译时,它输出8x8

使用Target Framework = 4.5编译时,输出4x4

使用MSVS2012调试器运行此示例也始终输出4x4(使用任何目标框架)。

其他选项(目标框架配置文件、目标平台、启用/禁用Aero)不会影响结果,唯一改变输出的是目标框架和使用调试器运行。我已经能够在3台计算机上重现这个问题,不幸的是,它们在安装的软件方面几乎完全相同:

  • 带有MSVS2012(英语/白俄罗斯语)更新1的Windows 7 Ultmate SP1(俄语,已安装所有更新)
  • Windows 8(在虚拟机上)

目前,我正在考虑修补一些.NET类(例如SystemParameters),这些类使用反射调用GetSystemMetrics(),但我不确定如何获得正确的度量值。

问题:

  • 我是不是错过了什么?GetSystemMetrics()如何受到目标框架的影响
  • 有什么方法可以从.NET 4.5应用程序调用GetSystemMetrics()并获得正确的结果吗

我愿意接受任何关于解决这个问题的建议。此外,如果您无法重现该问题,请在评论中留下简短的系统描述。

GetSystemMetrics()为.NET 4.5&;返回不同的结果.NET 4.0

因此,这实际上是一种按设计的行为,如果有人有类似的问题,下面是始终输出相同结果的代码:

const int CXFRAME = 0x20;
const int CYFRAME = 0x21;
const int CXPADDEDBORDER = 92;
var dx = GetSystemMetrics(CXFRAME);
var dy = GetSystemMetrics(CYFRAME);
var d  = GetSystemMetrics(CXPADDEDBORDER);
dx += d;
dy += d;
Console.WriteLine("{0}x{1}", dx, dy);
Console.ReadKey();

还要注意的是,RibbonWindowWPF控件使用WindowChrome,现在是.NET4.5的一部分,它不知道这些更改,并显示混乱的窗口边界(幸运的是,我认为可以使用修改后的样式来修复它)。

根据微软的说法,这是经过设计的。

请参阅此处了解详细信息:

  • SystemParameters.WindowResizeBorderThickness似乎返回了不正确的值-Microsoft Connect(没有可用的存档版本)
  • 回归::GetSystemMetrics提供不同的值-MicrosoftConnect(存档)

尽管MS说这是";通过设计";,我仍然认为这是个bug!