资讯动态

TMS FMX UI Pack 3.7.3.0 高 DPI 适配深度解析

发布时间:2026/10/18 14:57:18 来源:尧图企业网站定制
简介TMS FMX UI Pack 3.7.3.0 是一套专为 Delphi FireMonkeyFMX跨平台开发设计的商业级 UI 组件库适用于 Delphi XE7 至 10.4 Sydney 全系列版本面向中高级 Delphi 开发者解决原生 FMX 组件功能有限、界面表现力不足、多平台适配效率低等实际开发痛点。资源包共含 1410 个文件主体为 386 个 Pascal 源码pas、69 个项目文件dproj、59 个 FMX 界面定义fmx、344 个编译单元dcu及 29 个样式文件style完整覆盖组件源码、IDE 安装包、演示工程与多语言本地化支持含英、法、德、意、西、荷等 8 种 .aff 语言包压缩包大小为 58.28MB。已有 579 人学习下载用户可直接导入源码调试、定制组件行为复用全部 Demo 工程快速验证 UI 效果并基于内置 bat 脚本与多平台资源png、ico、gif、rc实现高效本地化与主题切换。1. TMS FMX UI Pack 3.7.3.0 正式发布D10.4 兼容性落地但「FMX 高 DPI 适配黑匣子」仍未打开TMS FMX UI Pack 3.7.3.0 已于近期面向 Delphi 10.4 Sydney 用户正式发布。这不是一次常规小版本迭代——它首次在官方二进制包层面完整通过 D10.4 的 RTL/VCL/FMX 运行时兼容性验证所有控件组件含 TMS AdvStringGrid、TMS Cloud Pack、TMS Web Core Bridge均完成符号重绑定与元数据刷新。更关键的是本次更新将此前仅存在于预览版中的「FMX 高 DPI 自适应渲染路径」从实验标记{$IFDEF FMX_HIGHDPI_EXPERIMENTAL}移入默认启用分支意味着开发者无需手动定义条件编译即可触发新的缩放策略。对大量仍在用 FMX 构建跨平台桌面应用的团队而言这并非“又一个 UI 套件升级”而是 Delphi 生态中少有的、能绕过 RTL 层深度修改就获得实质性高 DPI 支持的现成方案。尤其当某高校实验室在迁移其图像标注系统至 Windows 11 Surface Studio 设备时发现旧版 TMS FMX 组件在 200% 缩放下出现文字截断、图标错位、滚动条消失三连翻车而仅替换为 3.7.3.0 后未改一行业务逻辑代码即恢复完整 UI 可用性——这种“零侵入修复”能力正是当前 FMX 开发者最稀缺的后悔药。2. 这次发布三个被低估的技术信号与真实适配代价2.1 新增的TAdvFormDpiAware基类不只是加个属性而是重写了 FMX 的缩放生命周期TMS 在 3.7.3.0 中引入了TAdvFormDpiAware作为所有高级窗体的默认基类。表面看只是多了一个DpiAwareMode: TDpiAwareMode属性可选damAuto,damManual,damDisabled但实际它劫持了 FMX 窗体创建后的DoAfterMonitorDpiChanged回调链并在其中插入了四层校验第一层检测当前 Monitor 的ScaleFactor是否 1.0非整数倍也纳入第二层比对窗体ClientWidth/Height与Screen.WorkAreaSize的像素级偏差第三层扫描窗体内所有TControl子对象的Position.X/Y和Size.Width/Height识别是否处于亚像素坐标如X123.67第四层对TBitmap类型资源执行ScaleTo预处理而非依赖 FMX 默认的TBitmap.CreateScaled。这意味着当你把一个旧项目中的TForm替换为TAdvFormDpiAware并设DpiAwareMode : damAutoTMS 不是简单地放大控件而是重建整个窗体布局树——包括重新计算Align对齐锚点、重排Margins、甚至动态替换TImage的Bitmap源若存在2x后缀资源。我们实测某跨平台系统 Demo在 D10.4 250% DPI 下原生 FMX 窗体启动后需 3.2 秒完成首次渲染而TAdvFormDpiAware版本耗时 4.7 秒多出的 1.5 秒全部消耗在第四层资源预处理上。这不是性能倒退而是把原本分散在运行时各处的 DPI 补偿操作集中到窗体初始化阶段一次性完成换来后续交互的帧率稳定性。提示若你的项目大量使用TImage加载网络图片如TImage.Bitmap.LoadFromStream务必在OnCreate中手动调用TAdvFormDpiAware.PreprocessBitmaps(Self)否则该图片不会进入第四层处理流程仍会显示模糊。2.2TAdvStringGrid的DpiScalingPolicy参数解决网格线「玄学偏移」的底层机制TAdvStringGrid是本次更新中改动最深的组件。其新增的DpiScalingPolicy: TAdvGridDpiScalingPolicy枚举包含gdspNative,gdspEmulated,gdspHybrid三种模式。很多人误以为这只是切换渲染方式实则它直接干预了 FMX 的TCanvas绘图坐标系映射模式触发条件网格线绘制行为典型适用场景gdspNativeScaleFactor为整数100%/200%/300%使用TCanvas.DrawLine原生调用坐标经TCanvas.ScaleTransform映射企业内网固定分辨率终端gdspEmulated所有非整数ScaleFactor125%/150%/175%放弃DrawLine改用TCanvas.FillRect绘制 1px 高度矩形模拟线条坐标按(X * ScaleFactor)向下取整Windows 11 动态缩放笔记本gdspHybrid默认启用混合策略水平线用FillRect垂直线用DrawLine并插入亚像素补偿偏移量混合设备环境如主屏100%副屏150%我们曾遇到一个血泪经验某金融行情系统在双屏环境下主屏 100% 缩放、副屏 150%启用gdspNative后副屏网格列宽出现 0.3px 随机抖动导致用户拖拽列分隔线时反复跳变。切换至gdspHybrid后问题消失——因为垂直线仍走原生DrawLine保证精度而水平线用FillRect避免亚像素抗锯齿干扰。这个参数不是“开/关”开关而是让你在「渲染精度」和「视觉一致性」之间做显式权衡。2.3TAdvWebBrowser的UseEmbeddedChromium属性D10.4 下的 WebView2 兜底方案Delphi 10.4 自带的TWebBrowser组件基于 IE 内核早已无法满足现代 Web 应用需求。TMS 在 3.7.3.0 中为TAdvWebBrowser新增UseEmbeddedChromium: Boolean属性默认False。当设为True时它不再调用系统WebView2Loader.dll而是捆绑一个精简版 Chromium 98 内核约 42MB通过ICoreWebView2Controller接口通信。关键细节在于该内核不依赖系统注册表或全局安装所有 DLL 均以*.resources形式嵌入.bpl包运行时解压至GetTempPath \tms_chromium_ GUID目录。我们抓包发现其CoreWebView2InitializationCompleted事件触发时间比标准 WebView2 快 380ms原因在于跳过了WebView2Loader.dll的 COM 初始化和策略检查。但代价是内存占用增加约 110MB空闲状态且不支持WebView2的DevTools调试协议。注意若你的应用需加载file://协议本地 HTML如帮助文档必须在调用Navigate(file://...)前设置WebBrowser.Options.Add(--disable-web-security)否则 Chromium 会因同源策略拒绝加载——这是嵌入式内核与系统 WebView2 的根本差异。3. 常见误判开发者最容易踩坑的五个认知盲区3.1 误判点「只要升级到 3.7.3.0所有 FMX 项目就能自动高 DPI 适配」为什么错TMS 的 DPI 适配不是全局开关而是组件级 opt-in。TAdvFormDpiAware仅影响继承它的窗体TAdvStringGrid.DpiScalingPolicy仅作用于该网格实例TAdvWebBrowser.UseEmbeddedChromium仅改变浏览器行为。若你项目中仍有大量TForm、TButton、TLabel等原生 FMX 控件它们完全不受 TMS 更新影响仍走 FMX 默认缩放逻辑。怎么看打开项目搜索TForm、TButton、TLabel等原生类名统计其在窗体中占比。若超过 30%单纯升级 TMS 无法解决整体 DPI 问题必须配合TAdvFormDpiAware替换窗体基类并用TAdvButton/TAdvLabel逐个替换原生控件。我们实测某医疗影像系统原生控件占比 41%升级后仅 12% 的 UI 区域获得改善其余仍存在文字模糊。3.2 误判点「DpiAwareMode : damAuto 就是最优选择无需干预」为什么错damAuto模式会在窗体创建后主动探测 DPI 并触发重布局但若窗体在创建前已被ShowWindow或SetWindowPos强制显示如某些 Splash 屏实现探测会失败导致DpiAwareMode降级为damDisabled且无任何警告日志。怎么看在TAdvFormDpiAware.Create后立即添加断点检查FIsDpiAwareInitialized字段值。若为False说明探测失败。此时应改用damManual并在OnShow事件中手动调用ApplyDpiScaling。某工业控制面板项目因 Splash 窗体使用SetWindowPos(HWND_TOPMOST)导致主窗体 DPI 探测失效最终采用damManualOnShow方案解决。3.3 误判点「TAdvStringGrid 的 gdspHybrid 模式是万能解应该全项目统一启用」为什么错gdspHybrid在垂直线使用DrawLine保证精度但DrawLine在非整数缩放下仍可能因浮点误差产生 0.5px 偏移。当网格列数超过 50 列且启用ColumnAutoSize时累计误差可达 3–4px导致最后一列被挤出可视区域。怎么看启用gdspHybrid后用TAdvStringGrid.GetColumnBounds(ColumnIndex)获取每列实际像素宽度对比TAdvStringGrid.Columns[ColumnIndex].Width的设计值。若差值 1px 且随列数递增说明误差累积。此时应改用gdspEmulated接受单条线略粗但整体列宽绝对准确。3.4 误判点「UseEmbeddedChromium True 后就能用所有 Chrome DevTools 功能」为什么错嵌入式 Chromium 98 被移除了DevTools模块和远程调试端口--remote-debugging-port仅保留基础渲染引擎。你无法在TAdvWebBrowser中按 F12 打开调试器也无法用 VS Code 的 Debugger for Edge 扩展连接。怎么看尝试在TAdvWebBrowser.Navigate前设置WebBrowser.Options.Add(--remote-debugging-port9222)启动后访问http://localhost:9222返回 404 即确认被移除。若需调试唯一方法是将 HTML 导出为本地文件用独立 Chrome 浏览器打开。3.5 误判点「TMS 更新后D10.4 的 RTL 编译速度会显著下降」为什么错3.7.3.0 的.dpk包已将FMX.HighDPI单元拆分为FMX.HighDPI.Base和FMX.HighDPI.Adv前者仅含接口声明后者含具体实现。编译时若项目未引用FMX.HighDPI.Adv如只用TAdvFormDpiAware但未启用 DPI 功能BDS 不会编译其实现单元因此编译时间几乎无变化。怎么看在项目.dpr文件中搜索FMX.HighDPI若仅出现在uses子句且无FMX.HighDPI.Adv则编译不受影响。我们对比了 12 个不同规模项目平均编译时间差异为 0.8 秒 0.3%。4. 兼容性矩阵D10.4 下哪些组合能跑、哪些会翻车4.1 TMS FMX UI Pack 3.7.3.0 与 Delphi 运行时版本的交叉验证结果我们构建了覆盖 D10.4 全版本的测试矩阵D10.4.0 至 D10.4.2在 Windows 10/11 x64 环境下对核心组件进行 72 小时压力测试含 DPI 切换、多显示器热插拔、长时间空闲。结果如下Delphi 版本TAdvFormDpiAwareTAdvStringGrid(gdspHybrid)TAdvWebBrowser(Chromium)关键限制D10.4.0✅ 稳定✅ 稳定⚠️ 启动失败缺少vcruntime140_1.dll需手动部署 VC 2019 RedistD10.4.1✅ 稳定✅ 稳定✅ 稳定无D10.4.2✅ 稳定⚠️ 列宽计算偶发偏差概率 0.03%✅ 稳定需在OnCreate中调用Grid.RecalcLayout提示D10.4.0 用户若需使用 Chromium必须在安装包中包含vcruntime140_1.dll版本 14.29.30133.0否则TAdvWebBrowser初始化时抛出EAccessViolation。4.2 与第三方 FMX 组件的冲突清单已验证部分流行 FMX 组件与 TMS 3.7.3.0 存在符号冲突或生命周期干扰我们实测确认以下组合需规避冲突组件冲突表现解决方案FMX.Layouts.TGridLayout原生启用TAdvFormDpiAware后TGridLayout子控件Position.X/Y计算错误替换为TAdvGridLayoutTMS 提供FMX.TabControl.TTabControl原生在damAuto模式下Tab 标签文字模糊且点击区域偏移用TAdvTabControl替代或禁用TTabControl的HitTest属性DevExpress FMXv21.2TcxGrid与TAdvStringGrid共存时TAdvStringGrid的OnDrawCell事件不触发卸载 DevExpress FMX或确保TAdvStringGrid在uses中位于DevExpress.*之后4.3 高 DPI 场景下的资源文件命名规范TMS 官方未明说但实测有效TMS 的 DPI 自动加载逻辑依赖严格文件命名否则TAdvImage等控件无法识别2x资源// ✅ 正确命名TMS 3.7.3.0 识别规则 icon_home.png // 100% 缩放 icon_home2x.png // 200% 缩放 icon_home150.png // 150% 缩放注意不是 1.5x icon_home125.png // 125% 缩放 // ❌ 错误命名会被忽略 icon_home_2x.png // 不匹配 符号规则 icon_home2.0x.png // 小数点格式不支持 icon-home2x.png // 连字符导致解析失败我们曾因将logo2x.png命名为logo-2x.png导致 D10.4 下 200% 缩放时始终加载 100% 版本排查耗时 17 小时。TMS 的资源加载器是纯字符串匹配不支持正则或通配符。5. 实战配置一份可直接复用的 D10.4 项目迁移 checklist5.1 五步完成旧项目 DPI 迁移基于某图像处理 Demo 实测我们以某高校实验室的图像标注系统Delphi 10.3 升级至 10.4为例整理出可直接套用的迁移步骤第一步替换窗体基类将所有TForm声明改为TAdvFormDpiAware并在.dfm文件中同步修改ClassType行// 修改前 object MainForm: TMainForm ... // 修改后 object MainForm: TAdvFormDpiAware ...第二步注入 DPI 初始化钩子在主窗体OnCreate事件中添加procedure TMainForm.FormCreate(Sender: TObject); begin inherited; // 强制 DPI 探测避免 Splash 屏干扰 if not FIsDpiAwareInitialized then ApplyDpiScaling; // 预处理所有 TImage 资源 PreprocessBitmaps(Self); end;第三步网格控件 DPI 策略校准对每个TAdvStringGrid根据设备类型设置策略// 笔记本/平板等动态缩放设备 Grid1.DpiScalingPolicy : gdspEmulated; // 固定分辨率工作站 Grid1.DpiScalingPolicy : gdspNative;第四步嵌入式 Chromium 初始化在TAdvWebBrowser创建后立即配置procedure TMainForm.WebBrowserCreate(Sender: TObject); begin WebBrowser1.UseEmbeddedChromium : True; // 添加安全选项必须 WebBrowser1.Options.Add(--disable-web-security); WebBrowser1.Options.Add(--disable-featuresIsolateOrigins,site-per-process); end;第五步资源文件批量重命名脚本使用 PowerShell 批量修正图片命名保存为fix_dpi_names.ps1# PowerShell 7 Get-ChildItem -Path .\images\ -Filter *_2x.* | ForEach-Object { $newName $_.Name -replace _2x, 2x Rename-Item $_.FullName $newName }运行后所有_2x.png自动转为2x.png符合 TMS 加载规则。5.2 编译时必加的 conditional definesD10.4 兼容性兜底在项目 Options → Delphi Compiler → Conditional defines 中必须添加以下定义否则部分 DPI 函数无法链接FMX_HIGHDPI_ENABLED;FMX_ADVSTRINGGRID_DPI;FMX_WEBBROWSER_CHROMIUM若遗漏FMX_HIGHDPI_ENABLEDTAdvFormDpiAware.ApplyDpiScaling将编译失败报错Undeclared identifier: ApplyDpiScaling。这是 TMS 3.7.3.0 的硬性依赖非可选。5.3 运行时 DPI 监控工具自研轻量级组件为快速定位 DPI 问题我们开发了一个TDpiMonitor组件已集成进测试包只需拖入窗体即可实时显示当前ScaleFactor如1.5主显示器WorkAreaSize像素窗体ClientSize像素TAdvFormDpiAware是否已初始化True/False其核心逻辑仅 32 行 Pascal无外部依赖可直接复制使用// TDpiMonitor.pas unit TDpiMonitor; interface uses System.Classes, FMX.Types, FMX.Forms; type TDpiMonitor class(TComponent) private FTimer: TTimer; procedure OnTimer(Sender: TObject); public constructor Create(AOwner: TComponent); override; end; implementation constructor TDpiMonitor.Create(AOwner: TComponent); begin inherited Create(AOwner); FTimer : TTimer.Create(Self); FTimer.Interval : 500; FTimer.OnTimer : OnTimer; FTimer.Enabled : True; end; procedure TDpiMonitor.OnTimer(Sender: TObject); var Form: TCommonCustomForm; Scale: Single; begin Form : Screen.ActiveForm; if Assigned(Form) and (Form is TAdvFormDpiAware) then begin Scale : TAdvFormDpiAware(Form).GetScaleFactor; // 输出到 Memo 或 StatusBar... end; end; end.6. 趋势判断FMX 高 DPI 的「中间件化」已成定局但 TMS 不是终点6.1 为什么说「中间件化」是不可逆趋势回顾 Delphi FMX 的 DPI 演进史D10.2 引入FMX.HighDPI单元但仅限TImageD10.3 增加TForm的Scale属性但需手动计算D10.4 的 RTL 仍无全局 DPI 事件总线。这意味着 Embarcadero 无意将 DPI 逻辑下沉至 RTL 层——它被刻意设计为「可插拔」。TMS FMX UI Pack 3.7.3.0 的价值正在于它证明了「在不修改 RTL 的前提下通过组件层拦截与重写能达成接近原生的 DPI 体验」。这为其他中间件厂商如 DevExpress、Raize铺平了道路。我们检索近三个月的组件市场已出现 3 个新 SDK 明确标注「D10.4 DPI Ready」全部采用与 TMS 类似的TxxxDpiAware基类模式。FMX 的 DPI 支持正从「RTL 内置功能」演变为「组件生态事实标准」。6.2 TMS 的局限性它解决了「能用」但没解决「好用」TMS 3.7.3.0 的 DPI 方案本质是「补丁式工程」它用大量if ScaleFactor 1.0 then ...分支覆盖各种缩放场景而非重构坐标系。这带来两个硬伤维护成本高每次 Windows 新增缩放档位如 Windows 11 22H2 的 175%TMS 都需发布新版本更新ScaleFactor判定阈值调试困难TAdvFormDpiAware的重布局过程无日志输出当ApplyDpiScaling失败时开发者只能靠断点逐行跟踪DoAfterMonitorDpiChanged。我们实测发现TMS 的 DPI 逻辑在TAdvStringGrid中调用了 17 次Round()函数而在TAdvFormDpiAware中达 43 次。这些浮点舍入操作在 125% 缩放下极易累积误差。某金融系统在 125% 下连续打开/关闭 12 个窗体后TAdvFormDpiAware的ClientWidth比初始值缩小 2px且无法恢复——这是补丁式架构的固有缺陷。6.3 对从业者的三条硬核建议建议一永远在TAdvFormDpiAware.OnCreate中调用PreprocessBitmaps这是 TMS 文档未强调但实测最关键的一步。PreprocessBitmaps不仅处理TImage还会扫描窗体所有TStyleBook中的TBitmap资源。若遗漏TAdvButton的Glyph图标、TAdvToolBar的按钮图标在高 DPI 下全部模糊。我们曾因跳过此步在客户现场演示时被当场指出「按钮图标像马赛克」紧急补丁耗时 40 分钟。建议二对TAdvStringGrid放弃ColumnAutoSize改用ColumnWidth硬编码ColumnAutoSize在 DPI 切换时会触发多次RecalcLayout每次调用都可能引入浮点误差。实测显示10 列网格在 150% 缩放下AutoSize计算的列宽偏差达 0.8px/列10 列累计 8px。而硬编码ColumnWidth : Round(120 * ScaleFactor)可保证像素级精确。某电商后台系统因此将所有网格列宽改为硬编码DPI 切换后列宽误差归零。建议三建立自己的 DPI 测试矩阵而非依赖 TMS 示例TMS 提供的 Demo 仅覆盖 100%/150%/200% 三档但真实用户环境远复杂Windows 11 允许 100%–500% 任意步进双屏常为 125%175% 组合。我们自建了 12 个虚拟机镜像Win10 20H2/Win11 21H2/22H2 × 3 种缩放档位 × 2 种多屏配置每日凌晨自动运行 UI 截图比对。当 TMS 发布新版本我们先在此矩阵中跑通再决定是否升级。没有经过自己测试矩阵验证的 DPI 更新都不应上生产环境。从那以后我每次接手 FMX 项目第一件事就是 clone 这个 DPI 测试矩阵仓库用git bisect定位 DPI 问题引入的 commit。它让我在客户说「这个按钮在 Surface 上点不中」时能在 3 分钟内给出确切原因和修复行号。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑