如何在 C# 中更改 DPI 缩放行为

How to Change DPI Scaling behavior in C#

在我们的应用程序中,我们有一些功能无法在 4k 显示器上正常工作。当我们右键单击可执行文件并更改兼容性设置时,我们可以通过更改以下设置来使事情正常工作。

我的问题是:是否可以从 WPF 应用程序的 c# 代码中更改以红框突出显示的这两个设置?我想执行一个方法,改变这些设置,当5秒的计时器结束时,我想把它们改回来。

以下是我如何获取我正在识别的屏幕的坐标。

private void btn_identifyScreens_Click(object sender, RoutedEventArgs e)
{
   int screenNumber = 1;
   foreach (System.Windows.Forms.Screen screen in System.Windows.Forms.Screen.AllScreens)
   {
       NumberSplash numberSplash = new NumberSplash(screenNumber);
       numberSplash.Left = screen.WorkingArea.Left;
       numberSplash.Top = screen.WorkingArea.Top;
       numberSplash.Width = screen.WorkingArea.Width;
       numberSplash.Height = screen.WorkingArea.Height;
       numberSplash.Show();
       screenNumber++;
   }
}

如果你不想弄乱 win32-api 你可以在 app-manifest 中为你的应用程序设置 dpi-awareness。例如,每个监视器 dpi-awareness:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
...
    <application xmlns="urn:schemas-microsoft-com:asm.v3">
        <windowsSettings>
            <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
     <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
         PerMonitor   
     </dpiAwareness>
        </windowsSettings>
    </application>
...
</assembly>

见上文GitHub:https://github.com/Microsoft/WPF-Samples/tree/master/PerMonitorDPI

如果你想 fine-grained 控制你的应用程序,我相信你可能必须使用 win-api。这里有一篇很棒的文章对此进行了描述:https://blogs.windows.com/buildingapps/2017/04/04/high-dpi-scaling-improvements-desktop-applications-windows-10-creators-update/

您也可以直接设置注册表项 Computer\HKEY_CURRENT_USER\Control Panel\Desktop(但这将影响所有程序,正如 Ben 在下面的评论中指出的那样) 键在这里描述:https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/dpi-related-apis-and-registry-settings

编辑: 第一种方法是使应用程序 DPI-aware 使用清单,然后如果您需要应用程序处理 dpi-changes 并使其真正 DPI-aware 您将需要查询 GetDpiForMonitor (对于每个监视器意识)。这里有一个与包装器类似的问题:

2:nd Edit: 这里的注释后是一个在每个屏幕上显示监视器数字的示例:https://gitlab.com/mattincode/wpf_dpi_aware.git