我有一个问题,即应用程序(用 Delphi 编写)在所有系统上的默认 96 DPI 设置下表现正常,但在不同系统上的“150% 文本大小”(内部 144 dpi)设置下表现不一致。似乎在某些系统上,我的应用程序的某些文本/字体部分正在被拉伸,而在其他系统上,它们不是。我会认为我的应用程序,在某个版本的 Windows (Win7) 上,在某个 DPI 上,应该以相同的方式运行。
我的应用程序要么让 Windows 知道它不需要 DPI 虚拟化功能,要么不需要。我就这么理解。我不明白的是,DPI 变化如何导致两台机器上出现不同的外观,两台机器都运行 Windows 7,都是 144 dpi,以相同的固定大小显示相同的字体和表单。
我需要在 Windows(注册表等)中检查 DPI 虚拟化中涉及的一些与配置相关的元素吗?否则,您如何排除故障并知道是否在您的客户端窗口上进行了 DPI 虚拟化?
在 Delphi 中,如果不想缩放,则必须将 TForm.Scaled 属性设置为 false。但我不明白的是,当主窗体的 Scaled 属性为真时,我不能总是预测结果。
在我的应用程序中最令我困惑的是,我有一个控件,它只会在我的大型实际应用程序中出现异常,但在我尝试仅调试控件的独立应用程序中不会出现异常。为了理解独立应用程序中的控制行为,我被迫制作了一个演示应用程序,我通过清单文件强制 DPI 感知。然后我可以重现控制绘图故障,尽管形式不同。
这是我在演示应用程序中使用的清单文件,它暴露了我的控件在处理 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 会导致问题,而在某些形式中,它可以解决它:
更新:事实证明,我的某些控件使用 GDI+,并且 GDI+ 上下文中的字体行为与普通 GDI 上下文中的字体行为不同,至少对于某些使用 GDI+ 的第三方控件而言。这是头痛的主要来源。其次,对于 DPI 意识,VCL 中存在参差不齐的测试覆盖率和定义不明确的要求。一些 VCL 控件基于 MS 通用控件,虽然可以公平地说底层的通用控件在高 DPI 情况下可能工作正常,但并非所有 VCL 控件包装器都能保证正常工作。因此,检查应用程序在其所有控件中的高 DPI 意识,以及所有可用 Windows 7 主题中的正确行为:
- aero glass on,96dpi(大多数现代硬件上的默认 Win7 外观)
- 基本主题(航空玻璃关闭)但启用了 xp 主题
- 经典的win2000外观玻璃关闭,以及xp级别的主题,
- 高对比度白色
- 高对比度黑色
- 各种非 96 DPI 设置
..而且不胜枚举。作为应用程序开发人员,您的负担相当沉重。无论您是使用 VCL 的 delphi 用户,还是 MFC/ATL C++ 开发人员,在我看来,支持所有各种古怪的 windows 模式几乎是一个难以承受的负担。所以大多数人都不会打扰。我对吗?