
简介面向Delphi 12.3及以上版本开发者的TMS FNC UI Pack v6.2.0.0控件扩展包专为解决跨平台用户界面组件复用与界面快速构建问题而设计适用于桌面、移动端与嵌入式风格应用等常见开发场景技能层级覆盖从入门调参到深入二次开发。压缩包共包含2000个文件其中.pas源码为控件核心实现.dproj/.dpr/.fmx/.dfm工程与窗体文件便于直接编译和查看设计界面.ico/.png/.svg等图标资源适配界面美工需求html/csv/txt则提供参考示例与辅助说明整体包大小约29.85MB。目前已有55人学习下载。通过本包开发者可拿到完整的控件源码、多个可直接运行的示例工程以及配套图标与文档既能安装后迅速搭建UI也可阅读源码理解TMS FNC控件的分层结构与事件机制对需要按业务定制控件外观或调试第三方组件的技术人员很有帮助。1. 为什么 TMS FNC UI Pack v6.2.0.0 值得 Delphi 12.3 用户动手装一次拿到一份 Delphi 12.3 控件之 TMS FNC UI Pack v6.2.0.0.rar很多人最先做的就是解压、双击 .dpk、点 Install然后在编译报错里耗掉半个下午。先给结论这套控件值得装但安装顺序比安装动作本身重要得多。FNC 是 Framework Neutral Components 的缩写核心价值是同一套 UI 控件源码能分别生成 VCL、FireMonkey 和 Lazarus 三个框架的版本属性和事件签名保持一致。对 Delphi 12.3 用户来说最实际的收益是维护 VCL 老项目、同时用 FMX 开新工程时界面代码不用各写一套。这篇文章按安装前、编译中、运行后的顺序把文件结构、库路径、关键参数和五个高频雷区一次讲完。2. 解压、文件结构与库路径安装 FNC 前先理顺这三件套很多人拿到 rar 后直接在里面双击 .dpk这是第一个翻车点。rar 里的包文件如果被 IDE 临时解压打开编译出来的 .dcu 会散落在临时目录重启一次 Delphi 就全部失效。正确做法是先把整个压缩包解压到固定位置再让 IDE 认识这个位置。2.1 英文目录加 7z 解压路径问题会伪装成编译问题我习惯用 7-Zip 命令行解压路径和输出目录都写在命令里可重复执行比图形界面更可控# 解压到固定目录注意 -o 后面没有空格 7z x delphi 12.3控件之TMS FNC UI Pack v6.2.0.0.rar -oD:\Components\TMS\FNCUI\参数说明x表示解压并保留内部目录结构-o指定目标根目录。目标目录我推荐用D:\Components\TMS\FNCUI\这样的全英文路径不要放在桌面更不要放在带空格或中文的路径下。FNC 包内的 .dproj 和 .groupproj 里大多是相对路径引用路径一出现空格或非 ASCII 字符Delphi 12.3 在解析资源文件时就可能报 E2209 或奇怪的 “File not found”到时候你会误以为是控件本身有问题。解压后先别急着打开 IDE花两分钟浏览一下目录结构。常见的布局是根目录下分docs、source、packages三大块packages里再按 Delphi 版本或编译平台分子目录。你需要记住两个关键东西.groupproj是安装入口source目录是后面配库路径要用到的源码位置。2.2 FNC 的跨框架原理它不是封装控件而是抽象一层自己的基类FNC 全称 Framework Neutral Components设计思路和普通第三方控件不一样。普通控件要么只做 VCL 版要么单独做 FMX 版两套源码独立维护界面逻辑经常对不上。FNC 是在控件继承树中间插了一层自己的基类按钮、面板、工具栏等控件都从这层基类派生底层是接 VCL 的 TWinControl、FMX 的 TControl还是 Lazarus 的 LCL 组件由编译时条件分支决定。这套机制带来的直接好处是同一个TMSFNCButton在 VCL 工程和 FMX 工程里属性名、事件签名、外观层级几乎一致。你在 VCL 下写的TMSFNCButton1.Appearance.Fill.Color : ...切到 FMX 项目里仍然成立。代价是它不完全继承 VCL 原生按钮的所有行为部分原生消息和事件需要手动适配比如输入法相关事件在 FNC 控件里就要单独处理。目标框架底层平台典型场景VCLWindows 原生窗口维护老项目、需要大量 Windows 原生交互FMXWindows / macOS / iOS / Android跨平台桌面与移动端统一界面Lazarus LCLLinux / Windows / macOS免费 IDE 环境下复用同一套源码实际安装时我一般只装 VCL 和 FMX 的包Lazarus 版除非你有跨 IDE 需求否则先不碰。一次全装不仅耗时间还容易出现两个同名 package 在 IDE 里互相挤占的情况Tool Palette 里看到两套同名控件会让你分不清哪个是哪个。2.3 Library Path 配置动手编译前先把源码告诉编译器这一步放在编译前面顺序反了会白等一次全量编译。打开 Tools Options Language Delphi Library然后在 Library path 里把刚才解压出来的source根目录加进去。注意 Delphi 12.3 的库路径是分平台保存的Win32 和 Win64 要分别添加只加一个会在切换平台时重新报单元找不到。添加完库路径后最好先做一个快速验证。新建一个 VCL Application在 uses 里写一个最小的 FNC 单元引用直接编译uses Vcl.Forms, TMSFNCButton;逻辑说明如果 Library path 配置正确编译器能在几秒内找到TMSFNCButton.pas并编译通过。这里TMSFNCButton是 FNC 按钮的单元名如果你下载的包版本里控件命名不同可以先到source目录里看一眼 .pas 文件名再替换。这一步能过滤掉八成“包文件本身有问题”的误判。3. 编译安装从 Project Manager 打开 .groupproj 到 Tool Palette 出现 FNC库路径配好再打开 .groupproj这时候编译才具备意义。整个安装过程的核心是分清 runtime 包和 design 包runtime 包负责生成程序运行时要链接的 .bpldesign 包负责向 IDE 注册组件。顺序搞反是最常见的安装失败原因。3.1 打开 .groupproj先看项目组里有哪些包再统一目标平台在 Project Manager 里右键打开解压目录下的.groupproj展开后你会看到一组 .dpk 文件命名上通常能看出用途比如带Runtime的是运行时包带Design的是设计时包带FMX的是 FireMonkey 专用包。第一次安装我建议先把项目组里所有包的目标平台统一切到 Win32 Debug全部编译通过后再切 Win64。为什么先走 32 位Delphi 12.3 的 IDE 本身是 64 位但编译第三方包时 32 位通常更快报错也更直观。等 32 位全链路验证通过再为 Win64 单独编译一套能避免你在排查问题时同时面对“平台不匹配”和“依赖缺失”两个变量。具体操作是选中项目组里的某个 .dpk右键选择 Build而不是 Compile。Build 会对依赖的单元做全量重编第一次安装时用 Build 最稳妥Compile 是增量编译如果上次的 .dcu 是旧的可能漏掉依赖更新。3.2 Runtime 包先编译Design 包后 Install这个顺序不能乱很多人第一次装第三方包看到 .dpk 就直接右键 Install结果报错说找不到某个 class 或无法加载包。原因就是 design 包依赖 runtime 包而 runtime 包还没编译。正确顺序是先对 runtime 包执行 Build生成 .bpl 和 .dcp 文件再对 design 包执行 Build 和 Install。如果 IDE 提示 “Package ... was not installed because it contains design-time and runtime components”说明你选错了包应该去安装那个专门的 design 包。安装完成后可以用命令确认 BPL 文件是否真的生成了。Delphi 12.x 的用户 BPL 目录一般在%APPDATA%下# 12.x 的 BDS 目录一般是 23.0检查 TMS 系列包是否已经生成 dir /b %APPDATA%\Embarcadero\BDS\23.0\Bpl\*TMS*逻辑说明dir /b只输出文件名*TMS*是通配符用来过滤所有带 TMS 字样的 .bpl。如果这里能看到对应文件至少说明 runtime 编译成功如果列表为空说明包编译输出到了别的位置去 Project Manager 里看该包的 Output 目录设置。这条命令属于验证手段不会修复任何问题但它能帮你把“是否编译成功”这个疑问快速了结。3.3 验证安装结果从 Tool Palette 搜索 FNC 并拖放到窗体安装完 design 包后需要重启 IDE 才能让 Tool Palette 完整刷新组件列表。重启后新建一个 VCL Application在 Tool Palette 左上角搜索框输入FNC应该能看到 TMS FNC UI Pack 分类分类名后面可能带 v6.2.0.0 版本号。拖一个 TMSFNCButton 到窗体上然后看 Object Inspector如果出现了Appearance、Corners这些 FNC 独有属性说明 design 包注册成功如果控件能拖上去但属性里只有普通组件属性说明你把 runtime 包装成了 design 包需要回到安装流程重新处理。如果 Tool Palette 里根本搜不到重点检查 Component Install Packages 里 TMS 项是否处于勾选状态。4. 最小可运行 Demo三个 FNC UI 控件的圆角、间距与外观参数安装成功只是开始真正让这套包“值回票价”的是参数配置方式。我从按钮、面板、工具栏三个最常用的控件入手讲清楚外层属性怎么拆解。4.1 TMSFNCButton圆角按钮的三层外观参数FNC 按钮和原生按钮最大的区别是外观被拆成了 Fill、Stroke、Font 三部分颜色、边框、文字统一挂在Appearance下面。修改圆角时要找Corners子对象而不是找 BorderRadius 之类的扁平属性。看下面这段procedure TForm1.FormCreate(Sender: TObject); begin TMSFNCButton1.Caption : 保存; TMSFNCButton1.Width : 120; TMSFNCButton1.Height : 36; // Appearance.Fill 控制填充色 TMSFNCButton1.Appearance.Fill.Color : $FF2E86AB; // Stroke 控制边框颜色和宽度 TMSFNCButton1.Appearance.Stroke.Color : $FF1B4965; TMSFNCButton1.Appearance.Stroke.Width : 1; // Corners 控制圆角类型和半径 TMSFNCButton1.Corners.CornerType : fcncctRound; TMSFNCButton1.Corners.RoundRadius : 10; TMSFNCButton1.Appearance.Font.Size : 11; end;逻辑说明fcncctRound是 FNC 的圆角枚举值前缀fcnc是 FNC 系列的统一命令空间标识。RoundRadius的单位是像素但放在不同 DPI 环境下显示效果会随系统缩放变化所以高分辨率屏幕最好把半径设计成相对值或者后续通过样式统一调整。事件绑定和原生 VCL 保持一致procedure TForm1.TMSFNCButton1Click(Sender: TObject); begin ShowMessage(FNC 按钮已保存); end;这个事件签名在 FMX 工程里同样成立Sender仍然是 TObject这是 FNC 跨框架复用的直接体现。4.2 TMSFNCPanel用圆角容器做一张卡片面板控件比按钮更值得用 FNC因为原生 VCL 的 TPanel 圆角支持很弱而 FMX 里要自己拼圆角矩形麻烦且不统一。用 TMSFNCPanel 做卡片四行代码就能完成TMSFNCPanel1.Width : 420; TMSFNCPanel1.Height : 240; TMSFNCPanel1.Corners.CornerType : fcncctRound; TMSFNCPanel1.Corners.RoundRadius : 16; TMSFNCPanel1.Fill.Color : $FFF0F4F8; TMSFNCPanel1.Border.Width : 1; TMSFNCPanel1.Border.Color : $FFBCC6CC;逻辑说明Fill是面板背景Border是描边两个子对象各自维护自己的状态。这里的颜色值是 ARGB 格式$FF开头表示不透明后面六位是 RGB。注意FNC 面板是自绘制的它不像原生 TPanel 那样能容纳原生 Windows 控件并让控件被圆角裁剪。如果你需要把普通 TButton 放上去子控件仍会按矩形区域显示这是 Windows 窗口机制的固有限制不是 FNC 的缺陷。要真正实现圆角裁剪效果建议把子控件也换成 FNC 系列。4.3 TMSFNCToolBar子控件间距与工具栏布局参数工具栏是界面里最容易出现“子控件间距”问题的场景。原生工具栏在 VCL 和 FMX 里布局参数差异很大FNC 把布局收敛到了一组统一的属性上。下面是用代码向工具栏添加按钮的常见做法// 清空默认项再按顺序加入按钮和分割条 TMSFNCToolBar1.Items.Clear; TMSFNCToolBar1.Items.AddButton(Open, 0); TMSFNCToolBar1.Items.AddSeparator; TMSFNCToolBar1.Items.AddButton(Save, 1); // 子控件间距控制每个 item 之间的空白像素 TMSFNCToolBar1.ItemSpacing : 6;逻辑说明Items.AddButton的第一个参数是标题第二个是整数索引后续可以靠索引来定位并修改按钮状态。ItemSpacing就是热词里常说的“子控件间距”我一般设置在 4 到 10 之间小于 4 会显得拥挤大于 10 在窄窗口下容易出现换行。工具栏本身是自绘制体不依赖系统窗口菜单所以切到 FMX 后布局基本不变这是跨框架复用最省心的地方。5. 避坑与常见问题安装 FNC UI Pack 时容易翻车的 5 个场景把安装 FNC 过程中最常见的五个问题单列出来每一条都是现象、原因、解决三步走。这些问题不只在 v6.2.0.0 上出现往后升级版本时也大概率会遇到。5.1 现象编译包时报 E2209 或 Cannot resolve unit TMSFNC...原因Library path 没有正确指向source根目录编译器在搜索路径里找不到 FNC 单元。这个报错最迷惑人的地方在于它往往在编译某一个 .dpk 时才出现看起来像是包本身缺文件。解决回到 Tools Options Language Delphi Library确认 Win32 和 Win64 两个平台都添加了源码目录。添加后先做 2.3 里的 uses 验证再回到项目组里编译。如果还报错检查 Library path 列表上方是否有旧版本 TMS 的 source 路径旧路径抢先命中会导致新包引用了旧单元。5.2 现象Install design 包时提示 Cant load package 或 .bpl 不是有效映像原因目标平台不匹配。比如 project manager 里当前平台是 Win64但你编译的是 Win32 的 design 包IDE 加载 32 位 .bpl 进 64 位进程时就会提示不是有效映像。解决把需要安装的 design 包在 Project Manager 里切到 Win64 后重新 Build再 Install。如果你的程序目标是 32 位也要保留对应的 32 位 design 包别把两个平台搞混。我的习惯是 32 位和 64 位各编译安装一遍虽然多花几分钟但后面调试不同平台的目标程序时不用来回切。5.3 现象程序运行到控件初始化时提示编译程序报内存错误或 Access violation原因机器上残留了多个版本的 TMS 包旧的 .bpl/.dcp 文件在新版本安装后被 IDE 按搜索路径先加载了。这是 Delphi 第三方组件最经典的黑匣子问题12.3 里也没能免俗。解决先关闭 Delphi搜一下整个系统里的 TMS 相关 .bpl、.dcp、.dcu 文件把旧版本的残留物全部移出 IDE 搜索路径最好直接删除。然后用 Everything 工具搜索*TMS*Bpl*和*TMS*Dcp*确认没有第二份副本后再重新编译安装。想省事的话重装系统前先把 AppData 下的 Embarcadero 缓存目录备份出来这也是后悔药的一种。5.4 现象Tool Palette 里搜不到 TMS FNC重启 IDE 也不出现原因design 包没有成功安装或者 IDE 组件缓存坏了。很多人以为 runtime 包编译通过就等于安装完成实际上 Tool Palette 的组件列表只由 design 包决定。解决先打开 Component Install Packages看列表里有没有 TMS 开头的条目。如果没有回到 Project Manager 右键 design 包执行 Install等到 IDE 弹出安装成功提示再重启。如果列表里有但控件不显示把 AppData 下 Embarcadero 的缓存目录改名强制 IDE 重新扫描组件这一招对很多“控件消失”问题都有效。5.5 现象FMX 工程拖入 FNC 控件后窗体上显示空白点击无响应原因框架不匹配。FNC 控件的 VCL 版和 FMX 版是分开编译的两个包如果你只装了 VCL design 包FMX 窗体上拖入控件后设计期可能看起来正常但运行期没有对应的 FMX 包链接界面就会空白。解决在 Project Manager 里找到带FMX字样的 design 包和 runtime 包分别编译并安装。装完后回到 FMX 窗体删除原来的控件重新从 Tool Palette 拖一个。注意别把 VCL 版控件和 FMX 版控件混在同一个窗体里FNC 不支持跨框架混用。6. 进阶技巧用样式复用、缓存与调试习惯把 FNC 用顺安装稳定之后真正考验人的是日常开发效率。下面三个技巧是我用 FNC 写界面时的固定习惯覆盖样式复用、性能控制和事件排查。6.1 把一套圆角配色存成样式跨窗体复用FNC 控件支持把外观参数整体保存到样式对象里再批量套用到其他控件。比如我把上述按钮的圆角和配色调好后用SaveToStyle存起来新按钮直接LoadFromStylevar Style: TFNCControlStyle; begin Style : TMSFNCButton1.SaveToStyle; TMSFNCButton2.LoadFromStyle(Style); end;逻辑说明TFNCControlStyle保存的是外观快照包含 Fill、Stroke、Font、Corners 等所有层级。通过这种方式修改主题时只需要改一个控件或一个样式对象不用在每个窗体里手工同步参数。6.2 控件多时用缓存与最小重绘避免卡顿当窗体上的 FNC 控件超过二十个你会发现界面重绘和缩放开始变慢。FNC 是自绘制控件复杂阴影、半透明效果和渐变填充会用掉不少性能。我的处理方式是批量修改控件属性时用BeginUpdate和EndUpdate包住操作让控件合并重绘而不是每改一个属性就刷新一次同时克制阴影和透明效果的使用优先靠纯色和描边拉开界面层次。6.3 事件不响应时先用断点确认消息链路如果 FNC 控件的点击事件没有触发先别怀疑控件坏了。在事件处理函数里打上断点运行程序点一下按钮看断点是否命中。没命中的话检查父容器是否把HitTest关闭了或者某个绘制型面板把鼠标事件吞掉了。这条排查路径在 VCL 和 FMX 下都适用。这套安装和调试的流程我完整走过多遍第一次就吃了没装 design 包就开始写代码的亏后来学乖了拿到任何版本的 FNC 包先解压到英文目录、配好库路径再用 Runtime 先编译、Design 后安装的顺序把所有包过一遍最后在空白窗体里把要用的控件各拖一次确认事件能触发才进入业务开发。这套流程验证过后你会发现 Delphi 12.3 下安装第三方组件并没有那么玄学希望帮到你。本文还有配套的精品资源点击获取