You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi不同屏幕分辨率下硬编码坐标自动缩放适配问题咨询

问题原因

你遇到的缩放差异本质是DPI感知配置不同导致的:

  • 旧版Delphi 10编译出的程序默认未声明高DPI感知,Windows会在高DPI设备上对程序窗口做系统级位图拉伸,硬编码的固定坐标会跟着拉伸,看起来比例正常,但这种缩放会导致界面文字、图形模糊。
  • Delphi 10.4 Community Edition默认开启了Per Monitor V2 高DPI感知,此时系统不再做自动位图拉伸,所有传入画布、控件API的坐标默认按当前显示器物理像素计算,裸写的固定像素值不会随DPI缩放;而ClientWidth、ClientHeight这类属性本身是VCL框架经过DPI换算后的值,所以可以正常适配缩放。
无需批量修改硬编码坐标的解决方法

方法1:调整项目DPI配置(零代码修改,和旧程序表现完全一致)

如果不需要高DPI下的清晰显示效果,直接把项目DPI感知模式改成和旧Delphi一致即可,操作步骤:

  1. 打开项目后依次进入 Project -> Options -> Application -> Manifest
  2. 在DPI Awareness下拉菜单中选择Unaware,重新编译后程序就会和你旧笔记本编译的版本完全一样,由Windows自动完成缩放,不需要改任何代码。

注意:该方案的缺点是高DPI下界面会存在系统拉伸带来的模糊感。

方法2:使用VCL内置缩放方法(保留高DPI清晰度,最小化代码修改)

Delphi 10.4的VCL框架内置了DPI缩放的辅助方法,不需要手动计算缩放比,只需要对硬编码的96DPI设计值做一层简单包裹即可:
所有你在96DPI下写的固定像素坐标、尺寸值,用窗体/控件自带的ScaleValue方法包裹,框架会自动根据当前设备DPI换算成正确的物理像素值。
针对你给出的绘图代码,修改示例如下:

procedure TForm1.Button1Click(Sender: TObject);
begin
  with Canvas do
  begin
    MoveTo(0,0);
    // 对96DPI下的硬编码值做缩放转换
    LineTo(ScaleValue(400), ScaleValue(250));
    MoveTo(0,0);
    LineTo(ClientWidth,ClientHeight);
  end;
end;

如果代码里硬编码值非常多,不想逐处修改,可以直接把窗体的Scaled属性保持为默认开启的True,在项目源码(一般是.dpr文件的begin块)里加一行Application.MainFormOnTaskBar := True; 之后设置全局Screen.PixelsPerInch := 96;,VCL会自动对所有运行期的坐标、尺寸做全局缩放,效果比系统位图缩放更清晰,不需要逐行改业务代码。

长期适配建议

后续开发时尽量避免裸写固定像素值,优先用相对尺寸(比如基于ClientWidth、ClientHeight的比例值),或者统一用逻辑坐标(96DPI为基准)配合LogicalToPhysicalPoint、PhysicalToLogicalPoint方法做转换,就不需要反复适配不同DPI的设备。

内容的提问来源于stack exchange,提问作者Rudi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:54:19