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