TMS FNC Core 跨框架控件安装与避坑指南:从 XE7 到 13 Florence 简介TMS FNC Core v4.2.2.4 是面向 Delphi 与 C Builder XE7-13 Florence 开发者的跨平台控件库适合需要一套代码覆盖 Windows、macOS、Linux 及移动端的中高级开发者用于构建统一 UI、减少平台适配成本。压缩包共 824 个文件约 6.36MB以 452 个 pas 源码、34 个 dpr 工程、63 个 dproj 项目文件、29 个 dpk 包文件为主另含 dfm/fmx 窗体、dcr 组件资源、res/ico 图标及少量 html、style、jar 等完整源码便于二次编译与定制。资源附带文档与示例代码覆盖按钮、列表、编辑框等常用控件支持高级图形渲染、触摸与鼠标输入并集成响应式与模块化设计思路可帮助读者快速上手、理解控件特性并集成到现有项目。目前已有 44 人学习下载。1. TMS FNC Core 到底是什么从 XE7 到 13 Florence 的跨框架底座如果你手上有一份TMS FNC Core v4.2.2.4 for Delphi CB XE7-13 Florence Full Source.rar先别急着解压双击安装。这个包真正值钱的地方不是里面有多少个.pas文件而是它解决了一个从 Delphi XE7 一路拖到 13 Florence 都没被官方彻底摆平的问题同一套 UI 控件代码怎么在 VCL、FMX、LCL 三种框架上跑出接近一致的行为。TMS FNC Core 就是这套跨框架控件体系的公共底座FNC 是 Framework Neutral Components 的缩写Grid、Chart、TreeView 这些上层控件全都依赖它。你拿到的 Full Source 版本意味着可以跟源码调试、改绘制逻辑、绕开授权限制做二次封装。适合谁适合那些维护着 XE7 老项目、又想逐步迁到 13 Florence同时不愿意把 UI 层推倒重写的人。它不解决业务逻辑只解决“控件在哪个框架下都能用”这件事。2. 拆包与安装把 Full Source 变成 IDE 里能拖的控件2.1 解压后的目录结构与该先看哪个文件拿到 rar 之后我一般先解到一个短路径比如D:\Components\FNC\因为 Delphi 的编译期包对路径长度和空格都比较敏感路径里带中文或空格是经典翻车点。解压后典型结构是这样目录/文件作用是否必须Source\所有 FNC Core 的.pas源码必须Packages\各版本.dpk/.dproj包工程必须Demos\示例工程验证安装是否成功建议保留Lib\预编译 DCUFull Source 下可忽略可选Readme/License版本与授权说明看一眼关键动作是先确认Packages下有没有对应你 IDE 版本的包目录。XE7 到 13 Florence 跨度很大包工程通常按版本分文件夹比如Packages\Delphi 13 Florence\。如果只有老版本目录不要硬拿 XE7 的 dpk 去 13 里编译字符集和 RTL 单元引用会直接报一堆找不到的标识符。2.2 编译期包与运行期包的安装顺序FNC Core 是典型的“先编译期、后运行期”结构。顺序错了IDE 里能装上去但一拖控件就报类未注册。标准流程# 1. 先打开运行期包Runtime编译并 Install # 文件名通常形如 FNC.Core.RT.dpk # 2. 再打开设计期包Design编译并 Install # 文件名通常形如 FNC.Core.DT.dpk # 3. 两个包都 Install 成功后重启 IDE逻辑说明运行期包提供实际运行需要的单元设计期包只负责把控件注册到工具箱并挂上属性编辑器。先装设计期包的话IDE 在注册控件时会去加载运行期单元找不到就报Class Txxx not found。参数上唯一要注意的是 Output 路径建议把 DCU 输出统一指到一个独立目录别让它散落在源码树里否则以后升级版本会残留旧 DCU 导致玄学编译错误。2.3 在 XE7 与 13 Florence 上分别验证装完之后别急着写业务先做最小验证。新建一个 VCL Application从工具箱拖一个 FNC 的基础控件比如TTMSFNCBitmapContainer之类能拖出来、能编译、能运行说明底座通了。再新建一个 FMX Application 重复一遍。如果 VCL 能跑 FMX 报错八成是 FMX 相关的条件编译单元没被正确引用回去检查包的Requires里有没有把 FMX 的 rtl/fmx 单元列全。XE7 和 13 Florence 的差异主要体现在 Unicode 处理和泛型语法上Full Source 的好处就是报错能直接跳进源码看是哪一行比黑盒 DCU 强太多。3. 跨框架适配的核心机制FNC 怎么做到一套代码三处跑3.1 框架中立层与条件编译的分工FNC Core 的思路不是“写一套万能代码”而是“抽象一层 条件编译兜底”。它把绘制、消息、字体、鼠标事件这些框架相关的东西抽成接口VCL 下走 Canvas/Windows 消息FMX 下走 TCanvas/FMX 消息LCL 下再走一套。你在业务代码里调用的永远是 FNC 暴露的那层 API底层切换由编译期决定。这就是为什么同一个控件在三个框架下外观接近但细节有差异——差异被隔离在底层实现里了。理解这一点很重要因为它决定了你排错的方向如果控件在 VCL 下正常、FMX 下错位问题几乎一定在框架适配层而不是你的业务代码。Full Source 让你能直接进Source目录搜条件编译指令定位到具体是哪个{$IFDEF FMX}分支出了问题。3.2 用条件编译指令隔离平台差异实际改源码时最常见的操作是加平台分支。比如你要在某个绘制方法里针对 FMX 做特殊处理procedure TTMSFNCCustomControl.DoPaint; begin inherited; {$IFDEF VCL} // VCL 下直接用 Canvas.Handle 做 GDI 绘制 PaintVCL(Canvas); {$ENDIF} {$IFDEF FMX} // FMX 下必须走 TCanvas 的 DrawRect/FillRect不能碰 Handle PaintFMX(Canvas); {$ENDIF} {$IFDEF LCL} PaintLCL(Canvas); {$ENDIF} end;逻辑说明{$IFDEF}是编译期指令不是运行期判断所以不会带来运行时开销但也意味着你不能在运行期动态切换框架——框架在编译那一刻就定死了。参数上要注意VCL 和 FMX 的 Canvas 类型不同方法签名也不一样改源码时别想着写一个通用签名糊过去老老实实分三个方法。我一般会在改之前先CtrlF搜一遍现有代码里同类控件是怎么处理的照着它的模式来比自创一套稳。3.3 事件模型与消息循环的差异处理跨框架最容易踩的坑是事件模型。VCL 的鼠标事件带Shift: TShiftStateFMX 的OnMouseDown签名里坐标是Single而不是IntegerLCL 又接近 VCL 但消息常量不同。FNC Core 在中间做了一层转换把三套事件归一化成自己的事件类型。你在用 FNC 控件时绑定的OnMouseDown其实是 FNC 自己的事件不是框架原生的。这意味着两件事第一你拿不到框架原生的全部信息比如某些底层消息参数会被丢掉第二如果你需要原生行为得通过 FNC 暴露的NativeXXX属性或事件去拿。常见做法是先用 FNC 事件做业务真需要底层时再挂框架原生事件做补充。别指望 FNC 事件能覆盖所有原生场景它的目标是“够用且一致”不是“完全等价”。4. 避坑与排查Full Source 安装后最常见的 5 个翻车现场4.1 装完控件拖不出来报 Class not found现象包 Install 显示成功工具箱里也有图标但一往 Form 上拖就弹Class TTMSFNCxxx not found。 原因设计期包注册了控件但运行期包的 DCU 没被 IDE 找到或者运行期包根本没编译成功只是被跳过了。 解决回到Packages目录先单独打开运行期包Build 一次看有没有报错确认 Output 目录里有对应 DCU再重新 Install 设计期包。路径里带空格或中文的换短路径重来。4.2 XE7 工程升到 13 Florence 后编译报字符集错误现象老工程在 XE7 下好好的换到 13 Florence 编译一堆E2003 Undeclared identifier: UTF8Encode之类的错。 原因13 Florence 的 RTL 里部分字符串处理单元做了调整老代码里直接调用的某些函数签名变了或被移走了。 解决别去改 FNC 源码先在你的工程里加System.SysUtils、System.Character等显式引用把隐式依赖补全。Full Source 的价值在这里体现——报错能跳进 FNC 源码看它引用了哪个单元照着补。4.3 FMX 下控件能显示但点击无响应现象VCL 下一切正常FMX 下控件画出来了但鼠标点上去没反应。 原因FMX 的命中测试HitTest机制和 VCL 不同FNC 控件在 FMX 下需要正确设置HitTest和AutoCapture否则事件被上层容器吃掉。 解决检查控件的HitTest属性是否为 True父容器的HitTest是否把它挡住了。必要时在 FNC 源码里看它的MouseDown是怎么做命中判断的对照 FMX 的坐标体系调。4.4 同时装了旧版 FNC新版装完行为诡异现象升级到 v4.2.2.4 后某些控件行为跟文档对不上像是旧版本在生效。 原因旧版 DCU 残留在 IDE 的搜索路径里编译时优先命中了旧 DCU。 解决把 IDE 的 Library Path 里所有指向旧 FNC 目录的条目删掉只留新版路径。再狠一点把旧目录整个改名逼 IDE 找不到。这个坑血泪经验最多因为报错往往不直接指向版本冲突。4.5 编译期包能装运行期包 Install 按钮是灰的现象打开运行期包Install 菜单是灰的点不了。 原因运行期包本来就不该 Install它只需要 Compile。只有设计期包才需要 Install。 解决这是正常现象不是 bug。运行期包 Build 成功即可Install 交给设计期包。很多人第一次用 FNC 会在这里卡半天以为包坏了。5. 从 Full Source 到二次封装把 FNC Core 用出源码级价值拿到 Full Source 最大的好处是你能在它上面做二次封装而不受黑盒限制。我一般的做法是不直接改 FNC 源码而是新建一个自己的单元继承 FNC 的基类把项目里反复用到的样式、默认属性、事件绑定逻辑收进去。这样升级 FNC 版本时只要基类接口没大改我的封装层几乎不用动。具体技巧是抓住 FNC 的Custom基类。FNC 的控件大多有一个TTMSFNCCustomXXX基类它不含具体外观只含行为和属性框架。继承它你就能做出符合自己项目规范、又保留跨框架能力的控件。验证方法很简单写一个继承自 FNC 基类的最小控件分别在 VCL 和 FMX 下拖出来看行为是否一致。一致说明你的封装没破坏框架中立性不一致说明你在封装层里混进了框架相关代码。另一个值得投入的点是调试符号。Full Source 编译出来的 DCU 默认带调试信息配合 IDE 的“Use debug DCUs”能在 FNC 内部下断点。排查那些“控件行为诡异但报错不明确”的问题时能直接跟到 FNC 的绘制或消息处理逻辑里比猜快十倍。我现在的习惯是任何 FNC 相关的疑难杂症先开调试 DCU 跟一遍调用栈再决定是改源码还是改用法。这个习惯帮我省下的时间远比折腾安装那点成本多。希望帮到你。本文还有配套的精品资源点击获取