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

在.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台计算机上重现这个问题,不幸的是它们在安装的软件方面几乎完全相同:

  • Windows 7 Ultmate SP1(俄语,所有更新安装)与MSVS2012(英语/ rusian)更新1
  • Windows 8(在虚拟机上)

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

问题:

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

我对解决这个问题的任何建议持开放态度。 此外,如果您无法重现该问题,请在评论中留下简短的系统说明。

所以,它实际上是一种设计行为,如果有人有类似的问题,这里的代码总是输出相同的结果:

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

另请注意,使用WindowChrome并且现在作为.NET 4.5的一部分出现的RibbonWindow WPF控件不知道这些更改并显示杂乱的窗口边框(幸运的是,我认为可以使用修改的样式来修复)。