缩放的操作系统 DPI 上的 WPF 窗口大小不正确(DPI 感知/DPI 感知)

WPF Incorrect Window Size On Scaled Operating System DPI (DPI-Aware/DPI-Unaware)

提问人:Cyclone 提问时间:11/13/2023 最后编辑:Cyclone 更新时间:11/15/2023 访问量:47

问:

我在 WPF 中遇到了一个奇怪的问题,假设我们有一个固定大小为 512x512 像素的窗口,现在当我们在具有 125% 缩放比例的操作系统中运行此 WPF 应用程序时,创建的窗口大小将为 640x640 像素,这意味着原始大小乘以 1.25。

我希望我的窗口是 512x512,而不考虑操作系统的缩放值。我尝试了互联网上提供的所有解决方案:

  • 设置和在 app.manifestdpiAwaredpiAwareness
  • app.config 中设置为 falseSwitch.System.Windows.DoNotScaleForDpiChanges
  • 在程序集信息.cs 中设置[assembly: System.Windows.Media.DisableDpiAwareness]
  • 将 WPF 包装在本机窗口中

所有方法都会导致相同的无效窗口大小。请注意,在 DPI 感知模式和 DPI 无感知模式之间切换只会导致窗口内的视觉效果模糊和锐利视觉效果,例如,如果我将 dpi 感知设置为按钮的真实文本,则按钮将清晰锐利。

这是我准备的一个最小的示例项目:https://github.com/CycloneRing/Issue-WPFWindowScaleDPI

有什么办法可以解决这个问题吗?我不想手动修复 WPF 窗口的大小。

125% 与 100% :situation

我想出的唯一解决方案是使用本机导入设置窗口大小:

private void WindowLoaded(object sender, RoutedEventArgs e)
{
  IntPtr hWnd = new WindowInteropHelper(this).Handle;
  SetWindowPos(hWnd, IntPtr.Zero, 0, 0, (int)this.Width, (int)this.Height, 0x0002 | 0x0004 | 0x0020);
}

但这并不能解决主要问题,这样做的一个副作用是 wpf 窗口中的单位仍然会乘以 1.25。

注意:我有一个理论,由于WPF窗口在HwndWrapper中运行,也许dpi设置不会影响HwndWrapper,并且它始终使用窗口缩放值。

C# WPF Windows DPI

评论


答:

0赞 Haiming 11/15/2023 #1

我想说的是,在 WPF 应用程序中使用固定分辨率并不是一个明智的选择。 大多数时候,开发人员很难限制用户的 dpi 选择,因为您可能永远不知道您的应用程序当前在哪种硬件上运行。

因此,我建议你让你的应用程序能够感知dpi,这在WPF中是非常可行的。所有控件和布局的大小都取决于主窗口的实际大小,这是一个好主意。

下面是一些有用的链接: Windows 窗体 DPI 缩放 创建 DPI 感知应用程序