
简介本资源为Delphi跨平台UI开发核心组件库TMS FMX UI Pack v3.7.7.5完整源码包面向使用Delphi 11进行FireMonkeyFMX开发的中高级桌面与Android应用开发者解决原生FMX控件数量有限、定制能力弱、跨平台适配成本高等实际问题。压缩包为RAR格式大小56.74MB含全部可编译源代码及配套资源支持直接集成至Delphi IDE并深度二次开发其中核心为.pas单元文件实现控件逻辑、.dfm/.fmx窗体模板提供可视化示例结构、.png等资源文件用于主题与图标整体构成高度模块化的UI解决方案。目前已有272人学习下载适合需快速构建专业级多端界面、优化Android端渲染性能、或通过源码级调试解决布局/事件兼容性问题的实战型开发者。1. Delphi TMS_FMX_UI_Pack_v3.7.7.5 全源码包为什么一个 FMX 第三方 UI 组件集值得你花两小时搭好本地编译环境这不是又一个“下载即用”的控件压缩包。Delphi TMS_FMX_UI_Pack_v3.7.7.5 full source 是一套带完整 .pas 源码、可调试、可深度定制、与 FireMonkey 渲染管线深度耦合的 UI 组件集合——它不只提供按钮、表格、导航栏更提供TTMSFMXGrid支持虚拟滚动与 GPU 加速渲染的高性能网格、TTMSFMXWebGMap原生封装 Google Maps SDK 的跨平台地图控件、TTMSFMXCloudUpload直连 AWS S3 / Azure Blob 的断点续传上传器等真正解决移动/桌面混合部署痛点的组件。我曾在一个医疗设备数据看板项目中用它把原本卡顿的 5000 行实时波形表格刷新帧率从 8fps 提升到 52fps也曾在某高校实验室的跨平台实验记录 App 中靠修改TTMSFMXNavigationBar的DrawBackground方法三行代码实现深色模式下状态栏文字自动反色。它适合两类人一是正在用 Delphi 开发 FMX 跨平台应用、但被原生控件性能/样式/扩展性卡住的中高级开发者二是需要在客户现场做白标定制、必须能改底层绘制逻辑的交付工程师。别急着双击安装 —— 这个版本的「full source」意味着你必须亲手配置 IDE、处理单元依赖、绕过几个隐藏的编译陷阱否则连最基础的TMSFMXButton都无法放入窗体。下面我们从零开始把这套组件真正变成你 IDE 里可调试、可打断点、可 Patch 的“活”代码。2. 环境准备与源码集成在 Delphi 11 Alexandria 中注册 TMS_FMX_UI_Pack_v3.7.7.5 全源码包2.1 确认 IDE 版本兼容性与前置依赖TMS_FMX_UI_Pack_v3.7.7.5 官方声明支持 Delphi 10.4 Sydney 至 11.3 Alexandria。但实测发现若你使用的是 Delphi 11.0非 Update 1 或更高且未安装 Windows 10 SDK 10.0.19041.0则TTMSFMXWebGMap在 Windows 平台编译时会因WebView2Loader.dll加载失败而静默崩溃。这不是组件 Bug而是 FireMonkey 对 WebView2 运行时绑定的版本敏感性问题。因此请先执行以下检查# 在命令行中运行确认已安装的 Windows SDK 版本 dir C:\Program Files (x86)\Windows Kits\10\Lib /AD /B提示输出中必须包含10.0.19041.0或更高如10.0.22621.0。若无请前往 Microsoft 官网下载并安装 Windows 10 SDK 19041注意不是 Windows 11 SDK。Delphi 11.0 默认不附带此 SDK必须手动安装。同时确保已启用 Delphi 的「Design-time Packages」功能Tools → Options → Environment Options → Delphi Options → Library →勾选 Enable design-time packages。这是让组件出现在 Tool Palette 的前提缺一不可。2.2 解压源码结构与关键目录识别解压TMS_FMX_UI_Pack_v3.7.7.5_full_source.zip后你会看到如下核心目录结构目录路径用途说明是否必须纳入搜索路径\Source\FMX\所有 FMX 组件的.pas源文件如TMSFMXGrid.pas,TMSFMXCloudUpload.pas✅ 必须\Source\Common\跨平台通用工具单元TMSFMXUtils.pas,TMSFMXJSON.pas✅ 必须\Source\Win\Windows 平台专用封装TMSFMXWebView2.pas,TMSFMXCloudUploadWin.pas✅ Windows 项目必加\Source\Mac\macOS 平台专用封装TMSFMXWebViewMac.pas⚠️ macOS 项目才需添加\Design\设计时包源码.dpk文件如dclTMSFMXUI.dpk✅ 必须编译安装注意v3.7.7.5版本中TMSFMXWebGMap的 Google Maps API Key 注册逻辑已从设计时移至运行时ApiKey属性这意味着你不能再像旧版那样在 Object Inspector 里填 Key —— 必须在窗体OnCreate中赋值否则地图将显示灰色方块。这是该版本的重要行为变更后续章节会详解。2.3 编译并安装设计时包dclTMSFMXUI.dpk这是让组件图标出现在 Tool Palette 的唯一路径。请严格按顺序操作打开\Design\dclTMSFMXUI.dpk注意不是TMSFMXUI.dpk后者是运行时包右键点击包名 →Options→ 切换到Description页 → 将Requires中的rtl、fmx、vcl如有保留删除所有以TMS*开头的依赖项如TMSFMXCore、TMSFMXUtils——这些会在编译时自动解析手动添加会导致循环引用切换到Directories/Conditionals页 → 在Search Path中添加以下三行每行一个路径用分号分隔$(TMSFMX_SOURCE)\Source\FMX;$(TMSFMX_SOURCE)\Source\Common;$(TMSFMX_SOURCE)\Source\Win其中$(TMSFMX_SOURCE)是你自定义的环境变量。强烈建议在Tools → Options → Environment Options → Environment Variables中新增TMSFMX_SOURCE D:\Libs\TMS_FMX_UI_Pack_v3.7.7.5_full_source替换成你的实际解压路径这样未来升级版本只需改一个变量无需重配所有路径。点击Compile→ 若提示Unit not found: System.UITypes说明你当前 IDE 版本低于 10.4 —— 此包最低要求 Delphi 10.4编译成功后右键包名 →Install。IDE 将弹出确认框点击Yes。安装完成后重启 Delphi。打开任意 FMX 工程查看 Tool Palette —— 你应该能看到名为TMS FMX UI的新选项卡内含TMSFMXButton、TMSFMXGrid、TMSFMXNavigationBar等控件图标。3. 运行时包集成与跨平台条件编译配置3.1 编译运行时包TMSFMXUI.dpk并链接到工程设计时包只负责 IDE 内拖放真正运行时逻辑由TMSFMXUI.dpk提供。你不能跳过这一步直接在工程中uses源码单元否则将触发EAccessViolation尤其在 iOS/Android 上因为部分组件依赖运行时包中初始化的全局管理器如TTMSFMXCloudUploadManager。操作步骤打开\Design\TMSFMXUI.dpkOptions → Description → Requires中仅保留rtl、fmx、System、System.Classes——务必删除所有dcl*开头的包名如dclTMSFMXUI设计时包不可被运行时包依赖Options → Directories/Conditionals → Search Path中填入与设计时包完全相同的三行路径Compile→ 成功后不要点击 Install运行时包不能安装只能链接在你的目标 FMX 工程中打开Project → Options → Packages → Runtime Packages→ 勾选Build with runtime packages→ 在下方Runtime packages输入框中手动追加TMSFMXUI注意不带.bpl后缀也不带路径同时在Project → Options → Delphi Compiler → Search Path中添加与前述一致的三个源码路径。关键逻辑说明Runtime packages设置让工程在运行时动态加载TMSFMXUI.bpl而Search Path则确保编译器能找到.pas源码用于调试和符号生成。二者缺一不可。若只设前者你无法在TMSFMXGrid.pas中打断点若只设后者iOS 构建会因找不到libTMSFMXUI.a静态库而失败。3.2 针对 iOS 和 Android 的条件编译处理v3.7.7.5引入了对 iOS 17 和 Android 13 的适配层但默认未启用。若你的目标平台是移动设备必须在工程的.dpr文件顶部添加条件定义program MyFMXApp; uses System.StartUpCopy, FMX.Forms, // ... 其他 uses {$IFDEF IOS} {$DEFINE TMSFMX_IOS17_SUPPORT} {$ENDIF} {$IFDEF ANDROID} {$DEFINE TMSFMX_ANDROID13_SUPPORT} {$ENDIF} {$R *.res} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end.参数说明TMSFMX_IOS17_SUPPORT启用TTMSFMXNavigationBar对 iOS 17 新增的statusBarStyleAPI 调用TMSFMX_ANDROID13_SUPPORT启用TTMSFMXCloudUpload对 Android 13 存储沙盒权限的自动检测。不加定义则组件仍可运行但可能在新系统上出现状态栏文字不可读、或上传时因权限拒绝而静默失败。3.3 Windows 平台 WebView2 运行时自动部署避坑关键TTMSFMXWebGMap和TTMSFMXWebView2依赖 Microsoft Edge WebView2 运行时。v3.7.7.5不再自带WebView2Loader.dll而是通过TMSFMXWebView2.pas中的LoadWebView2函数动态查找。常见失败场景是开发机有 WebView2但客户机没有导致地图白屏。解决方案在工程中嵌入最小化 WebView2 引导逻辑。在主窗体OnCreate中加入uses TMSFMXWebView2, System.SysUtils; procedure TForm1.FormCreate(Sender: TObject); begin if not TMSFMXWebView2.LoadWebView2 then begin ShowMessage(WebView2 运行时未找到。请访问 https://go.microsoft.com/fwlink/p/?LinkId2124703 下载并安装); Application.Terminate; end; end;血泪经验不要试图在dpr中调用LoadWebView2—— 此时 FMX 应用上下文尚未初始化函数会返回False却不报错成为黑匣子。必须在首个窗体OnCreate中调用且必须在Application.Initialize之后、Application.Run之前。4. 常见编译与运行时问题排查五个真实踩坑记录与修复方案4.1 现象编译dclTMSFMXUI.dpk时提示F2051 Unit FMX.TabControl not found原因Delphi 11 默认安装的 FMX 框架路径未被正确索引或你安装了多个 Delphi 版本导致 IDE 混淆了FMX.TabControl.pas的位置。v3.7.7.5源码中大量使用FMX.TabControl.TTabControl的扩展方法若编译器找不到基类单元整个包无法解析。解决打开Tools → Options → Language → Delphi Options → Library → Library Path确保第一条路径为$(BDS)\source\fmx对应 Delphi 11 的 FMX 源码根目录若该路径不存在请手动创建指向C:\Program Files (x86)\Embarcadero\Studio\22.0\source\fmx22.0 是 Delphi 11 的内部版本号重启 IDE 后重试编译。4.2 现象Android 工程部署后TTMSFMXGrid显示空白Logcat 报java.lang.UnsatisfiedLinkError: dlopen failed: library libTMSFMXUI.so not found原因TMSFMXUI.dpk编译时未生成 Android 平台对应的.so动态库或工程未正确链接。v3.7.7.5的 Android 构建依赖Android NDK r21e而 Delphi 11.3 默认配置为r23b版本不匹配导致链接器跳过.so生成。解决下载Android NDK r21e官网归档页面可得解压至C:\Android\ndk\r21eTools → Options → Deployment → SDK Manager → Android SDK→ 点击Edit→ 将NDK Path改为C:\Android\ndk\r21e重新编译TMSFMXUI.dpkTarget Platform 切换为Android 64-bit在工程Deployment窗口中确认libTMSFMXUI.so已被添加到Remote Path: libraries\arme64-v8a\或arm64-v8a。4.3 现象iOS 真机调试时TTMSFMXWebGMap显示灰色方块Xcode Console 输出Invalid API key原因v3.7.7.5将 Google Maps API Key 的校验逻辑从设计时前移到了TTMSFMXWebGMap.Create构造函数中且 Key 必须在inherited Create之后、Self.Parent : ...之前设置。若你在窗体设计器中设置了ApiKey属性该值不会被序列化进.fmx文件 —— 因为TTMSFMXWebGMap未在DefineProperties中注册该属性的流式保存。解决在窗体OnCreate中严格按顺序编写procedure TForm1.FormCreate(Sender: TObject); begin inherited; // 必须在 inherited 之后、Parent 赋值之前 TMSFMXWebGMap1.ApiKey : YOUR_GOOGLE_MAPS_API_KEY; TMSFMXWebGMap1.Parent : Self; end;翻车现场曾有 A 同学把ApiKey设置放在TMSFMXWebGMap1.Visible : True之后结果因 Parent 未赋值导致Create未完成Key 被忽略 —— 调试器里ApiKey字段显示为空但断点根本进不去Create成了后悔药都难找的玄学问题。4.4 现象Windows 平台下TTMSFMXCloudUpload上传大文件500MB时进度条卡在 99%最终超时原因v3.7.7.5的TTMSFMXCloudUpload默认使用TNetHTTPClient其Timeout属性默认为6000060 秒且未暴露给用户。大文件上传受网络抖动影响单次请求极易超时而组件内部未实现分片重传。解决在上传前通过 RTTI 强制修改底层 HTTP 客户端超时uses System.Rtti, System.TypInfo; procedure TForm1.UploadBigFile; var LContext: TRttiContext; LType: TRttiType; LField: TRttiField; LHTTP: TObject; begin LType : LContext.GetType(TTMSFMXCloudUpload1.ClassType); LField : LType.GetField(FHTTPClient); // 私有字段名v3.7.7.5 中固定为 FHTTPClient LHTTP : LField.GetValue(TTMSFMXCloudUpload1).AsObject; // 修改 TNetHTTPClient.Timeout 属性单位毫秒 LType : LContext.GetType(LHTTP.ClassType); LField : LType.GetProperty(Timeout); LField.SetValue(LHTTP, 300000); // 设为 5 分钟 TTMSFMXCloudUpload1.UploadFile(...); end;提示此方案依赖私有字段名FHTTPClient属v3.7.7.5特定版本。升级到 v3.8 后字段名可能变更需同步更新 RTTI 路径。4.5 现象macOS 工程编译通过但运行时报EXC_BAD_ACCESS (code1, address0x0)堆栈指向TMSFMXWebViewMac.pas第 237 行原因v3.7.7.5的 macOS WebView 封装未正确处理 ARCAutomatic Reference Counting内存模型。当TTMSFMXWebViewMac实例被释放时其持有的WKWebViewdelegate 未置空导致 delegate 回调时访问已释放对象。解决在TMSFMXWebViewMac.pas中定位到Destroy方法约第 230 行附近在inherited Destroy之前插入// 在 TMSFMXWebViewMac.Destroy 中插入以下两行 if Assigned(FWKWebView) then FWKWebView.navigationDelegate : nil; inherited Destroy;注意此补丁需在每次升级 TMS 包后重新应用。建议将修改后的TMSFMXWebViewMac.pas单独存档并在团队 Wiki 中注明补丁版本与生效范围。5. 深度定制实战修改TTMSFMXGrid单元格渲染逻辑实现带图标与状态徽章的复合单元格TTMSFMXGrid是v3.7.7.5中性能最强、扩展性最高的表格组件但它默认的OnDrawCell事件只提供画布句柄和矩形区域不暴露原始数据对象。若你想在订单列表中为“已发货”状态的行右侧绘制一个绿色对勾图标 “已发货”徽章就必须深入其渲染管线。5.1 理解TTMSFMXGrid的三层渲染架构TTMSFMXGrid渲染并非简单调用Canvas.FillRect而是分三阶段数据层TGridDataItem对象存储原始数据如DataItem.Values[0]是订单号样式层TGridCellStyle控制字体、颜色、对齐OnGetCellStyles可动态返回绘制层OnDrawCell事件中ACanvas是TCanvas抽象类实例但实际类型取决于平台Windows 是TCanvasGDImacOS 是TCanvasCocoa。关键洞察OnDrawCell的ADataItem: TGridDataItem参数正是你获取业务数据的入口。v3.7.7.5已将TGridDataItem的Tag属性开放为Integer可用于临时挂载状态标识。5.2 实现带图标与徽章的订单状态列假设你的数据源是TListTOrder其中TOrder.Status: TOrderStatus (osPending, osShipped, osCancelled)。目标是在第 3 列状态列绘制osShipped→ 右侧绿色对勾图标 “已发货”徽章背景绿文字白osCancelled→ 右侧红色叉号图标 “已取消”徽章背景红文字白osPending→ 仅显示文字“待处理”。步骤如下预处理数据挂载状态 Tag在TTMSFMXGrid.LoadFromList后遍历Grid.DataItemsprocedure TForm1.LoadOrders; var I: Integer; LOrder: TOrder; begin Grid.LoadFromList(FOrders); for I : 0 to Grid.DataItems.Count - 1 do begin LOrder : FOrders[I]; Grid.DataItems[I].Tag : Ord(LOrder.Status); // 将枚举转为整数存入 Tag end; end;实现OnDrawCell分离文字与图标绘制uses FMX.Graphics, FMX.Types, System.UITypes, System.Math; procedure TForm1.GridDrawCell(Sender: TObject; ACanvas: TCanvas; AColumn, ARow: Integer; ARect: TRectF; AState: TGridDrawState; ADataItem: TGridDataItem; ASelected: Boolean); var LText: string; LStatus: TOrderStatus; LIconRect, LBadgeRect: TRectF; LIconSize: Single; begin // 仅处理第 3 列索引为 2 if AColumn 2 then begin inherited; Exit; end; LStatus : TOrderStatus(ADataItem.Tag); case LStatus of osShipped: begin LText : 已发货; Grid.Canvas.Fill.Color : $FF4CAF50; // 绿色背景 end; osCancelled: begin LText : 已取消; Grid.Canvas.Fill.Color : $FFF44336; // 红色背景 end; else begin LText : 待处理; Grid.Canvas.Fill.Color : $FFFFFFFF; // 白色背景 end; end; // 绘制徽章背景 LBadgeRect : ARect; LBadgeRect.Left : LBadgeRect.Right - 80; LBadgeRect.Top : LBadgeRect.Top 4; LBadgeRect.Bottom : LBadgeRect.Top 22; Grid.Canvas.FillRect(LBadgeRect, 0, 0, AllCorners, 1); // 绘制徽章文字 Grid.Canvas.Font.Size : 12; Grid.Canvas.Font.Color : $FFFFFFFF; // 白色文字 Grid.Canvas.FillText(LBadgeRect, LText, False, 1.0, [], TTextAlign.Center, TTextAlign.Center); // 绘制图标对勾/叉号 LIconSize : 16; LIconRect : ARect; LIconRect.Left : LIconRect.Right - LIconSize - 10; LIconRect.Top : LIconRect.Top (LIconRect.Height - LIconSize) / 2; LIconRect.Right : LIconRect.Left LIconSize; LIconRect.Bottom : LIconRect.Top LIconSize; case LStatus of osShipped: DrawCheckMark(Grid.Canvas, LIconRect, $FF4CAF50); osCancelled: DrawCrossMark(Grid.Canvas, LIconRect, $FFF44336); end; end;实现图标绘制辅助函数放入单元 implementation 区procedure DrawCheckMark(ACanvas: TCanvas; ARect: TRectF; AColor: TAlphaColor); var LPath: TPathData; begin LPath : TPathData.Create; try LPath.MoveTo(TPointF.Create(ARect.Left 4, ARect.Top ARect.Height / 2)); LPath.LineTo(TPointF.Create(ARect.Left ARect.Width / 2 - 2, ARect.Top ARect.Height - 4)); LPath.LineTo(TPointF.Create(ARect.Left ARect.Width - 4, ARect.Top 4)); ACanvas.Stroke.Color : AColor; ACanvas.Stroke.Thickness : 2; ACanvas.DrawPath(LPath, 1.0); finally LPath.Free; end; end; procedure DrawCrossMark(ACanvas: TCanvas; ARect: TRectF; AColor: TAlphaColor); var LPath: TPathData; begin LPath : TPathData.Create; try LPath.MoveTo(TPointF.Create(ARect.Left 4, ARect.Top 4)); LPath.LineTo(TPointF.Create(ARect.Left ARect.Width - 4, ARect.Top ARect.Height - 4)); LPath.MoveTo(TPointF.Create(ARect.Left ARect.Width - 4, ARect.Top 4)); LPath.LineTo(TPointF.Create(ARect.Left 4, ARect.Top ARect.Height - 4)); ACanvas.Stroke.Color : AColor; ACanvas.Stroke.Thickness : 2; ACanvas.DrawPath(LPath, 1.0); finally LPath.Free; end; end;关键参数说明ARect是单元格原始区域我们通过ARect.Right - 80计算徽章左边界确保徽章始终贴右DrawPath使用矢量路径而非位图保证 Retina 屏幕下清晰无锯齿Stroke.Thickness : 2是视觉平衡经验值太细则图标易被忽略太粗则破坏紧凑感。5.3 性能优化启用虚拟滚动与 GPU 加速上述自定义绘制若应用于万级数据表格仍可能卡顿。TTMSFMXGrid内置虚拟滚动Virtual Mode但需显式启用Grid.VirtualMode : True; Grid.OnGetCellText : GridGetCellText; // 必须实现否则虚拟模式不生效 Grid.OnGetCellStyles : GridGetCellStyles;并在GridGetCellText中根据ARow从原始数据源FOrders中取值而非依赖Grid.DataItems[ARow]虚拟模式下DataItems仅缓存可视行。最后强制启用 GPU 渲染Windows/macOS 有效Grid.UseGPU : True; // 此属性在 v3.7.7.5 中默认 False我一般会在项目启动时统一开启TMSFMXGrid.GlobalUseGPU : True;。这样所有TTMSFMXGrid实例默认走 GPU 路径避免逐个设置遗漏。实测开启后5000 行表格滚动帧率从 32fps 提升至 58fps且 CPU 占用下降 40%。希望帮到你。本文还有配套的精品资源点击获取