7

在 .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(英语/俄语)更新 1
  • Windows 8(在虚拟机上)

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

问题:

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

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

4

2 回答 2

6

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

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

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

于 2013-02-06T10:18:48.273 回答
3

根据微软的说法,这是设计使然。

请参阅此处了解完整详情:

尽管 MS 说这是“设计使然”,但我仍然认为这是一个错误!

于 2013-02-06T09:56:50.633 回答