简介Delphi TMS Component Pack v8.3.4.0 是一套面向 Delphi 开发者的知名控件全集覆盖从 D7 到 XE10.3 的版本需求可帮助使用不同 IDE 版本的技术人员在同一套控件体系下完成界面、数据库、网络等常见业务功能开发。内含全部源代码并在原版支持 XE10.2 的基础上修改扩展到 XE10.3亲测可用特别适合需要深度定制控件行为、修复特定问题或跨版本维护老项目的开发团队。压缩包共 2000 个文件约 166MB其中以 dcu、hpp、pas 等源码与编译单元为主辅以大量 dfm 窗体设计文件、res 资源文件、dpk 包工程以及可运行的 demo 示例既便于直接编译集成也方便对照示例学习控件的典型用法。已有 698 人学习下载目录结构完整清晰按控件分类组织从核心单元到示例工程一应俱全能显著降低控件选型、集成调试与排错门槛节省二次开发时间。1. Delphi 老项目接 TMS Component Pack从 D7 到 XE10.3 的版本地基TMS Component Pack v8.3.4.0 全源码版是那种「一套组件撑起半个 VCL 项目」的资源网格、编辑器、面板、图表都在一个包里从 Delphi 7 一路编译到 XE10.3。我拆过的老系统里最常见的诉求是D7 工程不能动新环境又用 XE10.3 开新模块两边必须共用一套控件——闭源二进制包在这种场景直接卡死full source 版的价值就是让你用本机 IDE 自己编译出对应版本的运行时库和设计期包。这篇按「编译安装 → 组件选型 → 跨版本踩坑 → 源码验证」走一遍适合手里有 D7 老工程、或在 XE10.3 上评估控件替换的工程师。2. 编译链路与安装顺序runtime 包与 design-time 包的先后关系2.1 为什么优先选 full source 版闭源分发版只给你编译好的 .bpl装哪个 IDE 版本就得等官方出对应包老版本没人维护时D7 用户只能干瞪眼。全源码包里是 .pas、.dfm、.dpk、.dcr 这四类文件你的 Delphi 编译器本身就是打包机只要把包工程逐个打开、编译、安装D7 和 XE10.3 都能出同一版本的组件。另一个实际收益是排查问题不再隔层纱表格排序不对、编辑器高亮失效直接在源码里下断点看黑匣子不存在了。拿到手先看目录结构常见做法是这样一个布局TMSComp834/ ├── Packages/ # 各 IDE 版本的包工程 │ ├── d7/ # Delphi 7 专用 .dpk │ └── xe10_3/ # XE10.3 的 .dpk/.dproj ├── Source/ # 全部 .pas 源码 ├── Design/ # 设计期注册单元dcl 开头 ├── Lib/ # 官方预编译 DCU一般用不上 └── Docs/ # 帮助与说明说明Source 是组件单元本体Design 里是 RegisterComponents 注册代码这两块目录都要进 IDE 的 Library pathLib 目录在某些版本里是给没有源码的试用用户准备的你既然拿到源码就把预编译 DCU 忽略用自己的编译结果免得 DCU 版本和 IDE 小版本不匹配。2.2 单版本最小安装先 Runtime 后 Design组件包分成两类工程一类是运行时包各功能包如网格、编辑器一类是设计期包文件名通常 dcl 开头前者提供单元给业务代码 uses后者负责把控件注册到 IDE 组件面板。安装顺序有讲究必须先编译运行时包再安装设计期包顺序反了 IDE 会报「找不到依赖包」。Delphi 7 下走 GUI 流程# 1) Tools Environment Options Library Library Path # 追加 Source 与 Design 两个目录 # 2) File Open 打开 Packages\d7 下的功能包 .dpkCompile # 3) 再打开 dcl 开头的设计期包 .dpkCompile 后点 Install # 4) 组件面板出现 TMS 页签XE10.3 下可以不用图形界面用 MSBuild 批量编译call 路径\bin\rsvars.bat # 初始化命令行编译环境 msbuild TMSGridPack.dproj /t:Build /p:PlatformWin32 msbuild dclTMSGridPack.dproj /t:Build /p:PlatformWin32参数说明/t:Build 指定构建目标/p:Platform 指定平台XE10.3 默认还有 Win64 平台第一批先只编 Win3264 位放到第 4 章单独处理。安装完成后验证标准是两件事组件面板能拖出 TAdvStringGrid新建工程里 uses 对应单元不报错。2.3 多版本并存一份源码多份产物老工程师的常见做法是共享一份源码目录给每个 IDE 版本单独设 BPL/DCP 输出目录避免同名 .bpl 互相覆盖。目录规划参考下表IDE 版本Library path 追加BPL/DCP 输出目录Delphi 7D:\Components\TMSComp834\Source; D:\Components\TMSComp834\DesignD:\Components\TMSComp834\Packages\d7\outXE10.3同上D:\Components\TMSComp834\Packages\xe10_3\out原因源码单元同一份DCU 与 BPL 不跨小版本兼容这么做的理由是DCU 二进制跟编译器版本强绑定D7 编出来的 DCU 拿到 XE10.3 里 uses 一定翻车而 BPL 输出目录如果共用后装的版本会把先装的同名包覆盖掉等你想回 D7 时只剩「找不到包」的报错。血的教训是别在 Library path 里加 Lib 预编译目录否则 IDE 会优先捡到旧 DCU你改了源码也不生效排查半天才发现是搜索路径顺序问题。提示修改 Library path 后重启 IDE 再编译包路径缓存才会彻底刷新。3. 组件选型与落地方案把 TAdvStringGrid、TAdvMemo、TAdvEdit 用对3.1 TAdvStringGrid表格类业务的主力这套包里被引用最多的就是 TAdvStringGrid它跟标准 TStringGrid 的继承关系让老代码迁移成本低同时又补了合并单元格、列排序、单元格类型、行选中这些企业功能。初始化代码我一般这样写// 表格初始化固定行、表头合并、整行选中 procedure TForm1.InitAdvGrid; begin // 在既有 Options 基础上追加集合项别整体赋值覆盖 AdvStringGrid1.Options : AdvStringGrid1.Options [goRowSelect, goRowMoving, goColMoving]; AdvStringGrid1.RowCount : 50; AdvStringGrid1.ColCount : 6; AdvStringGrid1.FixedRows : 2; // 前两行作为固定表头 AdvStringGrid1.FixedCols : 1; // 第一列固定横向滚动时可见 // MergeCells(起始行, 起始列, 结束行, 结束列) AdvStringGrid1.MergeCells(1, 1, 1, 3); // 表头行跨 3 列 end;逻辑说明这里刻意用Options : Options [...]而不是直接赋值是因为 TMS 各版本的默认 Options 集合不完全一致整体覆盖容易丢掉内置的编辑、焦点行为参数方面MergeCells 四参分别是起始行、起始列、结束行、结束列行列是从 1 开始计数的不是 0 基跟 Cells[] 属性混用时会差一行这是最常见的翻车点。排序配置常见做法是设计期在 Object Inspector 里设 SortSettings也可以在代码里指定// 点击第 3 列表头时按升序排 AdvStringGrid1.SortSettings.Column : 2; // 列从 0 计数 AdvStringGrid1.SortSettings.Direction : sdAscending; AdvStringGrid1.SortColumn(2);说明SortSettings.Column 和 Cells 一样从 0 计数而 MergeCells 从 1 计数同一段代码里两套索引并存建议在常量区写清楚注释另外 TAdvStringGrid 的排序默认只排非固定行想连同表头固定行一起排需要额外处理业务上一般也不需要。3.2 TAdvMemo 与 TAdvEdit文本类组件的组合用法TAdvMemo 在日志查看器和简单脚本编辑器里很常用核心是高亮器和大文本加载。设计期放一个高亮器组件再关联到 AdvMemo// 日志面板语法高亮 只读 AdvMemo1.Highlighter : AdvPascalHighlighter1; AdvMemo1.Lines.LoadFromFile(D:\logs\run.log); AdvMemo1.ReadOnly : True; // 滚动到尾部模拟 tail -f 效果 AdvMemo1.SetFocus; SendMessage(AdvMemo1.Handle, EM_SCROLLCARET, 0, 0);参数说明Highlighter 属性接受的是高亮器组件的实例高亮器要和编辑器放在同一个窗体否则运行时取不到实例大文本加载建议先关掉WordWrap不然上万行的日志在重绘时会有明显卡顿。TAdvEdit 的输入约束比 VCL 自带的 MaskEdit 灵活两个模式别混// 数字金额输入过滤非法字符而不是掩码 AdvEdit1.FilterMode : fmFilter; // 逐字符过滤 AdvEdit1.FilterMask : 0123456789.; // 只允许数字和点 AdvEdit1.MaxLength : 12;说明fmFilter 是把 FilterMask 里出现的字符以外的输入直接拦掉适合「只能输数字、小数」这类场景如果你要的是「第几位必须是什么」的定长格式那得用 Mask 体系两套机制同时开启会互相干扰这是文档里写得含糊、实际最容易踩的坑。3.3 工程引用关系业务代码只 uses 运行时单元组件装好只是第一步工程里怎么引用才是交付质量的生死线。设计期包的单元dcl 开头绝不能出现在业务代码的 uses 里否则交付时目标机器上没有设计期包程序启动直接报缺包。正确的工程引用长这样// 业务单元只引运行时单元 uses Winapi.Windows, AdvGrid, // TAdvStringGrid 所在单元 AdvMemo, // TAdvMemo 所在单元 AdvEdit;逻辑说明这些单元由运行时包提供编译时要么链接进 exe关闭 Build with runtime packages要么运行时依赖对应的 .bpl。我一般会把「Build with runtime packages」关掉把用到的单元静态编进 exe省去跟客户解释一堆 bpl 的安装顺序代价是 exe 体积变大但组件包全源码版的目的本来就是让你能静态链接。提示查看工程选项 Project Options Packages确认「Build with runtime packages」里勾选的包不包含 dcl 开头的设计期包。4. 避坑排查D7 到 XE10.3 跨版本编译的五个高频问题4.1 设计期包装不上报「unit 同时存在于两个包」现象安装 dcl 包时 IDE 弹窗说某个单元同时存在于两个 package 里或者直接拒绝加载。原因最常见的是旧版本包没卸载干净IDE 注册表里残留了同名的 runtime 包你这次又用同样的包名注册了一遍两个 .bpl 里都含同一批单元冲突就出来了。解决先在 Component Install Packages 里把旧的 TMS 条目 Remove重启 IDE再按第 2 章的顺序从 runtime 包开始重装。如果 Remove 后仍然报冲突去注册表里搜关键词「TMS」或包名做清理操作前先备份注册表这条属于重武器我一般只在 Remove 失效时才用。4.2 同一段字符串代码D7 正常 XE10.3 乱码现象同样的业务单元D7 编译通过移植到 XE10.3 后字符串长度对不上写入数据库的中文变成问号。原因D7 的 string 是 AnsiString按字节计数XE10.3 的 string 是 UnicodeString按字符计数。拿到全源码包后组件内部代码是有条件编译分支的但它只对自己的单元负责你业务代码里若用了 PChar 指针偏移或逐个字节处理中文到 XE10.3 必然翻车。解决业务层统一用 string 类型和 Copy、Pos、Length 这些标准函数别直接动 PChar(Str)[i] 的索引实在要处理字节流比如解析协议包用 RawByteString 显式表达意图并在代码注释里写明「这是字节处理不是字符处理」。组件包源码里对 Ansi/Unicode 的切换分支可以作为参照照它那套条件编译写法改业务代码。4.3 多版本共用目录后D7 工程找不到单元现象两个 IDE 版本共用安装目录D7 工程突然编译不过提示找不到之前一直正常的某个单元。原因多半是装 XE10.3 时把 BPL/DCP 输出目录指到了 D7 的目录新编译的 DCU 覆盖了旧的或者 Library path 里加入的目录顺序变了IDE 优先找到的是 XE10.3 的 DCU而 D7 的编译器不认。解决按 2.3 的规划给每个 IDE 版本独立输出目录并在编译前确认当前 IDE 的 Library path 第一顺位是该版本自己的输出目录。排查手段是打开 Project Options Directories/Conditionals看 DCU 输出路径写的是不是当前版本目录这属于路径玄学十次有八次是这里出的问题。4.4 组件装上但面板图标全是默认圆球现象拖到窗体上能用属性也没问题就是组件面板上全是默认图标分不清哪个是哪个。原因设计期包编译时没把 .dcr 资源编进去。组件的 .dcr 文件在 Design 目录里.dpk 通过{$R xxx.dcr}指令引用如果只把 .pas 路径加进 Library path 而没带资源文件或者 .dpk 里的资源指令被注释掉就会得到没图标的包。解决检查 .dpk 源文件头部有没有{$R *.dcr}或显式的资源引用没有就补上再重编同时确认 .dcr 文件没有被杀毒软件当可疑文件删掉——这类文件在部分安全软件里确实会被误报解压时建议先加信任目录再解包。4.5 Win64 编译链接缺底层单元现象工程切到 Win64 编译链接器报缺某个 .obj 或单元文件但 Win32 编译一切正常。原因组件包官方分发的预编译 DCU 通常只有 Win32全源码版也得你把每个 runtime 包在 Win64 平台下重新 build 一遍产出 64 位 DCU 和 BPL只编了应用工程的 Win64组件单元没编链接器自然找不到。解决在 IDE 顶部的平台下拉框切到 Win64把第 2 章里涉及的所有功能包逐个 Build不是 CompileBuild 才强制重编全部单元再回到应用工程 Build 一次。注意 64 位下如果还开着设计期包记得同步重编 dcl 包否则 IDE 里拖组件会崩。5. 进阶验证与迁移技巧源码断点加适配层替换不伤老代码全源码版最大的底气是把黑匣子打开。我拿到包的第一件事不是写业务而是给候选组件加验证用例。以排序为例在 TAdvStringGrid 的排序相关源码里下断点点击表头触发排序确认比较回调返回的 -1/0/1 符合预期// 验证排序稳定性比较两行指定列的值 function TForm1.CompareRows(Grid: TAdvStringGrid; R1, R2, C1: Integer): Integer; begin Result : CompareText(Grid.Cells[C1, R1], Grid.Cells[C1, R2]); end;参数说明R1、R2 是要比较的两个行号C1 是排序列返回值语义与 CompareText 一致通过断点看这两行传入顺序就能确认包内排序算法是稳定排序还是非稳定这个特性直接影响报表里「同值保持原顺序」的需求。再比如 TAdvMemo 的高亮失效问题在分词器的 NextToken 相关源码下断点能看到状态机在哪个环节漏掉了关键字这比对着文档猜快得多。配合一个最小的验证工程把「拖组件 → 设属性 → 跑场景 → 看断点」固化成模板新版本到手先跑一遍模板再决定升级。替换老网格组件时我习惯多包一层适配器业务代码只依赖自己定义的 TGridAdapter 接口底层在标准网格和 TAdvStringGrid 之间切换切换只改适配器一个文件不动业务逻辑。拿到包之后先按第 2 章的顺序把 D7 和 XE10.3 两个版本的包各编一遍跑通最小样例再上业务。从那以后我每次评估新组件包都强制走一遍「装包 → 编样例 → 断点验证 → 写适配层」四步确认无误才会动老代码。希望帮到你。本文还有配套的精品资源点击获取