首页 / 资讯中心 / 文章详情

Delphi 12 VCL界面开发提速:TMS UI Pack安装配置与实战避坑

Delphi 12 VCL界面开发提速:TMS UI Pack安装配置与实战避坑 ★ FEATURED ARTICLE
简介Delphi 12配套的TMS VCL UI Pack v13.1.2.02024年5月15日发布面向Delphi及RAD Studio Athens版本开发者提供覆盖数据输入、导航布局、图表展示、界面增强等场景的成套UI控件助力快速构建现代化桌面应用。资源包共2000个文件、226.78MB主体为501个pas源码、239个dfm窗体、227个dproj工程及210个dpr项目文件另含265个res资源、116个ico图标、47个pdf文档等便于直接查阅源代码、示例工程与说明文档。已有206人学习下载。压缩包内保留了TMS VCL UI Pack各功能模块的完整源码与演示项目既能直接编译使用也可针对控件绘制、数据绑定、主题切换等做深度定制适合需要构建现代专业界面并希望深入理解控件实现细节的Delphi中高级开发者。版本支持CodeBuilder 7至12的Athens可帮助团队统一界面风格、提升交付质量。1. 还在等官方控件吗TMS VCL UI Pack 解决的是什么如果你用 Delphi 12 做后台管理端最磨人的往往不是业务逻辑而是界面琐事侧栏要能折叠、表格要支持冻结列和行高亮、按钮希望像现代办公软件一样圆润。原生 VCL 能撑住框架但细节全靠自绘一个列表页就能拖掉一两周。TMS VCL UI Pack 正是冲着这个缺口来的13.1.2.0 版本发布于 2024 年 5 月 15 日核心就是为 Delphi 12 这一代 IDE 下的 VCL 开发提供开箱即用的界面组件。装上之后大部分通用界面组件直接拖用省掉的是重复造轮子的成本。这篇笔记面向要用 Delphi 12 交付桌面程序的开发者把安装、选控件、主题适配和常见坑一次性过一遍让新手和从旧版本迁移的团队都能照着自己落地。2. 安装到 IDE从 GetIt 到离线安装激活许可证TMS VCL UI Pack 不是单个文件而是一套设计时和运行时并存的组件库。安装的本质是三个动作把 bpl 包注册进 IDE、把 dcu 编译路径加入 Library 搜索路径、把许可证激活到本机。这三步缺一步后续都会以各种奇怪报错的形式找上你。2.1 装前检查Delphi 12、老版本残留和路径先讲为什么要检查。TMS 包注册时要写入 IDE 的包列表如果机器里留着一套旧版本的 TMS新装的包往往被旧包残留的搜索路径抢先。编译器可能加载了新 bpl却引用了旧 dcu错误信息完全看不懂。我一般按这个顺序检查在 IDE 的 Help 菜单里确认版本确实是 Delphi 12包版本 13.1.2.0 明确标注支持它但 IDE 必须是 12 系。打开控制面板的卸载程序列表看有没有旧版 TMS VCL UI Pack。有就先卸载卸载完到 IDE 安装目录和公共文档目录下检查有没有残留的 TMS 文件夹有就手动删除。确认当前 Windows 账号有管理员权限否则安装程序写不到 Program Files 目录激活过程也容易失败。有个误用值得提醒有人图省事不卸载旧版本直接拿新版安装包覆盖。旧包的文件不会都被覆盖残留的 dcu 和 bpl 会导致后面怎么修都报冲突。我见过某个项目反复编译错乱最后查出来就是两版 TMS 的 dcu 混在同一工程目录里。2.2 用 GetIt 一键安装库文件落在哪里打开 IDE 的 GetIt Package Manager搜索“TMS VCL UI Pack”列表里找到 13.1.2.0确认适配 Delphi 12 后点击 Install。GetIt 会把下载、安装、注册设计时包、添加库路径这套流程一次性做完而且会按当前 IDE 版本选择对的组件包对新手是最稳的安装方式。等待安装结束期间我会开一个 PowerShell 窗口等提示成功后跑一段检查$studioDir ${env:ProgramFiles(x86)}\YourStudio Get-ChildItem -Path $studioDir -Recurse -Filter TMS*.bpl | Select-Object FullName这段脚本用于确认 bpl 物理文件确实写入了 IDE 目录。使用时把 YourStudio 替换成自己的实际安装路径。如果没有任何输出说明包没装到当前 IDE 的目录下可能被安装程序识别成了别的版本如果有输出但文件名里带着旧日期说明旧版本残留没有清干净。脚本不会验证许可证只验证物理文件是否齐全。GetIt 装完bpl 通常放在 IDE 的组件库目录下dcu 根据目标平台分别放在 32 位和 64 位子目录。知道这一点是为了排查时心里有底设计期报错多半看 bpl编译期报错多半看 dcu 搜索路径。2.3 离线安装和许可证激活步骤内网环境访问不了 GetIt 是常态这时用离线安装包。常见步骤如下把安装包放到本机右键选择以管理员身份运行。在安装类型界面勾选 Delphi 12 对应的运行时包和设计时包两个都要装。安装完成会弹出激活窗口输入序列号和密钥。完全离线的机器选择离线激活方式在一台能联网的机器上生成请求码把激活响应文件拷回来粘贴进激活窗口完成。TMS 的许可证是按机器授权的激活后最好不要克隆虚拟机或批量做磁盘镜像否则授权状态会失效。激活成功的标记通常是在安装目录下生成许可证文件这个文件的备份要单独保存不要提交进代码仓库。不少团队把 License 文件混在工程目录里换个人克隆代码就把授权带走了后面机器一换就激活失败。2.4 安装后验证在设计期打开一个示例窗体装完不要立刻打开老工程先做一个小验证新建 VCL Forms Application从组件面板拖一个 TAdvStringGrid 到窗体上编译运行。能跑过说明包注册和路径都正常。最小验证工程大致长这样unit VerifyForm; interface uses Winapi.Windows, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, AdvStringGrid; type TfrmVerify class(TForm) AdvStringGrid1: TAdvStringGrid; end; var frmVerify: TfrmVerify; implementation {$R *.dfm} end.这里的关键是 uses 子句里的 AdvStringGrid 单元。如果编译这行失败说明 dcu 路径没生效如果设计期能拖但运行报找不到包说明运行时 bpl 没注册完整。两步分开判断能省很多排查时间。提示验证工程建议单独建在一个临时目录不要建在老工程里。老工程的 dproj 里往往带着历史搜索路径会干扰验证结果。3. 核心控件选型与上手表格、导航、联动选择TMS VCL UI Pack 里的组件数量不少新手最容易犯的错误是一次拖十几个控件上来结果样式不统一布局一团乱。我建议先抓住三类真正值钱的东西网格展示、导航容器、状态化输入。把这三类用熟比到处试控件更出活。3.1 从组件面板认识它哪一类控件真正值得用安装后在组件面板会看到 TMS 分类里面按功能分成表格、面板、按钮、编辑器等若干组。我的选型原则很简单原生控件花 5 分钟能达到效果的不引入 TMSTMS 只用在三件事上。第一是网格。TAdvStringGrid 是这套包里使用率最高的控件支持行列冻结、单元格着色、按需取数还能脱离数据库直接操作内存数组这是它和原生 TStringGrid 拉开差距的地方。第二是导航容器。TAdvPanel 一类的容器控件自带背景、边框、折叠区域比原生 Panel 的外观整齐很多适合做侧栏和分组。第三是状态化输入。带图标、水印、校验状态的输入控件能直接提升表单的完成度自己封装这些交互成本不低。选型不是越贵越好要看得维护成本。控件文档全、属性命名规律的项目接手容易那些用大量自绘回调的控件新人上手会很痛苦。3.2 用 TAdvStringGrid 搭一个数据列表分页显示与冻结列拖一个 TAdvStringGrid 到窗体后先设置 FixedCols 和 FixedRows。FixedCols 冻结左侧编号列FixedRows 冻结标题行列表滚动时这两部分保持不动。接着处理数据填充procedure TfrmMain.FillGrid; begin AdvStringGrid1.ColCount : 4; AdvStringGrid1.RowCount : 100; AdvStringGrid1.FixedCols : 1; AdvStringGrid1.FixedRows : 1; AdvStringGrid1.Cells[0, 0] : 行号; AdvStringGrid1.Cells[1, 0] : 订单号; AdvStringGrid1.Cells[2, 0] : 状态; AdvStringGrid1.Cells[3, 0] : 更新时间; for var i : 1 to 99 do begin AdvStringGrid1.Cells[0, i] : i.ToString; AdvStringGrid1.Cells[1, i] : Format(D2024%04d, [i]); AdvStringGrid1.Cells[2, i] : 待处理; AdvStringGrid1.Cells[3, i] : FormatDateTime(yyyy-mm-dd hh:nn, Now); end; end;这里的逻辑是先把 RowCount 一次性设为 100避免循环里自动加行导致网格反复重绘。Cells 属性的参数顺序是列在前、行在后和习惯里的行号列号顺序相反写的时候容易搞混。FixedCols 设为 1 之后横向滚动时第一列不滚。数据量真正大的时候不建议一次性填满 Cells而是配合 OnGetCellText 按需取数这个放到最后一章展开。i.ToString 是 Delphi 12 里支持的字符串转换写法老版本里写作 IntToStr(i)。3.3 用 TAdvPanel 布局一个管理端导航侧栏管理端界面最常见的结构是左侧导航加右侧内容区。左侧栏用 TAdvPanel固定宽度 220整体背景给深色让菜单按钮有层次。Align 设为 alLeft 后窗口横向缩放时侧栏宽度不变右侧主区域自适应比手工计算 Left 坐标省心太多。菜单项不要在设计期写死运行时按权限动态生成更灵活。动态生成前先把容器里的旧控件释放掉for var i : SidePanel.ControlCount - 1 downto 0 do SidePanel.Controls[i].Free;这个循环必须倒序释放。因为 Free 一个控件后ControlCount 会变化正序循环会漏掉原本相邻的控件。释放完成后再按权限列表创建新的按钮或导航项。使用 TAdvPanel 做容器外观风格由它统一管菜单项用普通 TButton 也能保持整体协调不一定要全都换成 TMS 的高级按钮。3.4 单元格着色与双击响应让列表具备可操作性数据列表光能显示还不够状态要一眼能看懂。TAdvStringGrid 提供了单元格绘制事件可以在绘制前改写颜色和字体procedure TfrmMain.AdvStringGrid1GetCellColor(Sender: TObject; ARow, ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont); begin if (ARow 0) and (AdvStringGrid1.Cells[2, ARow] 逾期) then ABrush.Color : $00C6C6E8; end;ABrush 和 AFont 是即改即生效的绘制参数事件里改完网格重绘时就会用新颜色。这里用字符串比较状态在原型阶段够用上生产建议把状态列改成整型字段再用枚举判断避免中文状态改文案后颜色逻辑失效。双击事件的写法也有讲究procedure TfrmMain.AdvStringGrid1DblClickCell(Sender: TObject; ARow, ACol: Integer); begin if ARow 1 then Exit; ShowDetailForm(AdvStringGrid1.Cells[0, ARow]); end;ARow 小于 1 通常是点击了标题行或固定行这时不应该触发详情窗口。如果网格把可编辑选项开着单击就会进入编辑状态双击事件很容易误触发这个问题在第 5 章会专门再讲。4. 主题与高DPI适配控件在新版本下的显示质量Delphi 12 对 VCL 样式的支持已经很成熟TMS 组件也有对应的兼容层。但真正让界面显得“新”的往往不是换了几个控件而是样式和 DPI 跟上系统了。这一章讲怎么让控件跟着工程的主题走以及高 DPI 下怎么避免布局翻车。4.1 让它跟着 VCL 样式走而不是各画各的TMS 控件对 VCL 样式的整体兼容性不错前提是在创建窗口前设置样式。代码一般写在工程文件里program Main; uses Vcl.Forms, Vcl.Themes, MainForm in MainForm.pas {MainForm}; {$R *.res} begin TStyleManager.TrySetStyle(Windows10 Slate Gray); Application.Initialize; Application.MainFormOnTaskBar : True; Application.CreateForm(TfrmMain, MainForm); Application.Run; end.关键点是 TrySetStyle 必须在 Application.Initialize 之前执行否则部分控件窗口已经按默认样式创建了切换样式后边缘颜色、标题栏绘制会不完整。样式名以当前工程安装的 VCL 样式为准代码里那个字符串可以在 IDE 的样式列表里查到替换成你自己的样式名。要注意的是少数 TMS 控件自带皮肤资源和 VCL 样式叠加时可能出现双重边框。遇到这种控件在设计期的 Object Inspector 里找外观相关属性关闭自绘外观分支保留 VCL 样式统一绘制。4.2 高DPI为什么固定坐标在 4K 屏上会翻车Delphi 12 默认开启高 DPI 支持但你的布局代码未必跟着改。最常见的问题是写死控件宽度比如侧栏固定 220 像素在 200% 缩放下看起来就只有原来的一半宽。TMS 13.x 版本对 DPI 的处理比早期版本好了很多但代码层面仍然要做缩放。推荐做法是用相对布局加缩放系数const SIDE_BAR_WIDTH 220; procedure TfrmMain.ScaleLayout; begin SidePanel.Width : MulDiv(SIDE_BAR_WIDTH, Screen.PixelsPerInch, 96); MenuButton.Height : MulDiv(36, Screen.PixelsPerInch, 96); end;Screen.PixelsPerInch 在 PerMonitorV2 模式下会随当前显示器变化在旧的 DPI 虚拟化模式下不会实时更新。MulDiv 是 Delphi 提供的整数乘除函数结果会四舍五入不会出现中间变量溢出。调用时机要注意先让窗体完成 ScaleForCurrentDPI再执行 ScaleLayout否则你算好宽度后系统又按 DPI 缩放一次宽度的值会被二次放大。4.3 在组件上做统一主题调整逐个控件去设置 Color 和 Font 非常累而且容易漏。我习惯写一个主题过程递归遍历容器里的所有控件procedure ApplyTheme(AParent: TWinControl); var i: Integer; begin if AParent is TAdvPanel then TAdvPanel(AParent).Color : ThemePanelColor; for i : 0 to AParent.ControlCount - 1 do if AParent.Controls[i] is TWinControl then ApplyTheme(TWinControl(AParent.Controls[i])); end;这段代码把主题逻辑集中在一处。遇到 TAdvPanel 就改背景色其他控件类型继续向下递归。ThemePanelColor 是你自定义的颜色常量实际项目里可以放在一个公共单元里所有窗体共用。等窗体初始化完毕后调用一次 ApplyTheme(Self)新加窗口时只要复制这一行漏配颜色的问题就很少出现了。如果控件属性和这里不同比如按钮的字体要在子结构里改在对应类型分支里补一行即可思路完全一样。4.4 验收显示质量用一张检查清单代替肉眼排查高 DPI 问题很难靠肉眼立刻看出来我建议验证时用一张固定检查表检查项预期表现异常信号窗口跨屏拖拽控件位置随显示器缩放更新侧栏宽度不变或按钮错位125%/150% 缩放表格字体清晰、行高完整文字被截断、行高不足中文文本显示无方块、无乱码字体名未映射到中文字体样式切换TMS 控件与原生控件风格一致边框双重或颜色突兀实际项目里把检查表交给测试人员比口头描述高效得多。问题一旦复现用第 4.2 节的缩放方式来定位是布局计算问题还是字体问题通常半天内能收完。5. 避坑指南安装后最容易翻车的几个点TMS 这套包用起来顺手但有几个坑几乎每个接手的人都会踩一遍。以下记录按“现象 → 原因 → 解决”来写都是我实际遇到过的类型。5.1 编译报 File not found第一优先查搜索路径现象新建工程拖 TMS 控件没问题老工程一编译就报 E2000 File not found: AdvStringGrid.dcu。原因老工程的 dproj 搜索路径里写死了旧 TMS 路径。IDE 的 Library 路径虽然正确但工程搜索路径优先级更高编译器先找到了旧文件引用于是报找不到。解决打开 Project Options进入 Delphi Compiler 的 Search Path把路径里所有 TMS 相关旧目录删掉。如果界面里找不到就用文本方式打开 .dproj 文件搜“TMS”关键字一条条清干净。顺手把工程目录下的 .dcu 缓存文件和 .identcache 文件删除再重启 IDE。这个方法能救回九成以上的路径类问题。5.2 组件面板里看不到 TMS 控件现象GetIt 显示安装成功重启 IDE 后组件面板搜不到 TMS但工程编译又能通过。原因设计时包没有加载进当前 IDE 配置。安装时如果只选了运行时包或者设计时包注册步骤被安全软件拦了就会出现这种“能编译不能拖控件”的状态。解决打开 Component 菜单里的 Install Packages看列表里有没有 TMS 开头的设计时包。没有就点 Add到 bpl 目录下选择文件名为 dcl 开头的 TMS 包确定后等 IDE 重新编译包列表。如果包在列表里但前面的勾没打上打勾后重启 IDE。再搜不到多半是安装时漏了设计时组件重新运行安装包把 Design-Time 相关选项补上。5.3 双击事件误触发筛选总是弹编辑框现象用户没有双击只点了一下单元格就弹出编辑窗口或者详情窗口。原因网格默认允许单元格编辑单击时已经进入编辑状态双击事件的 ARow 和 ACol 命中了一个可编辑单元格被误判成双击。解决在网格的 Options 里去点 goEditing让单元格不响应默认编辑。如果详情窗口是双击触发在事件里再判断一次 ARow 是否落在数据区小于 FixedRows 就退出。很多团队遇到这个问题第一反应是改事件判断逻辑其实把默认编辑关掉交互逻辑就完全由你自己的代码控制了反而好排查。5.4 高DPI下表格行高不够文字被截断现象100% 缩放下显示正常放到 150% 后 TAdvStringGrid 的行高只显示一半中文被上下切掉。原因默认 RowHeight 是固定像素值系统缩放字体后行高没有跟着乘字变大了行高还是老数值。解决在窗体的 DPI 变化事件里重新计算行高Grid.RowHeight : MulDiv(26, Screen.PixelsPerInch, 96); Grid.Font.Height : -MulDiv(9, Screen.PixelsPerInch, 96);Font.Height 用负数表示像素单位计算结果是 13 就写成 -13。这里要注意负号和 MulDiv 的嵌套顺序写错会得到一个负数字体直接不可见。如果你开了 VCL 样式表头高度还会受到样式影响样式切换后同时更新 Grid.HeaderHeight。13.1.2.0 版本对 DPI 已经有修复但代码层面仍要做自适应不能只指望控件升级。5.5 老工程升级到 Delphi 12 后一切正常唯独 IDE 假死现象工程编译通过程序运行正常但打开窗体设计器时卡顿偶尔 IDE 直接退出。原因旧版 TMS 生成的 dfm 资源里存了旧包属性新版包对属性注册做了解析设计器打开时反复抛异常造成假死。这类问题多发在从 Delphi 10.4 以下版本直接迁移过来的工程。解决右键窗体选择 View as Text把 dfm 切成文本模式查找旧 TMS 版本留下的节点删除带 Unknown Property 提示的行再切回窗体模式。如果窗体控件太多逐行定位成本太高我一般建议新建一个窗体把数据逻辑和控件代码迁移过去不保留旧 dfm。损失一点布局设置但换来 IDE 稳定很划算。注意假死问题不要反复在窗体模式里切来切去每切一次 IDE 可能卡住一次。先在文本模式改完再回到窗体模式一次搞定。6. 进一步运行时创建控件与内存管理的几个习惯把 TAdvStringGrid 用进真实项目后你会发现静态列往往不够用因为接口返回的字段是动态的。我经常会写一个创建列的辅助过程procedure CreateGridColumns(AGrid: TAdvStringGrid; AFields: TArraystring); var I: Integer; begin AGrid.ColCount : Length(AFields); AGrid.FixedRows : 1; for I : 0 to High(AFields) do begin AGrid.Cells[I, 0] : AFields[I]; AGrid.ColWidths[I] : 120; end; end;AFields 是来自接口的字段名数组。ColWidths 是网格继承自原生 TStringGrid 的列宽属性按列索引直接赋值不需要额外创建列对象。这个辅助函数可以在任何窗体里复用字段变化时只改传入的数组不用动窗体布局。数据量大时建议配合 OnGetCellText 按需取数而不是把所有数据写进 Cellsprocedure TfrmMain.AdvStringGrid1GetCellText(Sender: TObject; ARow, ACol: Integer; var ACellText: string); begin if ACol 1 then ACellText : QueryResults[ARow].OrderNo else if ACol 2 then ACellText : StatusText[QueryResults[ARow].State]; end;OnGetCellText 只在格子需要重绘时触发拖到屏幕外就停止调用视觉上滚动流畅很多。但这里有个隐含风险ARow 直接作为数组索引时过滤后索引对不上就会越界。我处理的办法是过滤后立即重建一个并行索引数组事件里通过索引数组取真实数据避免原数组被跳过几行。内存管理上运行时创建的 TMS 控件创建时传了 Owner 就由 Owner 统一释放不需要你自己调 Free。没传 Owner 的控件释放时直接用 Free不要在 Application 的消息循环里反复 Create 和 Free 同一个控件。如果你把大量单元格对象放进网格释放网格本身不会自动释放这些对象集要额外释放。这是老项目最容易泄露内存的地方而且爆发现象很滞后。我现在的习惯是所有 TMS 相关的初始化代码集中在同一个单元里事件处理器只做分发动态创建控件一律带 Owner设计期就把网格的可编辑选项关掉。这套做法让我在模拟项目 X 里从“拖控件写业务”过渡到“界面配置化”后期改字段清单时不再需要逐个改窗体。如果你也准备把一个老桌面项目升级到 Delphi 12建议从安装验证和表格入手先把这两个环节跑通再追新控件。把玩游戏的时间省下来踩坑收益比直接换框架实在得多。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站