ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

TMS Component Pack v8.3.4.0 在 Delphi XE10.2 下的安装与开发实战

2026/9/25 9:55:43 拓冰建站 浏览量
TMS Component Pack v8.3.4.0 在 Delphi XE10.2 下的安装与开发实战 简介TMS Component Pack v8.3.4.0 是一款面向 Delphi 与 CBuilder 开发者的商用组件套件针对 XE10.2 Tokyo 版本完成兼容性优化覆盖数据网格、图表分析、表单导航、报表打印及数据库访问等高频开发场景可广泛应用于 ERP 系统、进销存软件、报表统计工具等业务型桌面应用帮助团队在界面层获得一致且高效的交互体验减少大量重复造轮子的编码工作。资源压缩包总大小约 103.4 MB包含约 2000 个文件其中以 pas 源文件、dcu 编译单元、dfm 窗体设计文件为主体并配有 dpr/dproj 工程配置、res 资源文件以及多个版本的批处理编译脚本。开发者可通过这些文件直接查看组件实现原理还原设计时布局并利用脚本快速在不同 Delphi 环境中完成构建与验证尤其适合需要深度定制控件或维护老项目的技术团队。目前该资源已吸引 1201 人学习下载。获取后还能参考 TAdvGrid、TMS Charts 等典型控件的完整示例快速搭建数据网格与可视化分析模块深入学习复杂交互逻辑的组织方式同时借助组件包自带的工程与文档资源可以显著缩短前期的选型评估、原型验证和后期集成周期为项目交付提供更稳定的控件基础。1. 做 Delphi 界面开发的人迟早会碰到 TMS Component Pack如果你的 Delphi 还停在“拖一个 Button、放一个 Edit、连个数据库”的阶段那 TMS Component Pack 对你来说可能只是一个“听说过但没用过”的名字。可一旦你开始做真正的业务系统——比如 ERP、进销存、医院工作站——你会发现 VCL 自带的那几个控件根本不够用表格不能合并单元格、日历不能标周末、进度条没有动画、TreeView 做个多级勾选要写半天。这时候 TMS Component Pack 就是那个让你少写几千行代码的控件集。这个包不是某一个小工具而是一整套商业 VCL 控件集合覆盖表格、图表、日历、计划、编辑器、导航、对话框等几十个组件。v8.3.4.0 这个版本号对应的是 RAD Studio XE10.2 Tokyo也就是 2017 年左右的版本。很多老项目至今还跑在 XE10.2 上升级 IDE 成本太高所以“TMS Component Pack v8.3.4.0 XE10.2”这个组合到今天依然是搜索热词需求量一直没断过。这篇笔记就围绕这个版本把安装、选型、落地的完整路径走一遍也给新手一条能直接照着做的学习路线。2. 用 XE10.2 安装 TMS Component Pack从拿到安装包到组件面板出现2.1 安装前先确认三件事IDE 版本、包文件格式、旧版残留先说版本。TMS Component Pack 的安装包对 IDE 版本极其敏感v8.3.4.0 只认 XE10.2。你把安装包拿去给 Delphi 10.3 或 Delphi 11 用大概率装不上装上也会在编译时直接报“找不到 vcl”或“package 版本不匹配”之类的错。所以第一步不是双击 Setup.exe而是打开 Delphi 的 About 对话框确认你的 IDE 确实是 XE10.2 Tokyo。如果你的 Delphi 是 10.3 Rio 及以上去装老包是没有意义的不如直接找对应新版本的 TMS 包。第二件事看包文件的格式。TMS Component Pack 的安装包一般有两种分发形态一种是完整的 Installer 程序双击就能装另一种是源码包需要你在 IDE 里手动打开 .dpk 文件编译安装。v8.3.4.0 的 Installer 版本会自动检测 IDE 版本和安装路径但源码包更常见于老项目的交接场景——别人把整个第三方源码目录拷给你你自己编译。这两种方式下面的操作步骤完全不同先分清你手里是哪一种。第三件事查旧版残留。如果你的机器上装过旧版 TMS尤其是 TMS 自家的其他包比如 TMS 的 Pro 版、TMS FlexcelExcel 和 Grid 系列组件会有 dcu 文件残留。装新版前最好在 Delphi 里执行一次 “Component Install Packages” 查看已安装的包列表把旧版 TMS 的 bpl 勾选移除再关掉 IDE 做安装。不清理旧版的话装完后拖控件时经常出现类名重复定义Delphi 会直接弹 “Duplicate class” 让你一头雾水。2.2 走一遍标准安装流程以 Installer 版为例以 Installer 版为例步骤不复杂但每步都有值得注意的细节。第一步退出 Delphi IDE。这一步不能省Installer 会往 IDE 的安装目录写入编译好的 bpl 和 dcp 文件IDE 正在运行会导致写文件失败或 IDE 缓存被污染。退出后右键安装包选择“以管理员身份运行”。TMS 的 Installer 默认会写 Program Files 下的 Delphi 安装目录UAC 权限不够会静默失败。第二步选择安装路径时不要改默认路径。默认路径通常是C:\Program Files\TMS\Component Pack和 Delphi 的 Library 路径是配套的。如果你改了路径后面必须手动到 IDE 的Tools Options Delphi Options Library里把Source目录和Lib目录加进去否则编译用到 TMS 单元时会报File not found。新手最常翻车的就是改路径后忘了加 Library 路径。第三步安装组件选择界面会让你勾选要安装哪些控件组。这里不要全选全选会导致 IDE 启动极慢。常见够用配置是勾选 Grid、AdvSmooth、AdvTree、AdvEdit 和 Dialog 这几组。如果你只是要做报表和表格只勾 Grid 和 AdvTree 就够了后面用到别的组件随时补装。安装完成后重新打开 Delphi执行以下步骤验证安装// 新建一个 VCL 应用程序 // 在 Form 上放一个 TAdvStringGrid从组件面板的 TMS 标签页拖出 // 在 FormCreate 事件中写入 procedure TForm1.FormCreate(Sender: TObject); begin AdvStringGrid1.ColCount : 3; AdvStringGrid1.RowCount : 3; AdvStringGrid1.Cells[0, 0] : 名称; AdvStringGrid1.Cells[1, 0] : 数量; AdvStringGrid1.Cells[2, 0] : 金额; AdvStringGrid1.Cells[0, 1] : 硬盘; AdvStringGrid1.Cells[1, 1] : 10; AdvStringGrid1.Cells[2, 1] : 5000; AdvStringGrid1.ColWidths[0] : 100; AdvStringGrid1.ColWidths[1] : 80; AdvStringGrid1.ColWidths[2] : 100; end;这段代码的逻辑很简单新建 VCL 工程拖入 TAdvStringGrid然后在 FormCreate 里初始化行列和单元格内容。它能验证的不是控件能不能拖出来而是 bpl 是否正确加载、单元是否被 IDE 正确索引。如果编译通过且运行后表格里显示了三行内容说明 TMS 已经正常挂载到 IDE 了。这里面有两个参数值得注意。ColCount和RowCount决定网格的行列数TAdvStringGrid 默认有行列但你最好显式设置避免后续代码里访问不存在的单元格抛异常。ColWidths设置列宽单位是像素在制作报表时这个值可以直接从最终打印效果反推。如果你发现运行后表格是空白的先检查是不是把Cells[0, 0]写成了Cell[0,0]——方法名写错是低级错误但非常常见。2.3 手动编译源码包的安装方式没有 Installer只有源码目录时安装路径变成这样拿到整个包目录后先确认里面有.dpk文件。打开 Delphi执行菜单Component Install Packages Add在弹窗里定位到源码目录选dclTMSGridPack.dpk这类带dcl前缀的文件。dcl前缀代表这是设计时包安装后组件面板会出现对应标签页没有dcl前缀的是运行时包只需要被引用而不需要安装到 IDE。选好 dpk 文件后点 OKDelphi 会开始编译并弹出一个确认对话框问你是否要安装这个包。点 Yes 后组件面板里会多出 TMS 标签页。这个过程中如果报错先看错误是不是File not found: xxx.dcu如果是回到上一步把源码的 Lib 子目录加进 Library 搜索路径再重新编译。手动编译的坑在于很容易忽略不同 Delphi 版本的命令条件。XE10.2 对应的包文件后缀一般是.dproj或.dpk但源码包里往往有针对多个 IDE 版本的子目录比如Source\XE10.2和Source\XE10.3。装之前看清楚目录名别用错版本。混淆了版本目录编译时大概率出现奇怪的类名冲突错误信息指向的却是完全无关的单元。3. 表格与数据呈现用 TAdvStringGrid 做一张能直接打印的分组报表3.1 选择哪个表格控件TAdvStringGrid 还是 TAdvColumnGridTMS 的表格控件不止一种名字接近的几个功能差异很大。核心问题不在于哪个更好而是看你的数据源形态。如果你已经把数据查询成了二维数组、TStringList 或 TDataSet接下来的核心需求是显示、打印和简单排序那 TAdvStringGrid 是最直接的选择。它的 API 和标准 StringGrid 长得像迁移成本极低。如果你的数据源是数据库查询结果且你需要列类型、下拉选择、日期控件、多列排序这些交互那应该用 TAdvColumnGrid 或 TAdvDBGrid。TAdvDBGrid 直接挂 DataSourceTAdvColumnGrid 则适合你把数据手动填充到列模型中的时候。实际项目里我见过最多的用法是 TAdvStringGrid 配 TDataSet 手动填充。因为大部分报表数据是经过联表聚合后的结果不再是简单的一张表DataGrid 直接绑定反而要写一堆字段映射。手动填充虽然多花几行代码但可控性最强。下面是核心代码procedure TForm1.LoadDataToGrid(AGrid: TAdvStringGrid; ADataSet: TDataSet); var i, j: Integer; begin // 先设置列标题 AGrid.ColCount : ADataSet.FieldCount; AGrid.RowCount : ADataSet.RecordCount 1; for i : 0 to ADataSet.FieldCount - 1 do AGrid.Cells[i, 0] : ADataSet.Fields[i].DisplayLabel; // 填充数据行 ADataSet.First; j : 1; while not ADataSet.Eof do begin for i : 0 to ADataSet.FieldCount - 1 do AGrid.Cells[i, j] : ADataSet.Fields[i].AsString; Inc(j); ADataSet.Next; end; // 启用隔行变色 AGrid.Options : AGrid.Options [goRowHighlight]; AGrid.RowHighlightColor : $00F0F0F0; end;这段代码有两个细节值得展开。FieldCount和DisplayLabel是从 TDataSet 元数据里取列数和显示名对应的 SQL 里建议给字段起中文别名比如SELECT name AS 名称 FROM itemsDisplayLabel 会直接用它。AsString是万能转换日期和时间字段也会转成短日期格式如果你的报表需要精确的yyyy-mm-dd hh:nn:ss格式要单独处理不能依赖 AsString。运行后如果你发现第一列前多了个空列这是 TAdvStringGrid 的行指示器Row Indicator列。是否显示由AGrid.IndicatorCol控制设成你想要的宽度即可不想显示就设为 0。这个细节等真用到时会省去不少搜索时间。3.2 合并单元格与分组表头让报表更像正式报表做完数据填充真正的报表需求才刚出来分组汇总行、跨列合并表头。在公司里做一张“看得过去”的报表至少要有表头合并和分组小计。TAdvStringGrid 在这块做得非常顺手不需要你手写画布绘制。// 合并表头把第0行的第0到2列合并成一个单元格 AdvStringGrid1.MergeCells(0, 0, 2, 0); AdvStringGrid1.Cells[0, 0] : 货物明细含金额汇总 ; // 按第一列分组并显示分组统计行 AdvStringGrid1.GroupCol : 0; AdvStringGrid1.Options : AdvStringGrid1.Options [goGroupSummary]; AdvStringGrid1.GroupSummaryType : gstSum; AdvStringGrid1.GroupSummaryCol : 2;MergeCells的参数是起始列、起始行、结束列、结束行按行列坐标合并一个矩形区域。注意合并前一定要先把内容写到左上角单元格合并后其它单元格的内容会被隐藏写别的位置再合并会丢数据。GroupCol指定按哪一列分组设为 0 就是按第一列分组。goGroupSummary选项开启后每个分组末尾会自动插入一行统计GroupSummaryCol指定统计哪一列GroupSummaryType决定是求和、平均值还是计数。这里有一个玄学般的坑gstSum求和只对数值类型有效如果你从数据库取出来的是字符串“1234.5”它会把字符串拼接而不是数值相加。解决方法是把单元格值临时转成 Double 存进去或者在填充阶段就保留一个隐藏的数值列。实战里我用的是第二种给表格加了一列隐藏列专门保存数值显示列则正常输出格式化后的文本两全其美。3.3 打印与导出把表格直接输出到 PDF表格做出来是给屏幕看的但最终交付物往往是一张 PDF 或图片。TAdvStringGrid 内置的打印功能不用额外安装报表控件这一点对很多项目非常关键——一个没有采购报表控件的项目TMS 自带的打印能力可以直接顶上。AdvStringGrid1.PrintSettings.PageHeader : 月度销售报表; AdvStringGrid1.PrintSettings.PageFooter : 第 [Page] 页 / 共 [Pages] 页; AdvStringGrid1.PrintSettings.TitleLines : 1; AdvStringGrid1.PrintSettings.FooterLines : 1; AdvStringGrid1.Print;打印参数比较好理解PageHeader是页眉文字[Page]和[Pages]是打印引擎内置的占位符TitleLines和FooterLines分别表示页眉页脚各占几行防止表格内容和页眉重叠。直接调Print会弹出系统打印对话框。如果你需要导出 PDF用AdvStringGrid1.SaveToPDF(report.pdf)即可。这个功能的限制在于它是按屏幕显示去打印的如果你表格有很宽的列打印时会被裁掉。解决方法是打印前临时调整列宽为PrintSettings.FitColsToWidth这个属性设为 True 会让所有列自动缩放适配页面宽度。打印完记得恢复列宽因为屏幕显示场景下每列合理宽度和打印适配宽度往往不一致不恢复的话界面看起来会非常扁。4. 把 TMS 控件用进多线程与实时刷新场景4.1 为什么 TMS 控件在多线程里会“闪退”说到 Delphi 多线程很多老手的血泪经验是不要在线程里直接访问 VCL 控件。TMS 的控件本质上是 VCL 组件同样继承了这个限制。但问题是TMS 的很多控件尤其是图表和网格在数据更新时有自己的刷新机制你在线程里调AdvStringGrid1.Cells[0,1] : xx往往不报错但界面卡死、闪烁、偶尔闪退。这比 Access Violation 更难查。原因是 TMS 控件的内部绘制器在访问主线程的窗口句柄时没有做同步你在线程里给 Cells 赋值触发了内部重绘这个重绘发生在线程上下文里和主线程的消息循环打架。解决方式不是给代码加 Sleep而是用TThread.Synchronize或TThread.Queue把赋值操作调度回主线程procedure TMyThread.Execute; begin while not Terminated do begin // 模拟从外部设备或数据库取到的数据 Queue(nil, procedure begin Form1.AdvStringGrid1.Cells[1, 1] : IntToStr(Random(100)); end ); Sleep(200); end; end;Queue和Synchronize的区别是Synchronize会阻塞当前线程直到主线程执行完对应代码Queue则把代码放进主线程消息队列不等待。在高速刷新数据时用Queue更好因为同步阻塞会导致线程积累延迟但Queue的代价是如果主线程卡住刷新消息会堆积。自己做的采集程序里我就是用Queue配合一个简单的计数器每 10 条数据合并刷新一次避免消息堆积。4.2 TMS 图表控件的实时曲线从滚动数据到边界处理实时刷新最典型的场景是曲线图比如设备温度监控。TMS 的图表控件有几种常见的是 TAdvChartView。实时曲线的核心不是画图而是管理数据缓冲区边界——把旧数据移除加新数据保持曲线平滑滚动。procedure TForm1.AddPointToChart(AValue: Double); var Series: TAdvChartSeries; begin Series : AdvChartView1.Series[0]; Series.AddPoint(Now, AValue); // 限制最大点数超过后移除最旧的 if Series.PointCount 300 then Series.DeletePoint(0); // 自动调整 X 轴范围 AdvChartView1.XAxis.Range.Min : Series.XValue[0]; AdvChartView1.XAxis.Range.Max : Series.XValue[Series.PointCount - 1]; end;这段代码有三个参数值得留意。Series.AddPoint的第一个参数是 X 轴值Now是当前时间AValue是测量值。PointCount超过 300 个点时调用DeletePoint(0)删除最早的点这是控制内存和绘制性能的关键。不设上限的话跑几个小时后曲线会慢到没法看。XAxis.Range.Min和Max手动设置 X 轴范围否则部件默认的自动范围在删除旧点后不会收缩曲线会越画越靠右最终消失在视图外。实际项目和这个逻辑还有一个差别数据不是均匀到达的偶尔会有几十毫秒的突发数据。这种情况下DeletePoint(0)一次删一个是不够的要在添加前先计算当前点数和目标点数的差批量删除。我一般会写一个循环把PointCount控制在 200 到 300 之间即超过 300 就删到 200避免每次添加都触发一次删除降低绘制压力。5. TMS Component Pack 避坑记录安装失败、图标不出现、编译报错的 4 个真实场景5.1 安装完成后组件面板里没有 TMS 标签页现象安装包运行完成重启 Delphi组件面板里找不到 TMS 或 TMS 下的控件是灰色的。原因分两种情况第一种是 Installer 版装的是运行时包而非设计时包导入的 bpl 被放到了未识别的路径第二种是你安装的时候没有勾选“安装到 IDE”选项只安装了运行库。解决先执行Component Install Packages在弹窗里点 Add手动定位到安装目录下的dcl开头的 bpl 文件例如dclTMSGridPack.bpl选好后确认。如果这个文件不存在回去看安装目录是否完整正常情况下该文件一定存在。如果找到了文件但添加后报加载失败检查报错信息是不是“无法找到指定模块”这条往往说明你在 64 位系统上装了 32 位 IDE 的包或者反之Delphi 与 bpl 的位数不匹配。5.2 编译报错 File not found: AdvGrid.dcu现象代码里写了uses AdvGrid;但编译时报找不到.dcu文件。原因Delphi 的 Library 搜索路径里没有包含 TMS 编译生成的.dcu输出目录。源码包安装时没有自动加路径或者你改了安装目录后原路径失效。解决在 Delphi 里打开Tools Options Delphi Options Library在Library path里追加 TMS 安装目录下的Lib子目录。填完后点 OK关闭对话框然后执行Project Clean再重新编译。注意不要直接改系统环境变量Delphi 的 Library path 是 IDE 内部的配置改系统 PATH 不起作用。5.3 运行程序时 TMS 控件弹出试用版提示或功能被限制现象开发时功能都正常但生成的 exe 在别的机器上运行弹“Evaluation version”窗口或某些功能如打印、导出 PDF失效。原因这个版本没有正确注册授权或者 License 文件没有随着安装写入到目标机器。TMS 的控件在运行时检测许可证不是靠编译期静态绑定。解决首先确认你的安装包是正规授权版本。安装后检查安装目录下是否存在tmslic.ini或类似名称的许可证文件。如果文件存在但依然弹提示把它拷贝到 exe 同目录下再运行一次。如果是试用版安装包注册或购买授权是唯一路径没有别的绕过方式。这个问题要正面处理不要尝试任何非正规破解手段规避法律和数据安全风险。5.4 TAdvStringGrid 在滚动时闪屏严重现象大数据量下滚动时表单闪烁尤其开了隔行变色后明显。原因控件每次滚动都重绘整张表格且窗体开启了双缓冲但控件没有。TMS 控件本身有默认绘制优化但和代码里手动设置的Color或FixedColor搭配不佳就会触发全量重绘。解决在 FormCreate 里对这个控件设置DoubleBuffered : True并关闭不需要的重绘选项。具体来说把AdvStringGrid1.Options里的goColumnMoving去掉这个选项开启时每次滚动都会重算列显隐。调整后闪屏基本消除。如果仍然严重减少RowCount的冗余——如果实际只有 200 行数据不要把 RowCount 设成 10000TAdvStringGrid 会真去渲染不可见的行。6. 进阶把 TMS 控件包封装成自己的界面库换掉项目里的裸控件到这一步说明你已经能在项目里熟练使用 TMS 的核心控件了。接下来值得做的一件事是把 TMS 控件从业务代码里隔离开封装成自己的数据展示组件。很多人觉得封装是多此一举但等你要从 XE10.2 往 Delphi 12 迁移或需要同时维护多个项目的界面时封装层会让你省下大量返工时间。具体做法是建一个独立的单元比如UViewGrid.pas在里面包一层 TAdvStringGrid只暴露自己定义的方法和事件。这样业务代码里不直接出现任何 TMS 类型后续替换控件或者升级版本只改这个单元。type TViewGrid class(TPanel) private FGrid: TAdvStringGrid; public constructor Create(AOwner: TComponent); override; procedure SetDataset(ADataSet: TDataSet); procedure ExportToPDF(const AFileName: string); end; constructor TViewGrid.Create(AOwner: TComponent); begin inherited Create(AOwner); FGrid : TAdvStringGrid.Create(Self); FGrid.Parent : Self; FGrid.Align : alClient; FGrid.Options : FGrid.Options [goRowHighlight]; end; procedure TViewGrid.SetDataset(ADataSet: TDataSet); begin // 统一走 TMS 的填充逻辑 LoadDataToGrid(FGrid, ADataSet); end;封装层的价值在项目维护期才会体现你会发现自己不依赖 TMS 也能改界面交互新来的同事也不需要先啃一遍 TMS 文档才能上手业务代码。最后给一个我自己的习惯每次拿到新的第三方控件包先花 30 分钟把读到的控件对象模型用 Delphi 的 IDE Insight 过一遍再写一个最小测试工程跑通常见场景然后再进入正式开发。这套习惯让我避开过很多次“控件装好了但项目引不进去”的尴尬。希望帮到你。本文还有配套的精品资源点击获取