
简介这份资源是面向 Delphi 与 C Builder 开发者的 TMS VCL UI Pack v13.5.11.0 完整源码包适用于从 Delphi 7 到 13 Florence 的各版本环境尤其适合需要快速构建专业级 Windows 桌面界面的中高级开发者。压缩包共约 2000 个文件、123.99MB以 pas 源码、dfm 窗体、dproj/dpr 工程、res/dcr 资源、ico/jpg/png/bmp 图像及 pdf 文档为主另含 dpk 包文件、csv/xls 数据与少量 cpp、h 头文件覆盖组件源码、示例工程与素材资源。已有 120 人学习下载。借助完整源码读者可深入理解按钮、编辑框、列表框、导航抽屉、菜单、状态栏、进度条等控件的设计原理与实现方式按需定制样式与功能并参考示例工程快速集成到自己的项目中提升界面开发效率与代码质量。1. TMS VCL UI Pack 到底解决什么问题从一套源码包说起如果你正在用 Delphi 或 CBuilder 做 Windows 桌面项目大概率遇到过这种局面VCL 自带的 TStringGrid、TListView、TPageControl 能用但客户看一眼就说“太像 2005 年的软件”。想换第三方控件DevExpress 报价不低而且源码不给你出了问题只能等官方更新。TMS VCL UI Pack 就是在这个缝隙里被大量 Delphi 团队选中的方案——它是一套覆盖网格、编辑器、导航栏、日程、图表、富文本、工具栏等常见界面需求的 VCL 控件集合并且这个版本带 Full Source也就是完整源码随包提供。这次拆的是 TMS VCL UI Pack v13.5.11.0适配 Delphi CB 7 到 13 Florence。注意版本跨度从 Delphi 7 一直覆盖到 13意味着包里同时存在老式 DCU 兼容层和新版编译单元安装时不能一股脑全编。它适合三类人一是维护老 Delphi 项目、想低成本升级界面的二是需要读源码改控件行为的三是用 CBuilder 但找不到对应 HPP 头文件的。下面按“能装、能用、能改、能排错”的顺序走一遍。2. 安装与编译从包结构到 IDE 里真正跑起来2.1 先看清包里的目录结构再动手拿到压缩包解压后不要急着双击任何 dpk。TMS 这类多版本控件包的目录通常按“源码 包 示例 帮助”分层先花两分钟确认结构能省掉后面半小时的编译报错。常见布局是根目录下分Source、Packages、Demos、Help几个文件夹Packages里再按 Delphi 版本号分子目录。目录作用处理方式Source全部控件源码单元加入搜索路径不要手动编译Packages各版本 dpk/dproj 包工程按你的 IDE 版本选对应子目录Demos示例工程用来验证安装是否成功HelpCHM 或 HLP 帮助可选装完再看关键点在于Source是给 IDE 编译时引用的不是让你单独编译的。很多人翻车的第一个动作就是打开 Source 里的某个 pas 直接 Build结果一堆条件编译指令报错因为那些单元依赖包工程里定义的宏。2.2 按 IDE 版本选择正确的包工程Delphi 7 到 13 的包格式差异很大。Delphi 7 用的是老式 dpk从 Delphi 2009 开始引入 Unicode包内的字符串处理单元完全不同到 Delphi 10.x 之后又涉及 Win64 目标平台。所以Packages目录下一般会有类似Delphi7、Delphi11、Delphi12、Delphi13这样的子目录每个里面是一组 dpk。操作顺序建议这样# 以 Delphi 13 Florence 为例进入对应包目录 cd TMSVCLUIPack/Packages/Delphi13 # 目录里通常有多个 dpk按依赖顺序编译 # 先编译基础包再编译依赖它的高级包 ls *.dpk在 IDE 里的等价操作是File → Open Project选中基础 dpk右键 Install。如果包之间有依赖先装被依赖的那个。判断依赖关系的土办法是看 dpk 的 requires 子句里面列出的包必须先装好。提示Delphi 13 的 IDE 对包签名和搜索路径比老版本严格装之前先把Source目录加到 Tools → Options → Language → Delphi → Library 的 Library Path 里否则编译包时找不到单元。2.3 编译顺序与搜索路径配置假设包里基础包叫TMSVCLUIPack.dpk高级包叫TMSVCLUIPackExtras.dpk正确顺序是先基础后扩展。每个包装完后 IDE 会提示“是否重新编译依赖包”选是。全部装完后组件面板上会出现 TMS 分类页。搜索路径配置有个容易忽略的点32 位和 64 位要分别配。Delphi 13 默认可能只配了 Win32 的路径如果你要编译 Win64 目标得在 Library Path 里把平台切到 Windows 64-bit 再加一遍Source路径。CBuilder 用户还要额外确认 HPP 头文件生成选项是否打开否则 C 侧引用控件时会提示找不到头文件。// 验证安装是否成功的最小工程代码 procedure TForm1.FormCreate(Sender: TObject); var Grid: TTMSFNCGrid; begin Grid : TTMSFNCGrid.Create(Self); Grid.Parent : Self; Grid.Align : alClient; Grid.Cells[0, 0] : 安装成功; end;这段代码的作用是运行时动态创建一个 TMS 网格控件并填一个单元格。如果编译通过且运行后窗口里出现网格说明包安装和路径配置都没问题。参数上Parent必须设否则控件不显示Align : alClient让它铺满窗体方便肉眼确认。3. 核心控件上手网格、编辑器与导航栏的实战配置3.1 TAdvStringGrid 的数据绑定与性能参数TMS 里用得最多的控件之一就是 TAdvStringGrid它比 VCL 自带 TStringGrid 多了排序、过滤、合并单元格、内嵌按钮等能力。数据量大的时候性能差异非常明显。默认配置下往网格里灌一万行数据如果每写一个单元格都触发重绘界面会卡到怀疑人生。正确做法是先关掉重绘再批量填procedure TForm1.LoadData; var I: Integer; begin AdvStringGrid1.BeginUpdate; // 暂停重绘 try AdvStringGrid1.RowCount : 10001; // 含标题行 for I : 1 to 10000 do begin AdvStringGrid1.Cells[0, I] : IntToStr(I); AdvStringGrid1.Cells[1, I] : Item IntToStr(I); end; finally AdvStringGrid1.EndUpdate; // 恢复重绘并刷新 end; end;BeginUpdate/EndUpdate是这类网格控件的标准性能开关作用是把多次重绘合并成一次。参数上RowCount要设成数据行数加一因为第 0 行通常是标题。如果数据源是数据库更推荐用DataSource属性直接绑定 TDataSource让控件自己管理游标比手动填 Cells 快得多也少写很多同步代码。3.2 富文本与 HTML 编辑器的取舍TMS 包里带富文本编辑能力常见的是 TAdvRichEditor 这类控件。它的定位是轻量级富文本支持基础格式、图片插入、HTML 导入导出。如果你的需求只是让用户加粗、改颜色、插个表格它够用但如果要完整 CSS 渲染、复杂排版它和浏览器内核不是一回事别指望它当 Word 用。配置时重点看两个属性ReadOnly和HTMLMode。ReadOnly控制是否允许编辑HTMLMode决定导出内容是完整 HTML 文档还是片段。导出片段更适合嵌入已有页面导出完整文档则自带 head 和 body。// 把编辑器内容导出为 HTML 片段 procedure TForm1.ExportHTML; begin AdvRichEditor1.HTMLMode : hmFragment; AdvRichEditor1.SaveToFile(output.html); end;hmFragment表示只导出 body 内部内容适合后续拼接到模板里。如果选hmFull导出的文件可以直接用浏览器打开预览。这里没有玄学就是看你的下游怎么消费这段 HTML。3.3 导航栏与页面切换的状态管理TMS 的导航类控件如 TAdvToolBar、TAdvPageControl在复杂窗体里能明显减少手写布局代码。但页面切换时有个常见问题页面上的控件在页面未激活时是否已创建。如果用了延迟创建第一次切到某页时会有短暂卡顿如果全部预创建启动又慢。折中方案是预创建轻量页面重量级页面含大网格、图表延迟到第一次切换时再建。判断逻辑放在OnChanging或OnChanged事件里procedure TForm1.AdvPageControl1Changing(Sender: TObject; var AllowChange: Boolean); begin if (AdvPageControl1.ActivePage tabHeavy) and not HeavyPageBuilt then begin BuildHeavyPage; // 首次进入时才构建 HeavyPageBuilt : True; end; end;AllowChange默认 True除非你要阻止切换。HeavyPageBuilt是个布尔标志防止重复构建。这个模式在仪表盘类应用里很实用启动速度能快一截。4. 源码级定制改控件行为与 CBuilder 互操作4.1 读懂 Full Source 的条件编译结构带 Full Source 的最大价值是能改。但 TMS 的源码里条件编译指令很多直接改公共单元容易在下次升级时冲突。稳妥做法是先找到你要改的那个方法确认它没有被多个平台分支包裹然后在你的工程里用继承方式覆盖而不是直接改原文件。比如你想改网格某个单元格的绘制逻辑标准姿势是新建一个类继承 TAdvStringGrid重写DrawCell或对应的绘制方法把自定义逻辑放进去。这样原包升级时你的改动不受影响。type TMyGrid class(TAdvStringGrid) protected procedure DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); override; end; procedure TMyGrid.DrawCell(ACol, ARow: Integer; ARect: TRect; AState: TGridDrawState); begin inherited; // 先执行父类默认绘制 if (ACol 0) and (ARow 0) then Canvas.Brush.Color : clInfoBk; // 自定义首列背景 end;inherited不能省否则父类的绘制逻辑全丢单元格会变成空白。AState里包含是否选中、是否聚焦等信息按需判断。4.2 CBuilder 侧的 HPP 生成与引用CBuilder 用户装完包后如果组件面板能看到但代码里#include报错多半是 HPP 没生成。Delphi 编译包时有个选项叫“Generate C headers”默认可能没勾。重新编译包时勾上或者在 Project Options 里确认。C 侧引用 TMS 控件的头文件命名规则通常是单元名加.hpp比如TAdvStringGrid对应AdvGrid.hpp。如果找不到去包的输出目录里搜一下实际生成的文件名不同版本命名可能有细微差别。// CBuilder 中动态创建 TMS 网格 #include AdvGrid.hpp void __fastcall TForm1::FormCreate(TObject *Sender) { TAdvStringGrid *grid new TAdvStringGrid(this); grid-Parent this; grid-Align alClient; grid-Cells[0][0] C 侧创建成功; }注意 C 里属性赋值用-字符串用双引号。Cells[列][行]的索引顺序和 Delphi 的Cells[列, 行]一致别写反。4.3 版本升级时的源码合并策略从 v13.5.x 升到下一个版本时如果你改过源码直接覆盖会丢改动。建议用 Git 管理你修改过的文件升级时先拉官方新包再把你的改动以补丁形式应用。TMS 的更新频率不低养成这个习惯能省很多后悔药。5. 避坑与排查安装、编译、运行时的常见问题5.1 装完包组件面板不出现现象dpk 编译安装成功但 Tool Palette 里找不到 TMS 分类。原因通常是 IDE 的组件页缓存没刷新或者包被装到了错误的 IDE 实例比如同时装了 Delphi 12 和 13装到了 12 里。解决重启 IDE确认 Tools → Options → Environment → Delphi Options 里的包列表中有对应包且已勾选检查是不是多版本 IDE 装混了。5.2 编译时报找不到某个 dcu现象编译你的工程时提示TMSxxx.dcu not found。原因Library Path 里没加Source目录或者加了但平台不对Win32 加了Win64 没加。解决按目标平台分别配置搜索路径确认路径指向的是Source而不是Packages如果用了相对路径确认工程移动后路径没失效。5.3 运行时控件显示为空白或错位现象窗体设计器里正常运行时网格或导航栏空白、错位。原因常见于高 DPI 缩放场景TMS 控件的 DPI 感知设置和你的工程清单不一致。解决在工程选项里统一 DPI 感知级别检查控件的ScaleBy相关属性如果是多显示器不同缩放确认窗体创建时的 PixelsPerInch 处理。5.4 CBuilder 链接时报重复符号现象C 工程链接阶段报 multiple definition 或重复符号。原因同一个 TMS 单元被 Delphi 包和 C 静态库同时引入。解决确认只通过包方式引用不要在 C 工程里再手动添加 pas 文件检查包列表里是否有重复安装的 TMS 包版本。5.5 升级 Delphi 版本后包编译失败现象从 Delphi 12 升到 13 后原来能编的 TMS 包报错。原因新版本 IDE 的编译器对某些老式语法或已废弃单元更严格。解决用新版本对应的Packages子目录里的 dpk不要拿旧版 dpk 硬编如果官方还没出对应版本看Source里是否有条件编译开关能绕过废弃 API。6. 进阶技巧把 TMS 控件用出差异化的几个习惯第一个习惯是给每个 TMS 控件写一个薄封装单元。不要直接在业务窗体里散落AdvStringGrid1.Cells[...]这种调用而是包一层TMyGridHelper把常用配置列宽、排序、导出收进去。这样换控件或升级时只改一个地方。我见过一个项目因为没做这层后来从 TMS 换到另一套控件改了三百多个文件。第二个习惯是利用 Full Source 做“只读侦察”。遇到控件行为不符合预期时别急着搜论坛直接打开对应源码单元看那个属性 setter 里到底做了什么。比如你设了某个颜色不生效源码里可能有个条件判断把它覆盖了。这种第一手信息比任何文档都准。第三个习惯是导出功能统一走一个入口。TMS 网格和富文本都支持导出 HTML、CSV、PDF部分控件但每个控件的导出 API 不一样。写一个IExportable接口让需要导出的控件适配它业务代码只调接口。下面是个简化示例type IExportable interface procedure ExportTo(const AFileName: string); end; TGridExporter class(TInterfacedObject, IExportable) private FGrid: TAdvStringGrid; public constructor Create(AGrid: TAdvStringGrid); procedure ExportTo(const AFileName: string); end; procedure TGridExporter.ExportTo(const AFileName: string); begin FGrid.SaveToCSV(AFileName); // 具体导出格式按需换 end;TInterfacedObject提供引用计数ExportTo里调具体控件的保存方法。这样业务侧只依赖IExportable不依赖具体控件类型。最后一个习惯是版本锁定。TMS 每个小版本都可能修 bug 也可能引入新 bug团队里要统一用一个版本号写进工程文档。升级前先在分支上跑一遍所有用到 TMS 的窗体确认没有视觉和交互回归再合并。从那以后我每次拿到新版本包都先在一个空白工程里装一遍、跑一个最小示例确认没问题才往主工程里引。希望帮到你。本文还有配套的精品资源点击获取