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 (английский / русский), обновление 1
  • Windows 8 (на виртуальной машине)

В настоящее время я думаю о исправлении некоторых классов.NET (SystemParameters например), который называют GetSystemMetrics() используя отражение, но я не уверен, как получить правильные значения метрики.

Вопросы:

  • Я что-то пропустил? Как может GetSystemMetrics() быть затронутым целевой структурой?
  • Есть ли способ позвонить GetSystemMetrics() из приложения.NET 4.5 и получить правильные результаты?

Я открыт для любых предложений по исправлению этой проблемы. Кроме того, если вы не можете воспроизвести проблему, оставьте краткое описание системы в комментариях.

2 ответа

Решение

По словам Microsoft, это является второстепенным.

Смотрите здесь для полной информации:

http://connect.microsoft.com/VisualStudio/feedback/details/763767/the-systemparameters-windowresizeborderthickness-seems-to-return-incorrect-value

https://connect.microsoft.com/VisualStudio/feedback/details/753224/regression-getsystemmetrics-delivers-different-values

Несмотря на то, что MS говорит, что это "по замыслу", я все еще думаю, что это ошибка!

Итак, на самом деле это поведение на основе разработки, и если у кого-то есть похожие проблемы, вот код, который всегда выдает один и тот же результат:

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 WPF control, который использует WindowChrome и теперь входит в состав.NET 4.5, не знает об этих изменениях и отображает грязные границы окна (к счастью, я думаю, что это можно исправить с помощью измененных стилей).

Другие вопросы по тегам