多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

Delphi 13.1安装TMS FNC UI Pack:从自绘控件原理到排错全攻略

Delphi 13.1安装TMS FNC UI Pack:从自绘控件原理到排错全攻略 简介TMS FNC UI Pack v7.1.1.0完整源码包专为Delphi与C Builder XE7至XE13Florence版本设计是一套覆盖Windows、macOS、Linux、iOS及Android的通用界面控件集适用于需要统一多平台视觉风格、快速交付触摸友好型应用的开发团队。包内共2000个文件其中591个pas文件提供了完整的Object Pascal源代码配合dfm/fmx窗体定义、dproj/dpr工程文件、ico/png/jpg图标素材、html帮助文档及少量示例CSV数据构成从界面设计到编译调试的完整链路整体体积约31.09MB目录结构清晰。目前已有60人学习/下载该套件。除开箱即用的现代组件外资源亮点在于全源码开放开发者可深入修改渲染逻辑、动画曲线与样式主题甚至将其中部分UI模块直接迁移到自己的工程同时控件包支持从XE7到XE13的长版本跨度便于在新旧项目中保持一致体验对追求界面定制与跨平台复用价值的Delphi开发者具有较高的实用参考意义。1. Delphi 13.1装TMS FNC UI Pack v7.1.1.0这套Full Source控件包到底能干嘛如果你也奔着“Delphi 13.1下载好了UI控件却装不上”这个诉求来那TMS FNC UI Pack v7.1.1.0 for Delphi CB XE7-13 Florence Full Source 这个包几乎是绕不开的。它要解决的不是“多几个按钮和输入框”而是同一套自绘UI控件在VCL、FMX、甚至Lazarus的LCL里保持一致的外观和交互标题里的Full Source则意味着你可以直接阅读、断点调试和二次扩展控件的内部实现。包不大但安装顺序、编译平台和Library Path三个环节任何一个没对上后续就是接连不断的“dcu not found”和组件面板空白。这篇笔记按“框架原理→安装落地→跑通Demo→高频避坑→源码定制”来写新手能照做熟手也能对一下边界。2. 框架中立到底中立在哪装TMS FNC UI Pack之前要搞懂的三件事2.1 FNC控件的自绘机制不是包原生句柄而是画出来的VCL里的标准控件比如TButton本质上是在Windows上包了一个真实的按钮句柄HWND消息、焦点、绘制全交给操作系统。TMS FNC的路线完全不同FNC全称是Framework Neutral Components它把控件绘制统一收到自己的Canvas抽象层里按钮、网格、树、侧栏这些控件在运行时是“画”出来的而不是“包”出来的。同一个TTMSFNCGridWindows的VCL工程里能用Android的FMX工程里也能用外观、事件、属性几乎一致。这个设计的直接代价是所有绘制细节都必须由控件自己处理所以它对IDE版本、Canvas实现和DPI缩放特别敏感。这也就解释了为什么网上搜TMS FNC安装问题翻车现场往往集中在“重绘黑块”“字体模糊”“安装后控件面板空白”这几类——它们不是控件逻辑坏了而是自绘控件和宿主Form的绘制上下文没有对齐。理解这一点再动手装包排错思路会完全不同先怀疑Canvas上下文而不是先怀疑代码。2.2 UI Pack的职责边界网格侧栏工具栏有Excel和PDF不在TMS FNC UI Pack覆盖的是通用业务后台界面那一类控件数据网格、树形列表、侧边栏、工具栏、按钮组、日期选择、搜索框、磁贴面板等等。如果你的界面需求是“一屏表格加左侧导航再加顶部操作区”这个包很合适。但它的边界也很清晰——UI Pack管界面不直接管文书和表格文件生成。很多人搜索“delphi excel 操作”时会顺手把这个包下下来以为能直接导出xlsx或生成PDF实际那是TMS FlexCel、TMS FNC PDF这些独立组件的职责。下面是装包前值得做的一张对比表能帮你判断到底该不该选它对比维度原生VCL控件TMS FNC UI Pack底层机制操作系统句柄自绘Canvas渲染框架覆盖只支持当前IDE的VCLVCL、FMX、LCL多框架IDE版本跨度跟随当前Delphi版本从XE7到13.x均可安装源码可读性多数逻辑在IDE/RTL里Full Source包提供完整.pas适合场景快速开发经典Windows桌面应用需要跨平台一致交互或深度定制主要风险平台迁移要重写界面高DPI、绘制性能需要额外关注我一般建议是项目只要锁死在Windows VCL上UI Pack不是刚需如果团队同时在维护Windows和移动端界面或者你希望界面控件能做到深度定制那这套包的收益就很明显。2.3 标题里的“XE7-13”和“Florence”怎么对应“for Delphi CB XE7-13”指的是这个控件包的编译单元按老到新的IDE版本逐一适配过从XE7到RAD Studio 13.1都能装标题里的CB是CBuilder说明它也生成了CBuilder需要的.bpi、.lib等链接产物。Florence这个标识在包里通常以目录名或工程名前缀出现对应的是Delphi 13.1这条线。不少新手看到Florence就懵其实第三方控件包经常用IDE代号分目录比如Packages\Florence就是给13.1用的。实际安装时如果解压后没看到13.1或Florence目录我的习惯是先找目录名数字最大的那一份再找带Latest、Current字样的目录这类控件包向下兼容做得好通常选最新那版编译能覆盖13.1。需要提醒的是标题里的“Full Source”只针对UI Pack本身的.pas源码不代表这个rar里包含了TMS所有产品线。后面装包时如果发现没有FlexCel、没有Aurelius别意外那本来就是另一套包。3. 安装v7.1.1.0到Delphi 13.1解压、编译、Install三步走3.1 装前准备路径、文件锁定、环境变量检查安装这类带源码的控件包最忌讳的就是从网盘下载后直接解压到同步盘或加密盘。OneDrive、坚果云这类目录会在编译时锁文件轻则编译失败重则生成半个dcu导致IDE缓存错乱。我通常先解压到D:\Components\TMS_FNC_UI_Pack这种无中文、无空格的纯本地路径然后全选文件右键打开“属性”在“解除锁定”那里打钩确认。这一步不做后面Install时会出现奇奇怪怪的“Access denied”或“File in use”。接下来打开RAD Studio 13.1先用一个批处理确认环境变量没被改动过。常见做法是调用IDE自带的rsvars.bat来加载环境脚本如下echo off call C:\Program Files (x86)\Embarcadero\Studio\13.0\bin\rsvars.bat echo BDS%BDS% echo BDSCOMMONDIR%BDSCOMMONDIR% echo Platform%Platform% if not defined BDS ( echo [ERROR] BDS is empty. Check rsvars path or IDE env vars. exit /b 1 ) echo Check System Library Path if exist %BDS%\lib\win32\System.pas ( echo System.pas found: OK ) else ( echo [WARN] %BDS%\lib\win32\System.pas not found )这个脚本的核心作用是确认BDS环境变量指向Studio安装目录。如果BDS为空说明IDE的环境变量被第三方包或手动配置顶掉了后面Library Path再怎么写都是白搭。路径里的13.0对应你安装的Delphi 13.1如果是RAD Studio 12.x就改成12.0。脚本里对System.pas的检查也很关键这个文件是Delphi RTL的核心单元如果它不在系统Library Path里编译任何控件包都会报“System.pas not found”。3.2 找到正确的dpk并按顺序编译先运行时后设计期解压完成后不要急着双击.dproj先在IDE里用File Open Project打开包里的.dpk文件。dpk是传统的包工程文件dproj是MSBuild工程文件对安装控件包这件事来说dpk在Project Manager里的右键菜单更直观能看到Install选项。安装包的目录一般按IDE版本拆分进到对应13.1的目录后你会看到一堆命名相近的包工程命名规律大致是“组件单元名.dpk”和“组件单元名Design.dpk”。正确的编译顺序是先编译所有不带Design字样的运行时包再逐个Install带Design字样的设计期包。原因很简单运行时包负责实现控件逻辑不向IDE注册组件设计期包负责把控件图标注册到组件面板它依赖运行时包编译生成的dcu。顺序反了Install时大概率报“找不到某某编译单元”。我的操作习惯是先把目录里所有.dpk按文件名排序先CtrlF9编译前半部分再逐个右键Install后半部分。每个包编译时确认右侧Project Manager里当前的平台是Win32不要用Win64或All Platforms第三方控件包的安装流程在Win32下最稳。实际操作中Install动作在Project Manager里选中设计期dpk后右键就能看到如果右键菜单里没有Install说明这个包不是设计期包直接编译完跳过即可。全部装完后重启一次IDE组件面板才会刷新出TMS FNC页。3.3 配置Library Path让IDE每次都能找到FNC源码包编译通过只是第一步真正让控件能在你的业务工程里跑起来靠的是Library Path。打开Tools Options Language Delphi Library先把当前平台切换到Win32再在Library Path里追加解压目录\Source。这里注意不要用“All Platforms”一次性添加绝对路径否则切到Android或Linux平台时这串Windows路径会让IDE报一堆莫名其妙的错误。Library Path的搜索顺序是自上而下所以FNC的Source目录要放在系统路径之前。但千万不能把$(BDS)\lib\win32这类系统默认路径删掉否则编译时IDE找不到MSXML等系统单元就会撞上后面避坑章节要讲的“msxmldom.dcu not found”。稳妥做法是保留系统默认项在最上方新增一行FNC Source路径D:\Components\TMS_FNC_UI_Pack\Source $(BDS)\lib\win32 $(BDS)\lib\$(Platform)保存后最好再执行一遍批处理里的System.pas检查确认系统路径没被覆盖。Library Path配置完之后新建项目或打开Demo时IDE才会在编译阶段自动解析到TMSFNCGrid等单元。3.4 CBuilder的差异提示标题里同时写了Delphi和CB说明这包也确实支持CBuilder。但CBuilder的路径配置入口和Delphi是分开的在Tools Options里找到CBuilder对应的Library Path把同一个解压目录\Source再添加一遍。编译时CBuilder会生成.bpi和.lib如果某个Demo工程在CB里编译报“无法打开xxx.bpi”先检查是不是编译顺序又反了。大多数情况下照着Delphi的安装顺序重来一遍就能解决CB和Delphi在这套控件上共用的源码是同一份不用单独做翻译。4. 跑通第一个FNC Demo并手写Grid初始化直接在13.1里验证控件4.1 先跑官方Demo这是验证环境最快的捷径包安装完成后先不要急着新建工程直接从解压目录里的Demo子目录下手。进入Demo或Demos目录后优先找VCL子目录下的Grid示例如果目录里没单独列出13.1版本选数字最大的那个版本工程即可。打开.dproj后直接按F9运行正常情况下会弹出一个带网格数据的示例窗口能滚动、能点选、能编辑单元格。这一步能跑通说明运行时包和设计期包都装对了Library Path也没问题。如果Demo编译报错我的建议是不要死磕Demo自身先回第3章检查包的编译顺序和路径85%的“Demo编译不过”都是因为设计期包用了Win64平台编译而IDE当前在Win32下加载不了。Demo工程的价值在于它自带正确的单元引用和DFM配置比手动新建工程去猜要快得多这也是我每次拿新控件包的习惯先跑官方示例再写自己的界面。4.2 新建VCL工程并拖入TTMSFNCGrid一份最小可运行代码Demo正常后自己动手建一个最小工程才能真正确认控件在你自己的项目设置下没问题。新建VCL Application组件面板上找到TMS FNC页把FNC Grid拖到Form上。这时双击Form的OnCreate事件写上最简单的初始化代码unit MainFrm; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, TMSFNCGrid; type TForm1 class(TForm) TMSFNCGrid1: TTMSFNCGrid; procedure FormCreate(Sender: TObject); end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var I, J: Integer; begin TMSFNCGrid1.BeginUpdate; try TMSFNCGrid1.Columns.Count : 3; TMSFNCGrid1.Rows.Count : 5; for I : 0 to TMSFNCGrid1.Rows.Count - 1 do for J : 0 to TMSFNCGrid1.Columns.Count - 1 do TMSFNCGrid1.Cells[J, I] : Format((%d, %d), [J, I]); finally TMSFNCGrid1.EndUpdate; end; end; end.这段代码有几个容易踩的细节。第一BeginUpdate和EndUpdate成对出现中间做批量填充时控件不会每行重绘一次否则网格行数一多界面上就能肉眼看到一格一格刷新的卡顿。第二索引顺序是列在前、行在后也就是Cells[列, 行]这和很多表格控件的习惯不同写反了数据会填到转置的位置。第三如果在你当前的v7.1.1.0版本里Cells已经返回对象而不是字符串编译会报错把赋值语句改成TMSFNCGrid1.Cells[J, I].Text : ...即可这是跨小版本常见的API演进差异。4.3 用OutputDebugString确认运行时绑定界面能看到网格数据基本就说明安装成功了。但实战里还有一个更隐蔽的问题控件虽然拖上去了运行时IDE却可能加载了旧版本的dcu导致你改控件属性没反应。为了确认这一点可以在FormCreate里加一行调试输出uses Winapi.Windows; procedure TForm1.FormCreate(Sender: TObject); begin OutputDebugString(PChar( FNC Grid created, class TMSFNCGrid1.ClassName)); end;按F9运行后用DebugView之类的工具抓内核输出能看到这行字符串说明当前进程确实创建了TMSFNCGrid实例。如果这行没输出多半是运行时包根本没被链接进工程那就要回头检查Library Path和包安装状态而不是继续在代码层面找原因。5. TMS FNC UI Pack安装避坑清单5个高频报错与排查顺序5.1 编译报“msxmldom.dcu not found”Library Path被顶掉了现象安装完控件包后打开任何工程编译都报msxmldom.dcu not found甚至新建一个空VCL工程也报这个错。原因FNC的某些单元在解析主题或样式时会依赖MSXML相关单元而这个单元属于系统库位于$(BDS)\lib\win32下。第三方包安装时经常会把Library Path整段替换成自己的路径系统默认路径没了编译器自然找不到MSXMLDOM。另一个常见诱发点是IDE当前平台被切成了Android或Linux在这些平台下找不到Windows的DCU。解决打开Tools Options Language Delphi Library先把平台列表切回Win32然后把$(BDS)\lib\win32加回Library Path顶部区域。如果报错还带别的单元比如System.pas not found同样处理即可。这个报错属于“路径污染”类问题和控件包本身无关别去重装包重装只会浪费时间。5.2 Install时“File in use”杀毒、同步盘与残留进程现象右键Install设计期包时弹出Cannot open file xxx.bpl ... being used by another process多试几次偶尔能成功但很快又随机失败。原因第一怀疑对象是Windows Defender实时扫描它在控件包生成bpl的瞬间锁住了文件第二是解压目录放在了同步盘里同步进程一直读文件第三是IDE之前崩溃过残留的bpl加载进程没有完全退出。解决把整个解压目录加进杀毒排除项同时确认目录不在OneDrive、坚果云这类同步目录下。如果还报占用用系统自带的“资源监视器”或Process Explorer查看哪个进程占用了bpl结束掉再继续。最彻底的办法是删除整个解压目录重新解压一次再按第3章顺序重装这一招能解决60%以上的玄学占用问题。这个操作花不了多长时间比反复试Install要省心。5.3 组件面板没有TMS FNC页设计期包没装上现象包编译了Library Path也配了但新建VCL工程后组件面板里怎么都找不到TMS FNC页。原因最常见的是你只编译了运行时包没有右键Install设计期包。另一个原因是设计期包被编译成了Win64平台而IDE当前在Win32模式下工作它不会加载非当前平台的包。解决打开Component Install Packages先确认列表里有没有TMS FNC相关条目。没有的话回到Project Manager找到带Design字样的dpk确认右侧Platform是Win32右键Install。安装成功后Installed Packages对话框里能看到对应条目然后重启IDE组件面板才会刷新。这里有个血泪经验不要用“Compile All”代替“Install”编译和注册是两码事。5.4 打开旧Demo报“Property does not exist”跨版本DFM兼容边界现象从XE7时代带下来的FNC Demo工程在13.1里打开时IDE弹窗报Error reading TMSFNCGrid... property does not exist或者某个属性名在对象检查器里飘红。原因DFM文件里序列化了旧版本控件的属性而这个属性在新版组件里已经被改名或移除。FNC控件横跨XE7到13.1这类属性不兼容在跨版本Demo里非常常见。解决按报错提示用记事本打开对应DFM找到出错属性行直接删掉保存再重新打开工程。属性条目多的时候删起来很麻烦我的习惯是直接把旧Form上的FNC控件删掉重新从面板拖一个出来然后把需要的属性重新设置一遍。这样做的成本往往比逐条清理属性更低还能顺便梳理一遍界面代码。别指望旧Demo永远能无缝打开第三方控件的跨版本兼容从来不是二进制级别的。5.5 运行时黑块、字体模糊、点击无响应PerMonitorV2与画布冲突现象FNC控件在Form上第一次显示正常窗口缩放或跨DPI显示器拖动后出现黑块、字体模糊甚至单元格点击没反应。原因自绘控件的绘制依赖Canvas和Form的DPI缩放上下文。13.1默认支持PerMonitorV2高DPI但Form没开启对应DPI Awareness时FNC取到的缩放比例和实际窗口尺寸不一致绘制区域就乱了。另一种情况是Form上叠了透明层或开启了特殊边框效果导致TMS自绘画布没法正常接收鼠标点击区域。解决在项目设置里把DPI Awareness设为PerMonitorV2并在Application初始化时统一设置进程DPI。具体可以在.dpr文件里加入SetProcessDPIAware调用或者直接在项目选项的Manifest里打开DPI感知。如果Form上有透明玻璃效果先把它关掉再观察大多数黑块问题在关闭窗口透明效果后立刻消失。这属于自绘控件的固有边界遇到时优先调宿主Form而不是去翻控件属性。6. 把Full Source变成调试抓手在断点里看TMS FNC怎么画格子6.1 源码级调试直接在.pas绘制方法里下断点Full Source版和普通编译版最大的差别是你在调试时可以真正单步进入控件的内部实现。运行时按F9启动Demo在FNC Grid上触发一次重绘IDE会自动跳到TMSFNCGrid.pas源码里如果没跳说明Library Path里的Source路径没生效回到第3.3节检查。我常用做法是先在某个绘制相关的方法名上打断点比如带DrawCell或Paint字样的方法然后让网格滚动一下断点命中后看调用栈和局部变量。这一步能帮你直观理解自绘控件的坐标计算和Canvas状态比查任何文档都快。第一次看FNC绘制源码时重点看三处单元格矩形怎么计算、字体画刷怎么切换、滚动区域怎么与裁剪区相交。看懂这三处以后调样式、修闪烁、做自定义单元格绘制就都有依据了。6.2 验证Full Source是否生效看运行时有没有水印和试用弹窗装完控件后还有一个很容易被忽略的验证点运行时确认这是不是有效的Full Source包。试用版FNC控件启动时通常会在窗口角落绘制TMS字样水印或弹一次About提示Full Source版没有这些标记。如果跑Demo时看到水印或试用提示说明包里某个运行时包没编译干净或者IDE加载了残留的试用版bpl。处理方式是把所有FNC相关包卸载、删除dcu和bpl缓存再重新编译安装。顺带一提最直接的确认方式是在项目管理器里右键你编译过的包看“Options”里的DCU输出路径是否落在你指定的目录而不是IDE的临时目录。这套包我从XE8一路用到13.1养成的习惯是每次拿到新版本先跑Demo、跑通了再改代码改代码前先在绘制方法里下断点看一遍渲染流程。源码不是拿来收藏的而是用来读的读一次内部实现比踩三个月的坑学到的都多。希望帮到你。本文还有配套的精品资源点击获取
返回列表