gpt4 book ai didi

delphi - 对 Windows Vista 和 Windows 7 中的 DPI 虚拟化和 DPI 感知应用程序进行故障排除

转载 作者:行者123 更新时间:2023-12-03 14:35:08 26 4
gpt4 key购买 nike

我遇到一个问题,应用程序(用 Delphi 编写)在所有系统上的默认 96 DPI 设置下表现正常,但在不同系统上的“150% 文本大小”(内部 144 dpi)设置下表现不一致。似乎在某些系统上,我的应用程序的某些文本/字体部分正在被拉伸(stretch),而在其他系统上,它们则没有。我本以为我的应用程序在特定版本的 Windows (Win7) 上、在特定的 DPI 下应该具有相同的行为方式。

我的应用程序要么会让 Windows 知道它不需要 DPI 虚拟化功能,要么不会。我就明白这么多了。我不明白的是 DPI 更改如何导致两台计算机上的外观不同,这两台计算机都运行 Windows 7,均为 144 dpi,以相同的固定尺寸显示相同的字体和表单。

DPI 虚拟化中是否存在一些我需要在 Windows 中检查的依赖于配置的元素(注册表等)?否则,您如何排除故障并了解 DPI 虚拟化是否正在客户端窗口上完成?

在 Delphi 中,如果不想缩放,则必须将 TForm.Scaled 属性设置为 false。但我不明白的是,当主窗体的 Scaled 属性为 true 时,我不能总是预测结果。

在我的应用程序中,最让我困惑的是,我有一个控件,它只在我的大型实际应用程序中表现不佳,但在我试图调试该控件的独立应用程序中却不会表现不佳。为了了解独立应用程序中的控制行为,我被迫制作一个演示应用程序,在其中通过 list 文件强制 DPI 感知。然后我可以重现控制绘图故障,尽管形式不同。

这是我在演示应用程序中使用的 list 文件,它暴露了我的控件在处理 Windows 中的高 dpi 设置时遇到的问题。然而,我发现的一件奇怪的事情是应用程序是可能的

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings
xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>
<assemblyIdentity version="14.0.3615.26342" processorArchitecture="*"
name="TestProject" type="win32"></assemblyIdentity>
<description>High DPI Controls Test App</description>
</assembly>

以下是当我在应用程序中禁用 DPI 虚拟化时,应用程序中的控件出现困惑的大约 30 个地方之一的示例。通过关闭我表单中的 Scaled 属性解决了这个特殊的问题。但在其他地方,TForm.Scaled=false 会导致问题,而在某些形式中,它可以解决问题:

DPI Glitch Example with a non-DPI-virtualized app manifest, but main form is Scaled

更新:事实证明,我的一些控件使用 GDI+,并且 GDI+ 上下文中的字体行为与正常 GDI 上下文中的字体行为不同,至少对于某些使用 GDI+ 的第三方控件而言是如此。这是令人头痛的一个主要原因。其次,VCL 中对于 DPI 感知的测试覆盖率参差不齐,且要求定义不明确。一些 VCL 控件基于 MS 通用控件,虽然可以公平地说,底层通用控件可能在高 DPI 情况下工作正常,但并非所有 VCL 控件包装器都能保证正确工作。因此,检查应用程序的所有控件是否具有高 DPI 意识,以及所有可用的 Windows 7 主题中的正确行为:

  1. 打开毛玻璃,分辨率为 96dpi(大多数现代硬件上的默认 Win7 外观)
  2. 基本主题(空气动力学玻璃关闭),但启用 XP 主题
  3. 经典的 win2000 外观,以及 XP 级别的主题,
  4. 高对比度白色
  5. 高对比度黑色
  6. 各种非 96-DPI 设置

..这样的例子不胜枚举。作为应用程序开发人员,您的负担相当沉重。无论您是使用 VCL 的 delphi 用户,还是 MFC/ATL C++ 开发人员,在我看来,支持所有各种古怪的 Windows 模式都是一个几乎难以承受的负担。所以大多数人都不会打扰。我说得对吗?

最佳答案

您需要通过如下部分来表明您的应用支持 DPI:

<asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
</asmv3:windowsSettings>
</asmv3:application>

如果您这样做,您将无法获得 DPI 虚拟化。

您并不打算使用 DPI 虚拟化,因此我认为尝试弄清楚它是如何工作的没有什么意义。它很容易依赖于显卡驱动程序。我们几乎不可能解释为什么虚拟化会这样:您甚至没有提供任何屏幕截图、硬件详细信息等。但是,您根本不应该费心去诊断这一点。显示为 dpiaware,这不是问题。

我为您提供引用:

关于delphi - 对 Windows Vista 和 Windows 7 中的 DPI 虚拟化和 DPI 感知应用程序进行故障排除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5080380/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com