简介:TMS Component Pack 8.0.9.0 完整源码库面向 Delphi 开发人员,覆盖用户界面、数据库、图表、报表与网络通信等常用场景,支持从 Delphi 7 到 DX10 的跨版本开发。压缩包采用 7z 格式封装,整体约 36.71MB,包含 250 余种组件的完整源码,让开发者可以阅读、调试并按需修改,深度理解各控件的实现细节。资源中既有 AdvGrid、AdvStringGrid 等高级 UI 控件,也有数据绑定、图表绘制、HTTP 客户端、Web 浏览器等实用模块,可显著简化复杂功能开发。数据库组件支持 Oracle、MySQL、SQL Server 等主流引擎,报表模块可导出 PDF、Excel 等多种格式,满足企业级应用常见需求。随包附带的文档对各组件进行了分类说明,帮助梳理调用方式与设计思路,尤其适合希望深入源码层面定制控件的初中级开发者。目前已有 208 人下载学习,是快速构建高质量 Delphi 应用的有力参考。 前阵子在公司把一套压了很久的 Delphi 老项目从 D7 往 RAD Studio 10.3 迁移,顺手把 TMS Component Pack 从老版本升级到了 8.0.9.0 Full Source 版。这套组件包在 Delphi 圈子里属于绕不开的存在,前后折腾了小半个月,把 D7 和 DX10 两套环境都跑通了,今天就把这里的门道从头到尾捋一遍,给同样要做版本迁移或者刚接触 TMS 的兄弟一个参考。
这个版本号 8.0.9.0 对应的组件集覆盖范围很广,从传统 VCL 的表格、菜单、工具栏,到图表、计划和脚本引擎都有涉及。关键它是 Full Source,也就是说包内所有组件都带完整源码,这意味着你可以直接对着源码调试、改样式、甚至裁剪掉用不到的部分,而不是拿一个编译好的 DCU 黑盒在那瞎猜。对于既要兼容老项目、又要跑在新 IDE 上的场景,这个优势尤其明显。
1. 先把概念说清楚:TMS Component Pack 到底是什么
1.1 不是单个控件,是一个完整的组件生态
很多刚入门的 Delphi 开发者会把 TMS Component Pack 理解成"一个表格控件"或者"一个皮肤库",实际上它是一个包含几百个组件的集合包。举几个高频组件大家就有感觉了:TAdvStringGrid 是类 Excel 的表格,TAdvMemo 是高亮编辑器,TAdvChartView 负责图表绘制,TAdvSmoothPanel 和 TAdvGlowButton 这种专门做现代化扁平界面,还有 TPlanCalendar 做日程视图。再加上工具栏、状态栏、TreeView、ListView、进度条这些基础控件的增强版,基本上你开发一个商业桌面程序需要的界面部件,这里都齐了。
我这次迁移的老项目里就大量用到了 TAdvStringGrid,老版本是 5.x,新版本 8.0.9.0 对它的接口做了一些调整,特别是关于单元格合并和排序回调的部分,编译时冒了不少错。后来直接在源码里追着看,发现新版本引入了一些新的属性命名规范,比如原来的 OnCanSort 变成带 Sender 参数的回调签名。如果不看源码,光靠猜,这个问题绝对够你排查一下午。
1.2 D7-DX10 的跨度意味着什么
D7 是 Delphi 7,DX10 指的是 RAD Studio 10.x 系列(Seattle、Berlin、Tokyo 这些)。这两个时代的 Delphi 差别是很大的:D7 是 ANSI 字符串时代,10.x 是 Unicode 字符串时代,IDE 的包管理方式、RTL 接口、VCL 底层都变了很多。
TMS 敢把一个版本号同时覆盖 D7 到 DX10,说明它的内部做足了条件编译的功夫。你在源码里会看到大量类似 {$IFDEF VER150}、{$IFDEF UNICODE} 这样的编译指令,用于区分不同编译器版本。这也给我们的一个实际提示:升级组件包时,不是简单替换文件就能完事,必须要按照当前 IDE 版本重新编译生成对应平台的 DCU。我在迁移时就把这一条写进了项目团队的规范里,避免有人直接拷贝 DCU 导致版本错乱。
1.3 这个包适合谁用
如果你是做企业管理类、进销存、医疗信息、工业控制这类典型的 VCL 桌面应用,TMS Component Pack 几乎是必选项。它解决的是从零开始做界面和交互控件的时间成本,一套组件覆盖日常 80% 的需求,自己只需要在业务逻辑层下功夫。
当然,如果你只是写写内部小工具、不需要复杂表格和现代界面,那么这个包确实有点大材小用,安装后 IDE 加载组件会慢一些,安装体积也大。选型的时候要想清楚自己到底需不需要这么多功能,不要盲目堆组件。
2. Full Source 版本的价值,远不止"能调试"这么简单
2.1 源码在手,排查问题的效率完全不同
使用普通编译版组件时,遇到一个行为不符合预期,你能做的只有上网搜或者自己加日志,断点根本进不去。而 Full Source 版本可以直接在组件内部设断点,一步步跟踪属性设置、内部消息处理和绘制逻辑。
我举一个实际例子:TAdvStringGrid 的合并单元格在 D7 下表现正常,但在 DX10 下出现了文字绘制偏移。用 Full Source 直接在 TAdvStringGrid 的 DrawCell 相关方法里下断点,发现是因为 Unicode 版本下字符串宽度计算用的 API 不同,导致换行判断出错。于是我直接在源码里定位到 GetTextWidth 这个函数,看到它内部判断了 ANSI 和 Unicode 两套分支。虽然最终我没有改动源码,但能精准定位问题,对排查效率的提升是决定性的。
2.2 定制空间:裁剪、扩展、二次封装
Full Source 的另一个好处是允许你深度定制。比如项目要求表格里某些列显示"数字加单位、负数标红"这样的规则,我直接在源码基础上封装了一个 TDBAdvGrid 的子类,重写了 ColumnHeader 的绘制方法,在属性上增加了自定义的 FormatType 枚举。这种扩展用黑盒组件很难做干净,通常只能靠事件里写一堆 if-else。
还有一点,源码版做裁剪很方便。TMS Component Pack 安装后组件很多,但项目可能只用十几个。我习惯把用不到的组件从 package 源文件里移除,只编译需要的部分,这样 IDE 启动速度和编译速度都能快一些。不过要注意,TMS 的各个组件之间也有依赖关系,比如 TAdvChartView 会依赖 TAdvSmoothPanel 的某些基础类,裁剪的时候要先理清包之间的依赖树,否则编译会报找不到类。
2.3 版本管理上要留个心眼
用 Full Source 版本之后,你是把源码直接放在项目仓库里,还是放在统一的组件目录里?我遇到过一种尴尬情况:一个项目组里有人用旧版 TMS,有人用了新版 Full Source,结果互相提交改动时经常出现 DFM 文件里的组件类名对不上。
我的经验是建立一个统一的第三方组件目录,例如 D:\Components\TMS,然后通过环境变量或者 IDE 的 Library Path 指向它。项目代码里不直接附带 TMS 源码,只依赖编译出的 DCU。这样不同机器上只要路径一致,编译结果就能稳定一致。这个规范建议团队最好用文档固定下来,血的教训告诉我,研发协作里最容易乱的就是组件版本。
3. 从解压到面板出现图标:一步步安装实操
3.1 目录规划与包结构
先把安装包解压到一个无空格、无中文的路径,比如 D:\Components\TMS。为什么强调这点?因为 Delphi 老版本对路径中有空格的处理不好,编译期经常出现找不到文件但你也看不出来哪错了的情况。解压后你会看到类似这样的目录:
D:\Components\TMS ├── packages # 各版本的包工程文件 │ ├── D7 │ ├── D9 │ ├── D10.3 # 对应不同 RAD Studio 版本 │ └── ... ├── source # 各组件的源码文件 │ ├── AdvGrid │ ├── AdvMemo │ └── ... ├── DCU # 编译输出目录 └── demos # 官方示例这里最容易犯的错误是直接双击 packages\D10.3 下的某个 .dpk 文件就开始编译。TMS 的组件分成运行时包(RunTime,后缀通常带 R)和设计时包(DesignTime),两个必须分开编译和注册。如果只注册了运行时包,设计面板上是看不到组件的;如果只注册设计时包,运行时会提示找不到类。
3.2 编译顺序和注册流程
我在 D10.3 和 D7 两套环境下的操作步骤基本一致,核心顺序如下:
- 打开 Delphi IDE,先把库路径设置好。路径是 D:\Components\TMS\source 和 D:\Components\TMS\DCU\D10.3(如果用的是 D7 就改成对应的 DCU\D7 目录)。
- 在 packages 目录里找到对应版本的包文件。通常是 dclTMS... 开头的设计时包和 TMS... 开头的运行时包。
- 先编译运行时包:打开 TMSGridPack_R.dpk 这类文件,右键 Project -> Build,确保编译通过。
- 再打开设计时包:例如 dclTMSGridPack.dpk,右键 Project -> Install。执行完这一步,IDE 组件面板才会出现 TMS 分类。
这里有一个细节:Build 和 Compile 是有区别的。第一次安装新版本时要用 Build,它会重新编译所有依赖的单元,确保最新的源码生效;而 Compile 只编译发生变化的文件。如果觉得组件行为不对,就用 Build 强制全部重来。
3.3 多版本 IDE 共存时的注意点
很多开发者的机器上同时装了 D7 和 RAD Studio 10.x,这时候两个版本不能共用同一套 DCU 输出目录,一定要按版本来分目录。因为 D7 下编译的 DCU 是 ANSI 时代的东西,拿到 10.x 下是加载不出来的,反过来也一样。我按下面的方式布局:
| Delphi 版本 | 源码目录 | DCU 输出目录 |
|---|---|---|
| D7 | D:\Components\TMS\source | D:\Components\TMS\DCU\D7 |
| D10.3 | D:\Components\TMS\source | D:\Components\TMS\DCU\D10.3 |
不要偷懒试图省掉 DCU 输出目录这一步。我见过有人把 DCU 直接输出到源码目录,结果一个版本编译后的文件覆盖了另一个版本,最后怎么都找不到错误来源。分目录管理看似麻烦,实际是最省心的。
3.4 首次安装后验证是否生效
安装完成后,新建一个 VCL 项目,从组件面板的 TMS 分类里拖一个 TAdvStringGrid 到窗体上。拖动后能正常显示、属性编辑器能打开,这就基本没问题。然后再放一个 TAdvMemo,测试一下输入中文是否正常。如果这两个都过了,说明核心运行时没问题。
有时候拖组件时会出现"类 Txxx 未注册"的报错,这通常是设计时包和运行时包版本不一致。解决方法是把已经安装的 TMS 包从 IDE 里先移除(Component -> Install Packages 里去掉勾选),关闭 IDE,重新编译运行时包和设计时包,再打开 IDE 安装一遍。顺序:先运行后设计,这个顺序千万别反过来。
4. 实战中遇到的几个坑和排查办法
4.1 编译时报 "File not found: xxx.dcu"
这个是最常见的错误。原因不外乎三种:Library Path 没配好、DCU 目录被多个版本搞混了、或者当前编译的包依赖了另一个尚未编译的包。
排查顺序是:先在 IDE 菜单 Tools -> Options -> Library 里确认 Library Path 是否包含 source 和对应版本的 DCU 目录。然后检查编译输出目录是否正确,再看依赖的包是否已经 Build 过。我遇到过一次坑,是某个第三方组件包依赖 TMS 的 Grid,但 TMS Grid 的 DCU 还没编出来,就报了 dcu not found。编译完 TMS 的运行时包后立即就解决了。
4.2 组件面板上图标消失或灰色不可用
这个通常是设计时包没有正确安装,或者被 IDE 禁用。去 Component -> Install Packages 里看 TMS 相关条目是否打勾。如果显示是灰色不可选,说明组件加载时出错,Delphi 会把出错的包标记为"disabled"。你需要点 Remove 删掉,然后重新安装。
如果是新装的包但面板上连分类都没有,检查一下是不是只装了运行时包而忘了设计时包。我在 4.2 节提到过,这俩是分开的,最容易搞混。
4.3 运行期出现 "TAdvStringGrid with duplicate name" 或 "Invalid pointer operation"
这类错误多半是组件版本和项目引用不一致导致的。比如项目文件夹里有旧版的 TMS dcu 或者 bpl,运行时会优先加载旧文件,然后新版的 DFM 引用又指向新类名。最直接的解决办法是在项目搜索路径里把旧文件彻底清理掉,然后在 Project -> Options 里统一引用新库路径。
如果是 Invalid pointer operation,常见于 TMS 的一些内部对象没有正确释放。这个问题在 D7 和 DX10 下的表现不一样。D7 下偶尔出现但不影响下次运行,DX10 下因为 RTL 对内存管理器更严格,会直接崩溃。我后来在项目里打开 FastMM 的完整日志,定位到是一个 TAdvSmoothPanel 的 OnDestroy 事件里访问了已释放的句柄。定位到组件后,绕开了它的内部实现,改为在父窗体销毁后再释放,问题解决。
4.4 常见问题速查表
| 现象 | 常见原因 | 快速解法 |
|---|---|---|
| 编译报 dcu not found | Library Path 未设置或 DCU 目录混乱 | 检查路径配置,清理旧 DCU |
| 组件面板没有 TMS 分类 | 只安装了运行时包,未装设计时包 | 安装并 Install 设计时包 |
| 拖放组件报"类未注册" | 运行/设计时包版本不一致 | 移除后重新编译安装两套包 |
| 运行期崩溃 | 项目里残留旧版 TMS 文件 | 清理项目搜索路径,统一引用新库 |
| 图片资源加载异常 | 包路径引用了其他版本的资源 | 确认 DCU 输出目录与包版本一致 |
4.5 官方 Demo 是最好的调试参考
很多人不知道,TMS 的 demos 目录其实就是最好的排查手册。每个功能组件都有对应的示例项目,仔细看示例里的属性设置和事件处理方式,很多时候能直接发现问题。
我排查 TAdvChartView 的坐标轴显示问题时,就是照着 demos 里的 Chart 示例,逐行对比我项目里的设置,最后发现是 Font 的 ClearType 设置引起坐标轴文字重叠。这种问题如果不看官方示例,靠猜的话效率太低了。
5. 根据个人经验,再补充几个细节
5.1 组织好你自己的源码分支
虽然是 Full Source,但我不建议直接修改 TMS 的原始源码文件,除非你下定决心维护一个分支。因为组件包要升级时,如果你改动过源码,升级就会变得很痛苦。我的做法是把源码原封不动保存,需要扩展功能时,尽量通过继承子类的方式做。
5.2 编译前先清理所有临时文件
TMS 组件包在源码目录里有不少 .dcu、.local、.identcache 这类的临时文件。升级版本时,我习惯先把这些文件清理干净,再重新编译。否则旧的中间文件可能会残留编译信息,导致新代码没有完全生效。我自己写了个小脚本,一键删除源码目录下这些垃圾文件,省了很多心。
5.3 如果遇到不显示透明背景的问题
TMS 的 Smooth 系列组件在 D7 下对透明背景的支持和 DX10 不太一样。D7 下设置 Transparent 有时会导致控件背景变成黑色,这其实是旧版 VCL 对 Alpha 支持不够造成的,可以用 ParentBackground 或改父窗体颜色来绕过去。到 DX10 时代基本没有这个问题了。
最后再分享一个小技巧:TMS Component Pack 的完整源码在 IDE 调试时非常有用,你可以把源码目录直接加进 Tools -> Options -> Debugger 的符号路径里,这样调试时按 F7 就能直接进到组件内部代码。对于搞明白某些控件的绘制算法、理解内部缓存机制,这个方法比看任何文档都直观。我已经把这条路走顺了,希望你也能少踩几个坑。
本文还有配套的精品资源,点击获取