ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

TMS VCL UI Pack v13.5.11.0 完整源码版安装与实战详解

TMS VCL UI Pack v13.5.11.0 完整源码版安装与实战详解 简介在Delphi与CBuilder的桌面开发生态中VCL组件库一直是提升界面效率与业务功能的关键工具。TMS VCL UI Pack作为一款涵盖网格、图表、JSON解析、加密算法等能力的“常备组件全家桶”其完整源码版不仅支持从Delphi 7到RAD Studio 11.x的跨版本编译还能通过自定义源码编译适配不同IDE环境解决控件版本冲突和安装后丢失等常见问题。理解其包结构、条件编译机制以及Library Path配置原理是顺利集成的基础。在实际工程中无论是利用TAdvStringGrid实现数据展示与Excel导出还是通过TMS主题系统快速统一界面风格都能显著降低开发成本。本文围绕源码安装流程、核心组件实战、高频踩坑点如控件丢失、BPL定位失败、高DPI模糊展开为Delphi老手和转型新人提供了一套可落地的工程实践指南帮助开发者用好这套组件库少走弯路。1. 项目概述与版本解读先说结论这套 TMS VCL UI Pack v13.5.11.0是我近期在备料 Delphi 和 CBuilder 老项目时拿到的一份比较难得的完整源码版本。它覆盖了 Delphi 7 一路到 Delphi 13 Florence也就是 RAD Studio 11.x 那个时代线CBuilder 同样在支持范围内17 个版本号跨度的产品线能做到一个包全兼容在整个 VCL 第三方控件生态里也是不多见的。很多朋友一看到UI Pack就以为只是一堆皮肤和界面美化组件这是个误区。TMS VCL UI Pack 这个官方叫做组件全家桶的东西实际包含的远不止 UI 控件它有网格、表格、编辑框、树形视图、计划排程、仪表盘、图表、文件对话框、浏览器容器、JSON 解析、加密算法、网络请求等一系列模块。说白了它更像是一个常备组件库而不是单纯的换肤皮肤包。从我多年做 Delphi 项目的体感来说装了 TMS VCL UI Pack 之后很多日常小需求就不需要再到处找第三方控件了。至于标题里的FLorence这是 Embarcadero 给 RAD Studio 11.3 Alexandria 之后某个更新版本起的代号实际在 12 Athens 之前的一个内部或区域 codename在这个版本的 TMS 包中意味着对最新的 Delphi 编译器、最新的 VCL 风格系统、以及新版 Windows 11 上一些新增 UI 行为都做了适配。如果你正在用 Delphi 10.4 或 11.x这个版本是可以直接安装进 IDE 的如果你还在守 Delphi 7 的老项目这个包同样保留了对老版本编译器的兼容层这一点对做老项目维护的人来说非常关键。适合谁来读这篇文章呢二类人 一是 Delphi 老手用过 TMS 但没深入折腾过完整源码版想知道怎么编译、怎么集成、怎么解决安装后的坑 二是从其他语言转 Delphi 的新人想通过一个高质量组件库快速构建界面和业务功能少走弯路。这篇博文我就围绕这套控件的安装、配置、核心组件实战和踩坑实录四块内容展开文末再分享一些我个人维护多年 Delphi 工程的经验。内容基本都是实际动手才能遇到的问题希望对你有点用。2. 安装前必须搞懂的三件事2.1 Delphi 版本兼容性不是拿来就能装这是这套 TMS 包最容易被人忽略的地方。虽然标题写着for Delphi CB 7-13听起来很美好但它不是一个单一的安装包而是针对多个 IDE 版本分别做了不同的运行时和设计时包。你下载到的压缩包打开后通常会看到类似这样的目录结构Packages/ Delphi7/ Delphi2009/ DelphiXE/ Delphi10.4/ Delphi11/ Delphi12/ CB2009/ CB10.4/ ...每个子目录下都有对应的 .dpk 或 .cbproj 工程文件。你在哪个版本的 IDE 里用就进哪个目录去编译安装不能混用。比如你用的是 Delphi 10.4 Sydney就不要去打开 Delphi7 目录下的 .dpk编译大概率报错反过来如果你在 Delphi 7 里打开新版工程的 .dpk也会因为使用了新语法和不支持的 RTL 函数而直接失败。这里有个容易踩的坑TMS 官方为了保证老版本兼容性经常会用条件编译指令来区分不同 IDE 版本。比如在同一个 .pas 源文件里你会看到类似这样的代码{$IFDEF VER330} // Delphi 10.3 // 新版实现 {$ELSE} // 老版本兼容实现 {$ENDIF}这意味着即使你看到源码版本号很高它也保留了老版本编译器的兼容分支。但注意不是所有组件都支持老版本个别新出的组件可能只在 Delphi 10.3 以上可用。装之前最好到 TMS 官网上核对一下每个组件的版本兼容表或者直接看压缩包内的 readme.txt。2.2 完整源码版和正式安装版的区别很多人一听到完整源码版就以为跟免费开源一样其实不是。TMS 控件是商业授权产品只是交付方式上分了不同形态正式安装版Setup.exe编译好的 .bpl 运行时包 设计时包直接安装到 IDE方便但没法看源码也没法改源码。完整源码版FS Full Source所有 .pas 文件所有 .dpk 工程文件你有完整源码可以在 IDE 里自己编译安装也可以把源码加入自己的项目里做二次修改和定制。FS 版最大的好处不只是能看源码而是它能绕开一些二进制包和 IDE 版本之间的兼容性问题。比如你用的是 Delphi 11.3但官方安装包可能只提供了 11.0 或 11.1 的预编译 .bpl这时候你直接用源码编译就能适配到自己的 IDE 版本上。因为 Delphi 的 RTL/VCL 在不同 minor 版本之间如果接口变化不大源码重编译基本能过。再一个好处是可以精简组件集。有些项目只需要 TMS 的网格和计划排程不想把整个包十几个 .bpl 都装进 IDE那就可以只挑你需要的 dpk 来编译这样 IDE 启动速度更快发布的 exe 体积也更小。2.3 安装前系统环境检查清单在动手编译之前我建议你先确认以下几项不然编译过程中报错会绕很多弯IDE 版本必须明确最好准确到 Update 版本号。比如 Delphi 10.4.2 和 10.4.0 之间有细微的 RTL 差异个别源码可能编译不过。操作系统是 32 位还是 64 位。从 Delphi XE2 开始支持 64 位编译但 TMS 的 .bpl 设计时包有些只能 32 位加载进 IDE因为 IDE 本身是 32 位进程编译 Win64 程序时用的是运行时包这个要分清楚。是否安装了第三方依赖库。TMS VCL UI Pack 有些组件依赖 Indy、TMS FlexCel 等第三方库尤其是导出 Excel、报表相关功能如果没装对应依赖编译会报找不到单元。比如你想用 TAdvStringGrid 导出 xlsx就可能需要 FlexCel 的源码头文件。路径里不要有中文或空格。老版本编译器对路径中的中文支持非常差像 D:\源码\TMS UI Pack 这种路径编译时经常出现 Cannot open file 的诡异错误。提示建议把 TMS 的源码解压到一个纯英文、无空格的根目录比如D:\Components\TMSVCL然后在 IDE 的 Library Path 里添加这个路径。这个习惯能帮你省掉很多不必要的麻烦。3. 实操IDE 里编译安装 TMS 包3.1 编译环境的配置顺序这一步非常关键顺序错了可能要绕远路。我的做法是打开 Delphi IDE先不要急着打开任何包工程。菜单 Tools Options Environment Options Delphi Options Library 里把你解压后的 TMS 源码目录下对应版本的 Source 子目录添加到 Library Path 中。然后把 TMS 源码目录下 Packages\你的IDE版本 里的 .dpk 文件批量打开。先编译运行时包通常是 TMSXXR.dpk其中 XX 是版本号或功能缩写再编译设计时包TMSXXD.dpk。编译顺序不能乱。设计时包依赖运行时包运行时包依赖源文件如果你先把设计时包拎出来编译铁定报 Unit not found。关于包编译有一个经验分享优先用 dcc32 命令行编译而不是在 IDE 里右键 Compile。因为源码包里的 .dpk 文件往往有很多条件编译指令IDE 的编译器有时候不会自动启用所有路径导致一些奇怪的报错。命令行编译的话你可以精确控制输出路径还能把编译日志导出排查问题一目了然。这个包我用命令行编译过一次以 Delphi 10.4 为例手动执行的命令类似这样dcc32 -B –LE:\Output\BPL –LN:E:\Output\DCP –LU:rtl;vcl TMSR.dpk dcc32 -B –LE:\Output\BPL –LN:E:\Output\DCP –LU:rtl;vcl;TMSR TMSD.dpk其中-LE指定 BPL 输出目录-LN指定 DCP 输出目录-LU指定需要的其他包名。如果你不想记这么多参数也可以在 IDE 里操作但切记把 Source 路径放到 Library Path 的最前面避免 IDE 不小心拉到其他旧版本的 TMS 单元。3.2 为什么总有人编译不过TMS包我经常在群里看到有人问为什么我编译 TMS 的包总是报错 其实多数情况跟 TMS 自身没关系而是由于 IDE 环境中存在其他第三方控件的源码路径冲突。Delphi 的单元查找顺序是按 Library Path 中路径的先后顺序来的谁排在前面就先找谁。如果你之前装了另一个版本的 TMS 控件或者装了包含同名单元的其他库把 TMS 路径加进去之后编译器可能找到的是旧版本的 .dcu结果各种函数签名对不上报错报得很莫名其妙。解决办法是打开 IDE 的 Project Options Delphi Compiler Search Path把当前工程的搜索路径调整一下确保 TMS 的源码目录在这个工程里处于最高优先级。或者干脆把其他旧版 TMS 的路径从 Library Path 里移除清理掉旧版本的 .dcu 和 .bpl。3.3 安装后的验证手段装完以后你不要直接进 IDE 拖控件那样很容易踩到组件安装不完整的坑。正确的验证流程是在 IDE 里新建一个 VCL Application。打开 Component Install Packages确认 TMS 相关的设计时包已经勾选上。在窗体上尝试放置几个代表性组件比如 TAdvStringGrid、TAdvEdit、TMSThemeManager看看是否能正常显示。给窗体放一个按钮没写任何代码直接编译运行确认最基本的 VCL 程序能跑通。再试试放一个 TAdvStringGrid在代码里给它的 Cells 属性赋值编译运行如果能正常显示基本就说明运行时包也正常。注意不要在同一个 IDE 版本中同时安装两个不同大版本的 TMS 包比如既装 13.x 又装 12.x设计时包重名会导致 IDE 直接崩溃或控件不显示。如果你确实需要切换版本请到 Component Install Packages 中先移除旧包重启 IDE再安装新包。4. 核心组件深度拆解这些才是你真正会天天用的4.1 TMS 主题系统与窗体美化TMS 的 UI Pack 里最出名的就是 TMSThemeManager 系列组件。它提供了一整套 VCL 主题渲染机制可以让标准 VCL 控件TButton、TPanel、TEdit 等自动变成现代扁平风格无需大幅改代码。我自己的项目里最常用的是 TAdvPanel 和 TAdvToolBar 配合 TMSThemeManager 做整体界面框架。做法是在 MainForm 上放一个 TMSThemeManager把 Theme 设为ttOffice2019Colorful或ttOffice2016DarkGray。把 TAdvPanel 作为主容器设置Parent为 MainFormAlign设为alClient。在 TAdvPanel 上放 TAdvToolBar放入 TAdvToolBarButton 来做菜单按钮通过Glyph加载图标资源。按钮的 Caption 可以直接显示文字图标比如导出报表。这套做法的好处是相比原生 TPanelTButton能做出明显接近现代桌面软件的外观还不需要学习额外的皮肤引擎比如 VCLSkin学习成本低很多。4.2 TAdvStringGrid能打的数据网格TAdvStringGrid 是 TMS 家族里最有含金量的组件之一。它自带排序、合并单元格、列筛选、自适应列宽、数据导入导出、下拉列表单元格、进度条单元格等功能。我在做管理系统时通常直接用 TAdvStringGrid 替代原生 TStringGrid 或 TDBGrid。一个典型用法是给网格设置下拉列表var I: Integer; begin AdvStringGrid1.ColCount : 4; AdvStringGrid1.RowCount : 100; AdvStringGrid1.Cells[0, 0] : 姓名; AdvStringGrid1.Cells[1, 0] : 年龄; AdvStringGrid1.Cells[2, 0] : 部门; AdvStringGrid1.Cells[3, 0] : 状态; AdvStringGrid1.AddComboCell(2, 1, 研发部;市场部;测试部;运维部, False); for I : 1 to 99 do begin AdvStringGrid1.Cells[0, I] : 用户 IntToStr(I); AdvStringGrid1.Cells[1, I] : IntToStr(20 (I mod 30)); AdvStringGrid1.Cells[3, I] : 在职; end; end;这个小例子虽然简单但你能体会到它数据结构上的灵活性。它不像 TDBGrid 那样必须绑定数据集而是可以完全用 Cells 属性手动管理数据这对一些临时数据展示、导入导出记录列表非常方便。如果做正式的报表展示我还会用它的MergeCells方法来合并表头单元格让列分组显示更清晰AdvStringGrid1.MergeCells(0, 0, 2, 1); // 横向合并两列表头4.3 数据录入控件TAdvEdit 与 TAdvDateTimePickerTMS 的编辑框类组件最大的优势是自带校验、掩码、图形化提示不需要自己写大量 OnExit 和 KeyPress 事件。比如 TAdvEdit 的Filter属性可以直接设置为tfInteger或tfNumber这样用户就只能输入数字设置MaxLength控制长度设置Required控制是否必填再配合LabelCaption可以自动显示标签文字。举个例子做身份证号输入框除了长度限制还可以用OnValidate事件自定义校验规则procedure TForm1.AdvEditIDExit(Sender: TObject); begin if (Length(AdvEditID.Text) 18) then begin MessageDlg(身份证号码长度必须为18位, mtWarning, [mbOK], 0); AdvEditID.SetFocus; end; end;TAdvDateTimePicker 则比原生的 TDateTimePicker 功能更强它的Format属性支持更复杂的自定义日期格式串比如yyyy年mm月dd日还可以直接绑定日期时间做排程项目时非常省心。4.4 导出 ExcelMemo 数据快速落盘很多 Delphi 新人常问怎么把 Memo 里的数据导出到 Excel。其实用 TMS 的 TAdvStringGrid 是最快的路径因为 TAdvStringGrid 自带SaveToXLSX方法var I: Integer; begin AdvStringGrid1.Clear; AdvStringGrid1.ColCount : 2; AdvStringGrid1.RowCount : Memo1.Lines.Count 1; AdvStringGrid1.Cells[0, 0] : 序号; AdvStringGrid1.Cells[1, 0] : 内容; for I : 0 to Memo1.Lines.Count - 1 do begin AdvStringGrid1.Cells[0, I 1] : IntToStr(I 1); AdvStringGrid1.Cells[1, I 1] : Memo1.Lines[I]; end; AdvStringGrid1.SaveToXLSX(D:\output.xlsx); end;这里有一个关键点SaveToXLSX方法在高版本的 TMS 包中默认依赖 FlexCel 引擎如果编译时没把 FlexCel 相关目录加进 Search Path这个方法会在编译阶段直接报错。解决方案有两个一是去安装 FlexCel 并添加路径二是改用SaveToXLS老格式或直接导出 CSV。如果需求只是用 Excel 能打开导出 CSV 其实更轻量AdvStringGrid1.SaveToCSV(D:\output.csv, ;);CSV 兼容性极好Excel 双击就能打开只是没有格式信息。4.5 JSON 解析Delphi 的 JSON 处理不能只靠手写从 Delphi 10.3 起RTL 的System.JSON已经很强大了但 TMS 依然在 UI Pack 里提供了一些 JSON 相关的辅助控件比如 TJSONObjectHelper、TAdvJSONObject等。其实很多老项目还在用 Delphi 7那么 TMS 里带的 JSON 解析器就非常有价值了。它的使用方式和 System.JSON 类似只是 API 名称不同但胜在老版本的 Delphi 也能用。以 Delphi 10.4 为例如果你用的是 System.JSON解析一段字符串通常这样写uses System.JSON; var jsonObj: TJSONObject; jsonValue: TJSONValue; begin jsonObj : TJSONObject.ParseJSONValue({name:Delphi,ver:10.4}) as TJSONObject; try jsonValue : jsonObj.GetValue(name); ShowMessage(jsonValue.Value); finally jsonObj.Free; end; end;如果你是用 TMS 的 JSON 类API 风格也差不多只是命名空间不同。关键问题是不要在你的项目里两种 JSON 库混用。因为两个库的对象模型不同一旦混用容易出现对象释放两次、内存越界等问题。4.6 置顶窗体与窗口行为控制热搜词里有个delphi让自身置顶这是非常常见的需求。用原生 Windows API 其实就两行SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE);如果想让窗口取消置顶就改成HWND_NOTOPMOST。TMS 里有封装好的组件来做这件事比如 TMSFormAlert 之类的通知窗口。但很多场景下你并不需要引入额外组件直接在 MainForm 的 OnShow 事件里写一行 API 就够了。真正的坑点在于有些程序在显示其他模态窗口之后置顶效果会丢失。这是因为模态窗口通常会改变 Z 序。解决办法是在OnActivate事件里重新设置一次procedure TForm1.FormActivate(Sender: TObject); begin SetWindowPos(Handle, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE or SWP_NOSIZE or SWP_NOACTIVATE); end;这个方法很朴素但确实管用。我也见过有人用 Timer 轮询来强制置顶除非万不得已我不推荐因为会出现窗口闪烁而且容易干扰用户操作。4.7 执行 DOS 命令并获取返回值这也是 Delphi 老项目里极其常见的需求。如果你只是用ShellExecute执行外部 EXE那你拿不到输出结果。正确做法是用 CreateProcess 配合管道重定向。我这里用一个最小可用的封装示例兼容 Delphi 7 到 Delphi 11function RunDosAndGetOutput(const CmdLine: string): string; var SA: TSecurityAttributes; SI: TStartupInfo; PI: TProcessInformation; hReadPipe, hWritePipe: THandle; Buffer: array[0..255] of AnsiChar; BytesRead: DWORD; TotalRead: string; begin SA.nLength : SizeOf(SA); SA.bInheritHandle : True; SA.lpSecurityDescriptor : nil; CreatePipe(hReadPipe, hWritePipe, SA, 0); SetHandleInformation(hReadPipe, HANDLE_FLAG_INHERIT, 0); FillChar(SI, SizeOf(SI), 0); SI.cb : SizeOf(SI); SI.dwFlags : STARTF_USESTDHANDLES; SI.hStdOutput : hWritePipe; SI.hStdError : hWritePipe; FillChar(PI, SizeOf(PI), 0); if CreateProcess(nil, PChar(CmdLine), nil, nil, True, CREATE_NO_WINDOW, nil, nil, SI, PI) then begin CloseHandle(hWritePipe); TotalRead : ; repeat BytesRead : 0; if not ReadFile(hReadPipe, Buffer, SizeOf(Buffer) - 1, BytesRead, nil) then Break; Buffer[BytesRead] : #0; TotalRead : TotalRead String(Buffer); until BytesRead 0; WaitForSingleObject(PI.hProcess, INFINITE); CloseHandle(PI.hThread); CloseHandle(PI.hProcess); CloseHandle(hReadPipe); end; Result : TotalRead; end;这段代码对新手来说可能有点绕但它的原理很清晰创建管道子进程的标准输出重定向到管道写端父进程从管道读端读取内容直到读到 EOF。使用示例ShowMessage(RunDosAndGetOutput(ping -n 1 127.0.0.1));需要特别提醒的是受信任的 Windows 上CreateProcess第一个参数传nil第二个参数传完整命令行字符串是正确方式但需要注意如果路径中有空格必须用引号包裹整个可执行文件路径比如C:\Program Files\SomeApp\app.exe -arg。5. 高频实战问题实录5.1 每次进入 IDE控件都丢失怎么办这个话题是热词里我看到最扎心的delphi 控件版本问题 导致 每次进入ide都丢失控件需要重新放置保存后还是那样。这个问题其实很多原因但最常见的三个设计时包没有安装成功或者被 IDE 禁用了。打开 Component Install Packages看有没有对应的 TMS 包。如果没勾选勾上。控件的单元名没有加到uses列表里。.dfm文件里如果引用了不在 uses 中的单元打开窗体时 IDE 会报错拒绝加载该窗体一般表现为窗体没了或控件全丢了。.dfm文件保存时的资源格式问题。如果你从旧版本 Delphi 打开新版本生成的含 TMS 控件的.dfm文件老的.dfm是文本格式新版本是二进制格式或反过来可能会出错。针对第二种我实际处理过的一个案例朋友在 Delphi 10.4 中放了一个 TAdvStringGrid保存后关了工程第二天再打开窗体提示找不到 TAdvStringGrid然后整个窗体打不开。我看了一眼.pas文件的 uses 里只写了AdvStringGrid但 IDE 需要的是TMSAdvGrid或AdvGrid单元。原因是他拖动控件时 IDE 自动生成的 uses 有问题或者手动删除了某个单元引用。修复方法是在.pas文件的 uses 中手动补上AdvGrid, AdvObj, AdvUtil等单元然后重新编译。如果.dfm文件又坏了可以用文本方式打开.dfm手动把对象声明补全。这不是 TMS 的锅而是 Delphi 的 DFM 引用机制决定的。5.2 编译时提示无法定位 .bpl 文件这种问题多半是运行时 BPL 没有复制到系统目录或程序所在目录。你可以把编译出的 BPL 直接复制到 exe 的同一目录也可以把 BPL 所在目录加入环境变量 PATH。如果你希望发布给用户的 exe 不依赖 TMS 的 BPL那么应该在项目的 Link with runtime packages 中取消勾选。做法是 Project Options C Compiler / Delphi Compiler Linking把Link with runtime packages设为 False。这样编译出来的 exe 会自动把用到的 TMS 单元静态链接进来发布时只需要一个 exe不需要带任何 BPL。TMS 组件总体不算特别大静态链接之后 exe 增加 5 到 15 MB 左右完全可以接受。相反如果用动态 BPL虽然 exe 小但发布时少带一个 BPL 都会闪退排查起来非常麻烦。5.3 高 DPI 缩放下窗体模糊Delphi 10.4 以上对高 DPI 的支持已经有明显改善但 TMS 部分老组件在某些情况下还是会模糊。如果你是 Windows 10/11 用户且屏幕缩放是 125% 或 150%建议在.dpr文件靠前位置加入Application.HighDPI : True; Application.HandleScaling : True;如果你的工程文件是早期版本创建的可能没有这两行手动加上即可。但要注意TMS 某些老控件比如 TAdvStringGrid 的部分版本在高 DPI 下可能会发生行高计算错误需要在FormCreate里做一次强制刷新AdvStringGrid1.AutoSize : True; AdvStringGrid1.AutoSize : False;这样能触发一次重绘行高会自动校正。5.4 MD5 与字符串处理老版本环境的实用姿势热词里反复出现 delphi 10.4 md5计算、delphi 字符串函数、MD5这里我多说一句。现代 DelphiXE 以上可以直接用System.Hash.THashMD5uses System.Hash; function GetMD5(const S: string): string; begin Result : THashMD5.GetHashString(S); end;如果是 Delphi 7那你自己可以封装一个模块或者用 TMS 的加密组件。其实 TMS 包中带有加密组件可以用来计算 MD5、SHA1、CRC32 等在 TMS Crypto 包中。不过我要提醒的是MD5 只适合做校验、去重、签名线索绝不要当安全密码哈希用这是 2025 年人人都该有的常识。字符串函数方面Delphi 的 RTL 其实已经非常强了TStringHelper、TStringBuilder在 10.4 里都很好用。只要你在代码里加上System.SysUtils就可以用Split、StartsWith、Contains等方法。很多新人还在用旧的Pos、Copy函数不是说不行但这些新方法可读性更强推荐优先使用。5.5 FDQuery / ADO 连接 ExcelDelphi 连接 Excel 的方式非常多可以用 ADO、ODBC、或者直接 OLE。最简单的方案是使用 ADOConnection 连接 Excel 文件ADOConnection1.ConnectionString : ProviderMicrosoft.ACE.OLEDB.12.0; Data SourceD:\data.xlsx; Extended PropertiesExcel 12.0 Xml;HDRYES;IMEX1;; ADOConnection1.Connected : True;这样 TADOQuery 就能直接执行SELECT * FROM [Sheet1$]了。但我必须泼一盆冷水这种方式对 Excel 文件格式要求比较高遇到一些带合并单元格、公式复杂、多 Sheet 的工作簿可能会失败或读错数据。实际生产环境里我更推荐先把 Excel 另存为 CSV然后用 TStringList 或 TAdvStringGrid 加载稳定性和可控性都更好。TMS 的 TAdvStringGrid 加载 CSV 非常简单AdvStringGrid1.LoadFromCSV(D:\data.csv, ;);不需要 OLEDB 驱动不需要权限配置几乎不会出错。5.6 FireMonkey 与 VCL 的差距提醒很多从 VCL 转 FireMonkey 的开发者会困惑TMS VCL UI Pack 能不能用在 FireMonkey 上 答案是不能直接使用。TMS 有独立的 FireMonkey 版本但是是不同的安装包。VCL 版本是基于 WinAPI 控制句柄的F MX 版本是基于自绘制的两者 API 差异巨大。如果你打算用 Delphi 写 PDA 或安卓扫码应用那必须走 FireMonkey或者用 TMS 的 NEON 套件TMS NEON 是 FireMonkey 的组件套件。不过我要提醒的是同样的业务逻辑尽量放到底层单元里让 VCL 和 FMX 共用界面层别混用否则维护成本会很高。6. 我的实际操作体会最后聊点软性的东西。这些年我经手的老项目里Delphi 7 到 Delphi 11 的都有。TMS VCL UI Pack 这种控件库最大的价值不是某个组件功能多强大而是它能统一团队里不同项目之间的 UI 风格和交互模式。以前每个开发写自己的界面番茄炒蛋风格全都有后来统一用了 TMS 主题之后视觉上真的干净了很多。但我也要提醒控件库不是越多越好。TMS 包很大如果你的项目只是需要几个组件建议只挑需要的 dpk 安装不要整套全装进 IDE。因为每多一个设计时包IDE 启动可能慢几秒项目编译也可能多出一些不必要的开销而且一旦出问题排查范围会变大。我自己在实际项目中通常只装这几个模块TMS Grid、TMS Edit、TMS Theme、TMS Planning、TMS JSON/Crypto 这几个其他用到时再加。这样既能保持 IDE 轻盈也能控制软件的体积。再一个很实在的经验是不管装什么第三方控件先编译再安装先小项目验证再正式集成别一上来就一把梭。很多控件冲突要等到你集成到中大型项目里才会暴露早发现早处理晚发现就是加班。最后再分享一个小技巧TMS 包源码是跟着 Delphi 版本走的如果你需要同时维护 Delphi 7 和 Delphi 11 两个项目建议在同一个工作目录下建两个子目录分别放不同版本的 TMS 源码然后在各自的 Library Path 中分别指向它们。千万不要让两个版本共用同一个源码目录因为编译器的 .dcu 缓存路径一旦写错会交叉污染到时候各种 Unit not found 会让你怀疑人生。本文还有配套的精品资源点击获取
返回列表