【问题标题】:Incorrect screen width and height reported by Delphi 3Delphi 3 报告的屏幕宽度和高度不正确
【发布时间】:2015-02-22 20:30:57
【问题描述】:

我有一个 Delphi 3 应用程序,它已经广泛分布了至少十年。今天我收到一份报告,称该应用程序在 Asus Transformer T100TA-C1-GR(S) Windows 8 平板电脑上无法正常运行。具体来说,该应用程序拒绝运行,因为它检测到屏幕分辨率太小,以至于应用程序无法正确显示自身。在应用程序中,我有以下条件检查:

 if (Screen.Width < 800) or (Screen.Height < 600) then begin
    // display a message reporting screen resolution too low
    ShowMessage('blah blah...');
    Application.Terminate;

当我编译了我的应用程序的特殊版本以帮助调试问题并将应用程序提供给投诉用户时,他们报告了以下数字:

    Width: 980
    Height: 550

这是我添加的特殊编译的额外代码,然后我提供给用户:

 ShowMessage('Width: ' + IntToStr(Screen.Width) + #13#10 +
    'Height: ' + IntToStr(Screen.Height));

但是,用户发誓他们的平板电脑配置为 1368x768。他们甚至切换到 1024x768 并且 Delphi 报告了相同的错误数字。

所有 TForm.Scaled 属性都设置为 False。

一个可能有帮助的线索...屏幕宽度和高度检测代码(上)在以下过程中运行:

 procedure TForm1.WMDisaplayChange(var m: TWMDisplayChange);

知道会发生什么吗?

【问题讨论】:

  • 让他们在兼容性设置中设置禁用显示缩放。
  • 这意味着操作系统错误地报告了屏幕尺寸,而不是 Delphi 3。Delphi(甚至 3)通过 API 调用(特别是 GetSystemMetrics)检索它们,因此它报告的是操作系统告诉它的内容.

标签: delphi


【解决方案1】:

您的应用程序受制于 DPI 虚拟化。您的应用尚未向系统表明它知道并支持高 DPI 显示设备。有问题的机器使用大于 125% 的字体缩放比例。那是高 DPI 截止点。除了该缩放之外,系统还会为非 DPI 感知应用程序虚拟化字体缩放。来自documentation

Windows Vista 引入了一项称为 DPI 虚拟化的功能,该功能为不支持 DPI 的应用程序提供一定程度的自动缩放支持。借助此功能,Windows 可以缩放不支持 DPI 的应用程序的文本和 UI 元素的大小,以便在不更改应用程序的情况下在高 DPI 设置下适当调整它们的大小。这可以防止应用程序在高 DPI 屏幕上呈现过小的潜在可用性和可读性问题。

在 Windows Vista 到 Windows 8 中,此功能为不支持 DPI 的应用程序提供“虚拟化”系统指标和 UI 元素,就好像它们以 96 DPI 运行一样。然后应用程序渲染到 96 DPI 的屏幕外表面,DWM 缩放生成的应用程序窗口以匹配 DPI 设置。例如,如果 DPI 显示设置为 144,则 DWM 会将应用程序的窗口缩放 150%,即 144/96。

这样做的结果是系统会伪造屏幕尺寸。当您的应用程序被 DPI 虚拟化时,系统会报告虚拟化维度而不是真实维度。

最佳做法是声明您的应用程序支持高 DPI,并根据用户的字体缩放首选项缩放 UI。当然,这对你来说将是一个很大的变化。可能不是您想要的。

另一个选项是要求用户使用缩小的字体缩放。他们可能也不会对此非常热衷。

另一种选择是让您的应用具有高 DPI 感知能力,并继续不对其进行扩展。然后它肯定会运行,但它不会尊重用户的字体缩放偏好。再一次,我想用户会不高兴。

如果您当前没有显示您的应用,那么现在这样做会导致它没有被虚拟化。我的意思是应用程序虚拟化而不是 DPI 虚拟化。虽然您确实不应该仍然运行虚拟化,但如果禁用虚拟化,您可能会遇到麻烦。

Sertac 提出了另一种选择。让用户为您的应用应用兼容性设置以禁用 DPI 虚拟化。您可以将它应用到现在的应用程序中,而无需重新编译,至少您的用户能够取得进展。

从根本上说,您的用户的机器设置存在问题。如果它有 768 个垂直像素和大约 140% 的缩放比例,那实际上是 550 像素的 100% 缩放比例。这不是很多像素。您的应用程序正在反对,因为屏幕太小,而且,也许确实是这样。

这里的各种答案可能对您有用:How do I make my GUI behave well when Windows font scaling is greater than 100%

【讨论】:

  • 如果应用程序在启动时检查分辨率是有原因的(而不仅仅是为了惹恼用户),高 DPI 意识将不是解决方案:UI 元素不适合可用空间。在这种情况下,使用禁用该应用程序显示缩放的兼容性设置可能是唯一的解决方案(没有强制用户更改系统/监视器的 DPI 设置)。
  • @Sertac 没有缩放的高 DPI 将允许应用程序运行,尽管用户会很生气。这与禁用缩放几乎相同。
  • 是的,我看到了编辑,+1。不过,兼容性设置可能仍然是首选,为了给用户一个选项,他/她可能有更大的显示器等。
  • David 回答:“最佳实践是声明您的应用程序具有高 DPI 感知能力……”而我将如何使用 Delphi 3 来做这样的事情?
  • 与任何 Windows 应用程序相同。将 DPI 感知设置添加到您的应用清单。你是否有一个?而且您还需要扩展应用程序的用户界面。不是一项微不足道的任务。我在答案的底部添加了一个有用的链接。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 2015-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多