Windows 标题栏中启用 VCL 样式的应用程序和显示缩放中的视觉错误

Visual bug in Windows title bar with VCL Styles enabled application and display scaling

目前我正在测试启用 VCL 样式的应用程序的各个方面。

我注意到,Windows 缩放比例高于默认的 96 dpi/100%, VCL 窗体的图标和标题栏文本尺寸太大 - 两者要靠在一起 - 请参阅随附的屏幕截图。对于 200% 或 250%(例如用于 4K 显示器和 Windows 10)的更高缩放比例尤其如此,但即使缩放比例为 144 dpi/150%,问题也已经很明显。

RAD Studio 提供的所有样式都是如此。通过项目设置启用清单的高 Dpi 感知。 如果我在应用程序中禁用 VCL 样式,图标和标题栏文本的大小是正确的。

我是不是漏掉了什么?在启用显示缩放的情况下,交付的样式不应该在没有开箱即用的显示错误的情况下工作吗?或者是否有一些我可以调整的设置来解决这个问题。

谢谢,

VCL 样式不正确支持高 DPI 缩放。

如果您使用 VCL 样式,则应从您的应用程序清单中删除高 DPI 感知。


QP 报告要求对 VCL 样式提供一般高 DPI 支持: VCL styles don't scale properly under high DPI configurations

NC区域相关QC报告:Styled form's non-client area incorrectly scaled under High DPI

好的,这是我针对视觉错误的解决方案,请参阅附件截图。我在 Vcl.Forms.pas.

中修复了 3 个地方

第一个修复,注释为 // Title bar fix 1,解决了图标未正确绘制的问题,即使没有缩放,在默认 96dpi Windows 上使用 VCL 样式的应用程序。我可以根据 James Johnston 关于 WM_GETICON、ICON_SMALL2 的调查结果来解决这个问题, https://whosebug.com/a/35067909 谢谢,詹姆斯,为此!

另外两个修复解决了启用显示缩放后图标绘制过大以及图标与标题栏文本之间的距离过小的问题。这些是代码中用 // Title bar fix 2 和 3 注释的修复。 GetDpi 只是当前 dpi 值的 getter,我从应用程序中的 C 源代码中获取该值。

结果绝不是完美的,但就目前而言,VCL 风格的应用程序至少在缩放的情况下是可以接受的。

感谢大家的参与。

这是一个允许在 DPI 感知应用程序中使用 VCL 样式的单元。

VCL.Styles.DPIAware.pas

要使用该单元,只需将​​其添加到主窗体的 uses 语句中,并将以下代码添加到 FormCreate 处理程序中。

procedure TFrmMain.FormCreate(Sender: TObject);
Var
  StyleDPIAwareness : TStyleDPIAwareness;
begin
  StyleDPIAwareness := TStyleDPIAwareness.Create(Self);
  StyleDPIAwareness.Parent := Self;

默认情况下,组件以 100% 的倍数缩放样式。您可以通过添加以下行来更改它:

StyleDPIAwareness.RoundScalingFactor := False;

使用此语句,样式将缩放到 Screen.PixelsPerInch 的任何缩放因子结果。大多数样式都可以正常工作,但少数样式可能会出现一些视觉缺陷。