Задать вопрос
semennovikov123
@semennovikov123
Backend Developer

Как исправить размытый текст в Windows Forms?

В любых проектах win forms текст размытый , причём в редакторе всё нормально . Даже при переносе проекта с другого компьютера где текст чёткий , на моём становится всё плохо . Прикрепляю скрины редактора и запущенного приложения .
У меня Windows 10, Visual Studio 2017 . Изменение версии net.framework не помогает . Может быть сглаживание текста в настройках убрать , всё пролазил , не нашёл .
5acf73521f0ed515042302.png5acf73565c413096745749.png
  • Вопрос задан
  • 6102 просмотра
Подписаться 1 Простой Комментировать
Решения вопроса 1
VoidVolker
@VoidVolker Куратор тега C#
Dark side eye. А у нас печеньки! А у вас?
Гуглите DpiAware — изучите проблемы и выберете оптимальное решение для себя. Тут проблема в диком легаси наследии, реализованном через костыли и которое пытаются сохранить, добавляя исправления в виде костылей, которые генерируют новые баги и в новых версиях это пытаются исправить опять костылями. Кроме того, алгоритм работы масштабирования немного отличается в разных версиях ОС. Так что очень рекомендую проверять работу приложения в разных версиях ОС (7, 8.1, 10 Home, 10 Enterprise LTS) и с выключенным и включенным масштабированием. Да-да, в домашней десятке и в корпоративной долгосрочной десятке можно получить разный результат.

Вариант 1 — вызов специальной функции в коде (реальный код, который я использую — плюс вторая функция для масштабирования шрифтов, тык — примерно так получается в 4к):
const int WinDefaultDPI = 96;

/// <summary>
/// Исправление блюра при включенном масштабировании в ОС windows 8 и выше
/// </summary>
public static void DpiFix()
{
    if (Environment.OSVersion.Version.Major >= 6)
    {
        SetProcessDPIAware();
    }
}

/// <summary>
/// WinAPI SetProcessDPIAware 
/// </summary>
/// <returns></returns>
[DllImport("user32.dll")]
private static extern bool SetProcessDPIAware();

/// <summary>
/// Исправление размера шрифтов
/// </summary>
/// <param name="c"></param>
public static float DpiFixFonts(Control c)
{
    Graphics g = c.CreateGraphics();
    float dx = g.DpiX
        , dy = g.DpiY
        , fontsScale = Math.Max(dx, dy) / WinDefaultDPI
    ;
    g.Dispose();
    return fontsScale;
}


Плюс все формы имеют следующий конфиг (код, вызываемый в конструкторах форм):
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;


Учтите, что AutoScaleDimensions — в конструкторе выставляется автоматически в зависимости от разрешения и DPI вашего монитора. Поэтому я не использую конструкторы. Иначе, при запуске приложения на разных машинах с разным DPI можно получить очень неожиданные результаты.

Вариант 2 (v4.7):
app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
  </startup>
  <System.Windows.Forms.ApplicationConfigurationSection>
    <add key="DpiAwareness" value="PerMonitorV2" />
    <add key="EnableWindowsFormsHighDpiAutoResizing" value="true" />
  </System.Windows.Forms.ApplicationConfigurationSection>
</configuration>


Вариант 3 (v4.7):
app.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
  </configSections>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7" />
  </startup>
  <System.Windows.Forms.ApplicationConfigurationSection>
    <add key="DpiAwareness" value="PerMonitorV2" />
    <add key="EnableWindowsFormsHighDpiAutoResizing" value="false" />
  </System.Windows.Forms.ApplicationConfigurationSection>
<configuration>


Вариант 4:
app.manifest
<!-- Указывает, что приложение поддерживает определение DPI и не будет автоматически масштабироваться Windows при более высоких
       значениях DPI. Приложения Windows Presentation Foundation (WPF) по умолчанию поддерживают определение DPI, им не нужно 
       специально включать параметр для этого. Для приложений Windows Forms на платформе .NET Framework 4.6, для которых задан этот параметр, необходимо 
       также задать для "EnableWindowsFormsHighDpiAutoResizing" значение "true" в файле app.config.-->
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@alexalexes
В поиске меню Пуск забиваем "ClearType". Выходит эта самая настройка опции. Она?
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы