尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

TMS Component Pack 8.0.9.0 Full Source实战:D7-D10老项目组件编译与避坑指南

TMS Component Pack 8.0.9.0 Full Source实战:D7-D10老项目组件编译与避坑指南 简介TMS Component Pack 8.0.9.0 是 Delphi 开发者常用的高质量组件源码集支持 Delphi 7 至 DX10 多个版本涵盖界面、数据库、图表、报表、网络通信等核心开发场景覆盖从界面交互到数据管理的常见开发需求能够帮助开发者快速交付高质量桌面应用。包内集成了超过二百五十种可复用控件例如高级表格、网格、对话框、工具栏、图表与数据绑定组件并配有完整源码和开发文档。界面方面提供 VCL 与 FMX 系列组件数据库部分兼容 Oracle、MySQL、SQL Server 等常见引擎图表控件支持柱状图、折线图、饼图及动态交互报表工具可导出 PDF、Excel 等多种格式。由于源码随包分发开发者既能直接调试也可按项目需求修改扩展无论是快速搭建原型还是长期维护大型项目都能明显减少重复劳动。压缩包采用 7z 格式大小约三十六点七 MB内部以源代码文件与说明文档为主目录划分明确便于检索和移植。目前已有二百一十人学习下载对于追求编码效率、需要深度定制控件或研究 Delphi 组件原理的中高级开发者都是一份值得收藏的工具包。1. TMS Component Pack 8.0.9.0 Full Source for D7-DX10拆包实测D7 老项目能续命接手一套 Delphi 7 写的老进销存界面还停在灰底白字时代老板要求“下个月加个导出 Excel 的按钮颜色也换换”。我在仓库里翻到的第一个救兵就是 TMS Component Pack 8.0.9.0 Full Source for D7-DX10。它不是那种装完只剩 dcu 黑匣子的闭门二进包packages目录下几十个控件的.pas全部摊开从 TAdvStringGrid 到 TAdvToolBar 都能直接打开、单步、改默认值再重编。版本覆盖从 Delphi 7 一直到 Delphi 10 Seattle也就是说你手头的 D7、D2007、D2010、XE 系列都能在同一份源码里找到对应编译入口。这套资源真正解决的问题是老项目靠新控件续命时不会被供应商的安装程序牵着走适合正在维护老旧 VCL 项目、又没有预算买新授权的小团队。2. 把它装进 IDE先编译运行时包再装设计时包2.1 包结构里藏着设计时和运行时的分工解压之后别急着双击.dpk先按目录结构把包分成两类。8.0.9.0 这一代的组织习惯是运行时包Runtime Package和设计时包Designtime Package分开存放。命名上带dsgn或design后缀的是供 IDE 安装的设计时包负责把控件注册到 Tool Palette不带后缀的是业务代码运行时依赖的库包负责生成最终逻辑和绘制。我一般先打开packages目录做一个清单确认三件事当前要用的 Delphi 版本对应哪几个.dpk文件source目录里.pas单元是否完整lib目录是否为空因为编译输出要单独放避免源码和 DCU 混在一起污染 IDE 的搜索路径。路径内容编译产物source\所有组件.pas单元Full Source 的核心无编译时引用packages\各版本.dpk包工程DCU / BPLlib\D7\、lib\D10\按版本隔离的输出目录DCU、BPL、DCP这种按版本分目录的做法非常关键。Delphi 7 和 Delphi XE8 的.dcu格式不一样BPL 也不能跨版本加载如果你把 D7 编出来的 DCU 和 D10 的 DCU 混放后面会出现“单元版本不匹配”的奇怪报错。我第一次拆这种包时图省事把所有输出都丢同一个目录结果 D10 的 IDE 直接拒绝加载组件包最后老老实实按版本分目录重编了一次问题立刻消失。2.2 编译顺序先运行时包再设计时包装包顺序有没有讲究有而且顺序错了会让你白折腾半小时。设计时包依赖运行时包所以必须先编译不带dsgn的运行时包再编译设计时包。如果倒过来IDE 会提示找不到某个 BPL 或单元。以 Delphi 7 为例我的做法是不开 IDE直接用命令行编译这样能看到完整日志比图形界面下卡死半天再弹窗友好得多。命令行脚本如下set TMSC:\Components\TMS_8.0.9.0 set D7C:\Program Files (x86)\Borland\Delphi7 %D7%\bin\dcc32.exe -B -H -C -Q ^ -U%TMS%\source;%D7%\Lib ^ -NO%TMS%\lib\D7 -NB%TMS%\lib\D7 ^ %TMS%\packages\tmsgridsD7.dpk这里几个参数是给新手的避坑点-B表示全量重建保证不沿用旧 DCU-H生成 BPL这是包编译必需-C编译包Package模式-Q是安静模式只输出错误和警告-U指定搜索路径顺序很重要一定要把source放在最前面否则可能命中不明版本的旧.pas-NO指定 DCU 输出目录-NB指定 BPL 输出目录。编译完运行时包再编设计时包。通常设计时包命名类似tmsdsgnD7.dpk命令几乎一样只是目标文件和包名不同。按同样的写法换一下包名即可这里不重复占篇幅。如果你更喜欢图形界面直接双击.dpk打开 Delphi然后在 Project Manager 里右键选择Build效果一样关键是先后顺序别搞反。这一套动作我会重复做两遍一遍给 D7一遍给 D10 Seattle。因为 8.0.9.0 的源码是同一份靠条件编译和不同版本的.dpk区分所以你在packages目录里会看到tmsgridsD7.dpk、tmsgridsD10.dpk这类文件。每编完一个版本就去lib目录确认 BPL 是否生成再进入下一步注册。2.3 注册到 Tool Palette并处理 BPL 路径编译完成只是第一步控件要出现在 IDE 里还得注册。在 Delphi 菜单栏打开Component→Install Packages点击Add找到刚才lib\D7里生成的设计时 BPL 文件选中导入。正常情况下工具栏上会多出一排 TAdv 开头的控件包括 TAdvStringGrid、TAdvToolBar、TAdvListBox 等等。如果点了添加以后 Palette 上没出现先别急着怀疑包坏了。打开Tools→Options→Library把lib\D7路径加入 Library Path。这个路径的作用是让 IDEA 在编译业务工程时能找到 DCU 和 BPL。我见过太多人编译报错原因根本不是组件包文件坏了而是压根没把输出目录告诉 IDE。另一个入职新人经常踩的是系统中残留旧版本 TMS。比如之前装过试用版注册表里还留着旧 BPL 的信息。此时新包添加后可能弹“Class already exists”之类的冲突处理办法是在 Install Packages 列表里先移除所有 TMS 相关包重启 IDE再重新添加 8.0.9.0 对应版本的 BPL。这一步相当于给 IDE 做一次后悔药级别的清理比在代码层头排查更直接。3. TAdvStringGrid 实战一个可排序、合并、导入导出的 Excel 式表格3.1 TAdvStringGrid 在 8.0.9.0 里到底多了什么原生TStringGrid不是不能用但做业务表时你会发现排序要自己写、单元格合并要自己算坐标、列宽适应要自己处理、导出 Excel 还要 OLE 调Excel.Application。TAdvStringGrid 把这些功能从代码里搬到了属性层。8.0.9.0 这一代的 TAdvStringGrid 已经具备SortSettings、MergeCells、EditColumns、Appearance等核心能力对大多数进销存、报表、数据录入场景够用。它和原生网格最大的差别在于原生网格是“画布”你画什么出什么TAdvStringGrid 是“半成品框架”你要的是行为不是绘制逻辑。这意味着业务代码里少掉大量DrawCell事件维护量明显下降。下面我按从表单搭建到数据导出的完整顺序演示。3.2 快速搭一个可排序表格新建一个空 Form从组件面板拖一个 TAdvStringGrid 到窗体上或者直接在FormCreate里动态创建。推荐动态创建方便代码复用。基础初始化代码如下procedure TForm1.FormCreate(Sender: TObject); var Grid: TAdvStringGrid; begin Grid : TAdvStringGrid.Create(Self); Grid.Parent : Self; Grid.Align : alClient; Grid.FixedRows : 1; Grid.FixedCols : 0; Grid.ColCount : 4; Grid.RowCount : 6; Grid.Cells[0, 0] : 姓名; Grid.Cells[1, 0] : 部门; Grid.Cells[2, 0] : 工资; Grid.Cells[3, 0] : 入职日期; Grid.Cells[0, 1] : 张工; Grid.Cells[1, 1] : 研发部; Grid.Cells[2, 1] : 20000; Grid.Cells[3, 1] : 2020-03-01; // 运行时点击列头直接排序 Grid.SortSettings.Show : True; Grid.SortSettings.Index : 0; // 允许用户拖拽调整列宽 Grid.Options : Grid.Options [goColSizing]; end;这段代码里FixedRows : 1指定第一行为固定表头FixedCols : 0表示不需要固定左侧列。SortSettings.Show : True是给列头加上点击排序的三角形提示TMS 的排序是内部实现的不需要你接管Compare事件默认按字符串排。goColSizing允许运行时拖宽列。如果你接的是数据查询结果常见做法是先循环Query.Fields把字段名写进第 0 行再循环数据集写各行数据。这样做以后单元格内容默认就是字符串排序对字符串有效想要工资列按数字排记得在写入时把Cells[2, 1]补成money文本或者在上面对应的列设置Numeric判断否则排出来是字典序。3.3 合并单元格和导出 CSV 的两种高频写法业务表里经常出现“本月合计占两列”这样的表头TAdvStringGrid 的合并是老牌功能直接调用// 合并第 2 行第 1 列到第 2 行第 2 列 Grid.MergeCells(1, 1, 2, 1);MergeCells的四个参数分别是左上角列、左上角行、向右合并列数、向下合并行数。注意合并前不能先给这两个单元格都写不同的值合并后只保留左上角单元格内容其余显示为空。我经常看到有人合并完发现文字不见了其实是内容被原来的右下侧单元格占着。接着是导出 CSV这也是老业务系统里加导出按钮最常用的落地方式。我曾经为了导出 Excel 折腾 OLE后来发现直接出 CSV 更稳工控机上不装 Office 也能打开。代码不依赖 TMS 内置方法通用性更好procedure TForm1.ExportToCSV(Grid: TAdvStringGrid; const AFileName: string); var SL: TStringList; I, J: Integer; Line: string; begin SL : TStringList.Create; try for I : 0 to Grid.RowCount - 1 do begin Line : ; for J : 0 to Grid.ColCount - 1 do begin if J 0 then Line : Line ,; Line : Line AnsiQuotedStr(Grid.Cells[J, I], ); end; SL.Add(Line); end; SL.SaveToFile(AFileName, TEncoding.UTF8); finally SL.Free; end; end;这里我做了一个处理用AnsiQuotedStr包裹每个单元格这样字段内部出现逗号或引号时不会破坏 CSV 结构。SaveToFile指定TEncoding.UTF8保证中文不乱码如果你还在用 Delphi 7SaveToFile只接受一个参数那就直接写成SL.SaveToFile(AFileName)并在导出前把系统语言处理一下。3.4 TAdvListBox 替换 TListBox 的注意点顺手补充一个很有用的替换老项目里大量 TListBox想要每行显示不同的缩进或图标原生 TListBox 基本要自己 OwnerDraw。TMS 的 TAdvListBox 在 8.0.9.0 里直接扩展了绘制条目项可以带索引和图标。在赋值上原生写法是ListBox1.Items.Add(张三)换到 TAdvListBox 就需要关注它重载的AddItem系列方法参数通常是条目文本、序号、图标索引。如果你只是简单替换继续用Items.Add也能工作但那就浪费了这套控件的优势了。4. 改源码要趁早定位 TAdv 控件实现改默认值再重编4.1 拿到源码先搜什么从 dcu 黑匣子到单步进组件内部Full Source 给的最大价值不是“我有源码”这个事实而是你可以在调试器里单步进组件内部。我拿到这套包以后第一件是就是把source目录加入 IDE 的断点搜索路径然后在项目里放一个 TAdvStringGrid按 F7 走进它的构造和绘制过程看它是怎么分配内部列表的、排序比较器在哪里、绘制边框的开销主要在哪。定位的跳跃手法很简单全局搜索TAdvStringGrid class找到它声明所在的.pas再顺着published属性找到对应 setter 方法。这样没看文档也能理解每个属性对应的内部实现。比如你怀疑SortSettings.Show影响性能直接单步进去看它是在MouseUp里触发还是CellClick里触发比自己瞎猜准得多。常见做法是先从高频率使用的三个控件入手TAdvStringGrid、TAdvToolBar、TAdvListBox。把这三者的源码通读一遍你对这整套包的设计模式就有底了——它们普遍继承自公共基类大量使用虚方法和受保护属性扩展点找起来不费劲。4.2 改一个默认外观属性以 TAdvStringGrid 的默认颜色为例老系统最迫切的需求是换皮。改每个窗体单独设置颜色容易漏更好的做法是直接在源码构造一个组件的默认值。以 TAdvStringGrid 为例找到TAdvStringGrid.Create的末尾在继承构造完成后加入想要的默认属性constructor TAdvStringGrid.Create(AOwner: TComponent); begin inherited Create(AOwner); // 这里是我加的全局默认值业务 Form 不设置也会继承 Color : $00E8F4FF; Font.Size : 10; Font.Name : Microsoft YaHei; end;注意这段代码是在source目录里改的不是在业务工程里改。该完成后按前面第 2 章的顺序把运行时包和设计时包重新编译一次然后重启 IDE。之后新拖出来的所有 TAdvStringGrid 都默认浅蓝色背景、10 号微软雅黑。如果你只改了源码但不重新编译IDE 里预览和实际运行都还是旧效果这是最容易犯的错。改完以后要留意一个边界老 Form 上以前显式设置过Color的重编后不会受影响因为属性赋值是在运行时覆盖默认值的只有那些没显式赋值、一直用组件默认值的窗体才会整体换色。这既是优点也是坑业务系统里如果原先就有写死颜色的窗体你可能需要单独再核对一遍。4.3 往 Delphi 12 和 FireMonkey 迁移的边界有人问这套源码我能不能直接用在 Delphi 12 的 FireMonkey 项目里。我想直接说明白8.0.9.0 的源码是纯 VCL 时代的产物依赖Winapi.Windows、Vcl.Graphics、Vcl.Controls这些单元在 FireMonkey 项目里本质上就不存在。就算强行编译TWinControl与TControl的体系也完全不同绘制 API 从 GDI 换成了 Canvas2D代码层面对的是一堆找不到类型的报错。所以如果你要升级到 Delphi 12 的 FireMonkey 做跨平台唯一可行路线是拿新版 TMS FMX 包或者自己重写绘制层。这也是 Lazarus 和 Delphi 差距的一个缩影Lazarus 的 LCL 控件外观接近 VCL但内部控件体系、组件流机制和包管理都与 Delphi VCL 不互通这份 TMS 源码拿到 Lazarus 里一样不好使。Full Source 的边界就是它只在你停留在 VCL 这个范围内时才是全自由的。5. 避坑记录D7 到 D10 编译时的 5 个高频问题5.1 编译到一半报 EOutOfMemory 或 IDE 闪退现象在 Delphi 7 里编译大型 TMS 包时dcc32 提示 Out of memory甚至 IDE 直接消失。原因老 Delphi 7 是 32 位进程搜索路径里包含太多无关目录编译时解析链过长把内存耗尽另外系统临时目录空间不足也会触发类似现象。解决我优先用命令行-B -Q只编需要的包不打开 IDE把-U搜索路径收缩到source和自己的Lib两处清理系统 TEMP 后重试。如果还不行单独编译运行时包分批次处理不要一把梭全量包。5.2 D7 编译正常DX10 却报找不到 Winapi 单元现象同样的源码D7 下编译通过Delphi 10 Seattle 下报“找不到Windows”之类。原因Delphi 10 已经全面使用命名空间系统单元从Windows变成Winapi.Windows。TMS 8.0.9.0 这套源码的版本兼容是靠条件编译做好的但如果某些.pas文件是旧版本留下的就可能在 D10 下意气用事。解决全局搜索报错文件里的uses Windows改成Winapi.Windows同时查看源码前面有没有{$IFDEF UNICODE}之类的分支把这些分支打开编译。更稳妥的做法是回到packages目录找明确带 D10 后缀的.dpk编译不要拿 D7 的.dpk硬塞给 D10。5.3 安装设计时包后 Tool Palette 上不出现 TAdv 控件现象通过Component→Install Packages添加 BPL没有报错但组件面板上就是找不到 TAdv 组件。原因最常见的是 IDE 没有刷新 Known Packages 列表另一种是 BPL 加载了但控件注册过程中抛异常被 IDE 静默吞掉。解决先关闭 IDE用bds.exe -r重置 IDE 配置。重置后重新打开再添加 BPL。如果还看不到打开 Windows 事件查看器看 Delphi 加载 BPL 时有没有异常记录。我第一次遇到时傻傻重装了杀毒软件其实是杀毒软件阻止了 BPL 的注册表写入把杀毒软件退掉再导入就好了。5.4 运行时报错“Class TAdvStringGrid not found”现象编译能过运行到主窗体创建时报错说找不到类。原因业务工程编译时链接的是 DCU但运行时需要的 BPL 没有跟着部署或者说库路径里没有把对应的lib\版本号目录加进去。解决在 IDETools→Options→Library里确认路径包含 TMS 输出目录同时把对应版本的 BPL 拷到程序目录或用 Delphi 的Project→Options里的运行包列表勾选那些 BPL。老项目交接时我最常看的问题就是交接人只拷贝了 exe 忘了拷 BPL这种报错其实是部署问题不是编译问题。5.5 改完源码重编后组件行为没有任何变化现象按第 4 章改了源码默认值重新编译后程序运行起来还是旧效果。原因IDE 里还加载着旧 BPL或者工程搜索路径优先指向旧 DCU而不是我改动后的source。Delphi 在库路径搜索时按顺序找.dcu如果你把.dcu放在source前面改源码不会生效。解决打开Project→Options→Search path把source目录排到最前编译时强制-B再去Component→Install Packages里把旧 TMS 包移除重启 IDE重新注册。改变源码后的重编不能只按 F9要走完整“清理目录 → 重新 Make → 重启 IDE”步骤我把这当成固定习惯。6. 收尾一招用批处理循环把几个版本全部编一遍6.1 一键轮巡编译脚本既然要维护 D7、D2007、D2010、DXE2、DXE8、D10 这么多版本手工一个个编译效率太低。我习惯把编译命令抽成一个批处理通过循环轮巡版本目录echo off set TMSC:\Components\TMS_8.0.9.0 for %%V in (D7 D2007 D2010 DXE2 DXE8 D10) do ( echo Building %%V call %TMS%\scripts\build_%%V.bat if errorlevel 1 ( echo %%V build failed ) else ( echo %%V build success ) )脚本开工前先为每个版本写一条build_%%V.bat内部按第 2 章的命令行参数写死搜索路径和输出目录。这样做的好处是换新机器时不用把路径记在脑子里直接把TMS变量改成新磁盘路径即可。我自己的习惯是一个set变量管控全部路径这样升级目录只需要改一处。6.2 验证成品不要只靠编译通过编译通过不代表组件工作正常。我每次轮巡完都会顺手编译一个冒烟 Demo窗体上放 TAdvStringGrid、TAdvListBox、TAdvToolBar 各一个什么业务逻辑都不写只验证创建、显示、销毁三步。如果这个空 Form 能在该版本 Delphi 下跑起来那说明运行时包和设计时包协调一致。这个冒烟项目我建议一直留着每换一台电脑就编一次花了不到五分钟能省掉后面半天定位问题的功夫。我还会在冒烟项目里做一个一次性自我检查列一张版本号 → 编译结果 → 冒烟结果 → BPL 路径的简单表做完一版就勾一版。这套包的优势是 Full Source所有版本入口都摆在那里但真正把多版本吃透靠的正是这样的验证闭环。从那以后我每次拿到这种全源码组件包都会强制自己把“清目录 → 按版本重编 → 冒烟 Demo → 登记结果”整条走一遍再开始改业务代码。这个习惯是我吃过几次亏换来的第一次就是因为只编了当前 D7 就上手改等客户要求升到 XE8 时从头排查编译问题差点误了工期。希望这份 TMS 8.0.9.0 的拆包记录能帮你在拿到包的第一天就把它稳稳编过把时间留给真正挣钱的功能。希望帮到你。本文还有配套的精品资源点击获取
返回列表