如何配置应用程序以在具有高DPI设置(例如150%)的计算机上正确运行?

Bor*_*ris 86 c# fonts dpi winforms dpi-aware

我在C#中创建了一个简单的Winforms应用程序.当我在具有高DPI设置(例如150%)的计算机上运行应用程序时,应用程序会按比例放大.到现在为止还挺好!但是,不是使用更高的字体大小渲染字体,所有文本也只是按比例放大.这当然导致非常模糊的文本(在按钮等所有控件上).

窗户不应该正确地渲染文本吗?例如,我的应用程序的标题栏呈现清晰明了.

Han*_*ant 121

一旦超过100%(或者通过"XP风格的DPI缩放"复选框选中125%),Windows默认会接管UI的缩放.它通过让您的应用将其输出呈现为位图并将该位图绘制到屏幕来实现.该位图的重新缩放使得文本不可避免地看起来模糊.这是一种名为"DPI虚拟化"的功能,它使旧程序可用于高分辨率监视器.

您必须明确告知它可以通过向<dpiAware>清单添加元素来处理更高的DPI设置.MSDN页面在这里,但它没有完成,因为它省略了UAC设置.Project + Add New Item,选择"Application Manifest File".编辑清单文本或复制/粘贴此文件:

<?xml version="1.0" encoding="utf-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >
    <assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
        <security>
            <requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
                <requestedExecutionLevel level="asInvoker" uiAccess="false" />
            </requestedPrivileges>
        </security>
    </trustInfo>
    <asmv3:application>
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
</assembly>
Run Code Online (Sandbox Code Playgroud)

您还可以在Main()方法中调用SetProcessDPIAware(),例如,如果使用ClickOnce进行部署,则必需:

    [STAThread]
    static void Main() {
        if (Environment.OSVersion.Version.Major >= 6) SetProcessDPIAware();
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());             // Edit as needed
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern bool SetProcessDPIAware();
Run Code Online (Sandbox Code Playgroud)

更新,如果您使用VS2015 Update 1或更高版本,这种常见需求最终会更容易一些.添加的清单已经有相关指令,只需删除注释即可.


搜索关键字,所以我可以找回这篇文章:dpiAware

  • Hmya,Windows 8.1获得了每台显示器的DPI.我不知道我需要那个. (5认同)
  • 对于任何调查Win8疯狂的人来说,不推荐使用`SetProcessDPIAware`,它也无法正常工作(至少在Win8.1中没有),导致不同控件上出现不可预测的缩放.我强烈建议使用清单方法. (2认同)

sha*_*ika 15

应用程序可以以两种不同的模式开发.

第一个是声明我们的应用程序是非DPI感知的(不会声明任何默认的东西).在这种情况下,操作系统将使我们的应用程序在预期的96 DPI下呈现,然后将对我们之前讨论过的位图缩放进行处理.结果将是一个模糊的应用程序,但具有正确的布局.

第二种选择是将应用程序声明为DPI感知.在这种情况下,操作系统不会进行任何缩放,并会让您的应用程序根据屏幕的原始DPI进行渲染.在每个监视器DPI环境的情况下,您的应用程序将以所有屏幕的最高DPI进行渲染,然后该位图将缩小到适合每个监视器的大小.降尺度比升级产生更好的观看体验,但您可能仍会注意到一些模糊性.

如果要避免这种情况,则必须将应用程序声明为per-monitor-DPI-aware.然后,您必须检测何时将应用程序拖过不同的监视器并根据当前DPI的DPI进行渲染.

声明DPI感知是在清单文件中完成的.

请参阅以下链接 stackoverflow


Wol*_*ich 6

使用 .NET Framework 4.7 和 Windows 10 Creators Update (1703) 或更高版本,您必须执行以下操作才能为 Windows 窗体应用程序配置高 DPI 支持:

声明与 Windows 10 的兼容性。

为此,请将以下内容添加到您的manifest文件中:

<compatibility xmlns="urn:schemas-microsoft.com:compatibility.v1">
  <application>
    <!-- Windows 10 compatibility -->
    <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
  </application>
</compatibility>
Run Code Online (Sandbox Code Playgroud)

app.config文件中启用每个显示器的 DPI 感知。

Windows 窗体引入了一个新的System.Windows.Forms.ApplicationConfigurationSection元素,以支持从 .NET Framework 4.7 开始添加的新功能和自定义。要利用支持高 DPI 的新功能,请将以下内容添加到您的应用程序配置文件中。

<System.Windows.Forms.ApplicationConfigurationSection>
  <add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
Run Code Online (Sandbox Code Playgroud)

重要的

在 .NET Framework 的早期版本中,您使用清单来添加高 DPI 支持。不再推荐此方法,因为它会覆盖 app.config 文件中定义的设置。

调用静态 EnableVisualStyles 方法。

这应该是应用程序入口点中的第一个方法调用。例如:

static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());   
}
Run Code Online (Sandbox Code Playgroud)

这样做的优点是支持动态 DPI 方案,其中用户在启动 Windows 窗体应用程序后更改 DPI 或比例因子。

来源:Windows 窗体中的高 DPI 支持


小智 5

这些建议都不适合我,但是,在我Form.Font = new从 中删除 ...后发生了一些事情Form.Design.cs,表单开始正确地重新缩放,如果在构造函数中定义了字体或根本没有定义字体,它就可以工作。为什么?其他人可能能够解释,我只能谈论我所做的更改,并花了我几分钟时间才弄清楚这是我正在处理的表单的根本原因。希望能帮助到你。