☰
Delphi 13.1 Florence 下 DevExpress VCL 源码适配实战
2026/9/29 2:40:35 网站建设 项目流程

简介:本资源为Delphi XE7至XE13(Florence)全版本适配的DevExpress VCL Controls v25.1.6完整源码包,面向中高级Delphi桌面应用开发者,解决UI组件陈旧、安装繁琐、定制能力弱等实际开发痛点。包内含2000个文件,涵盖644个C++源文件(核心逻辑与跨平台桥接)、444个头文件(接口定义)、422个PNG图标资源(UI素材)、388个文本说明文档(含安装指南与API摘要),以及26个PAS单元文件(VCL原生封装),整体压缩后达640.38MB,结构清晰、模块完整,支持深度源码级调试与二次开发。已有396人学习下载,可直接集成DxAutoInstall自动化安装工具,免去手动注册组件的重复操作;同时提供CHM帮助文档、多套Demo源码(如RibbonNotepad、CloudStorage、CustomDrawTableView等),覆盖导航、数据网格、图表、仪表盘等高频业务场景,助力快速构建专业级企业应用界面。

1. Delphi 13.1 下跑通 DevExpress VCL Controls v25.1.6:不是装上就能用,而是得让 Florence 编译器认得清源码、绕得开 RTL 冲突、压得住 IDE 插件加载失败的黑匣子

你刚升级到 Delphi 13.1(代号 Florence),兴冲冲下载了 DevExpress VCL Controls v25.1.6 的 Full Source 包,双击 DxAutoInstall.exe —— 结果弹窗报错:“Cannot load package ‘dxCoreXX.dcp’” 或更糟:IDE 启动卡在“Loading design-time packages…”,鼠标转圈三分钟,最后蓝底白字提示 “Access violation at address XXXX in module ‘rtl290.bpl’”。这不是你代码写错了,是 Delphi 13.1 的 RTL(Run-Time Library)和编译器行为变了,而 v25.1.6 虽标称支持 XE7–13,但默认构建配置仍锚定在旧版 RTL 符号表和包依赖链上。本篇不讲“DevExpress 多强大”,只解决一个硬核事实:在 Delphi 13.1 Florence 环境下,让 DevExpress VCL 控件真正可编译、可设计、可调试、不崩溃——且全程用官方源码,不靠第三方 patch 或降级妥协。适合正在从 Delphi 12 迁移、或接手遗留 VCL 项目需叠加新 UI 组件的工程师;也适合被 FastReport VCL 或 TMS VCL 卡在兼容性上的团队,因为这里踩过的坑,90% 同样适用于其他大型商业 VCL 套件。


2. 从源码重编译:为什么不能直接安装 .bpl,而必须亲手过一遍 dcc32/dcc64 流程

DevExpress 提供的DxAutoInstall.exe是个便利工具,但它本质是调用msbuild+dcc32批量编译.dpk包,并注册到 IDE。在 Delphi 13.1 中,这个流程有三处致命断点:一是dxCoreXX.dpk默认 Target Platform 仍设为 Win32/Win64,未适配 Florence 新增的Win64-Clang和Win32-Clang编译器;二是dclDX*.dpk(设计时包)引用的Vcl.Themes单元在 Florence 中已重构,旧版dxThemeManager.pas会因TStyleEngine.RegisterStyleHook签名变更而编译失败;三是dxAutoInstall不校验$(BDS)\Source\RTL\Win下的System.Classes.pas版本,导致TObjectList<T>泛型继承链解析错误。所以,必须放弃一键安装,改用手动重编译源码——这不是折腾,而是把控制权拿回自己手里。

2.1 准备工作:定位源码根目录与关键路径映射

解压DevExpress_VCL_v25.1.6_Full_Source.zip后,你会看到类似结构:

DevExpress\ ├── Source\ │ ├── VCL\ ← 核心 VCL 控件源码(含 dxCore, dxBar, dxLayout 等) │ └── DesignTime\ ← 设计时包源码(dclDX*.dpk) ├── Lib\ │ ├── Win32\ ← 预编译的 .bpl(忽略,不用) │ └── Win64\ └── Tools\ └── DxAutoInstall\ ← 安装脚本(仅作参考,不执行)

提示:不要删除Source\VCL\下任何.pas文件,v25.1.6 的dxCore已拆分为dxCore,dxCoreCommon,dxCoreDesign三个逻辑单元,缺一不可。尤其注意dxCoreCommon.pas中的{$IFDEF DELPHI13_UP}条件编译块——这是 DevExpress 为 Florence 埋的适配开关,但默认未启用。

2.2 修改 .dpk 文件:强制启用 DELPHI13_UP 并重定向 RTL 引用

打开Source\DesignTime\dclDXCore.dpk(所有dclDX*.dpk都需同步修改),找到requires段:

requires rtl, vcl, vcltheme, dxCore;

必须改为:

requires rtl, vcl, vcltheme, dxCoreCommon, // 显式添加,避免隐式依赖链断裂 dxCore; // 保持原有引用

再找到contains段末尾,添加:

{$IFDEF DELPHI13_UP} dxCoreCommon, {$ENDIF}

接着,在文件顶部package声明后插入条件编译定义:

{$IFDEF VER350} // Delphi 13.1 = VER350 {$DEFINE DELPHI13_UP} {$DEFINE DELPHI13_FLORENCE} {$ENDIF}

参数说明:VER350是 Delphi 13.1 的内部版本号(Delphi 12 是 VER340,Delphi 11 是 VER330)。DELPHI13_UP是 DevExpress 源码中用于触发 Florence 专用补丁的开关,比如dxThemeManager.pas中的if not Assigned(TStyleEngine.Current) then TStyleEngine.Current := TStyleEngine.Create;就包裹在此宏内。不加这行,编译器会跳过所有 Florence 修复逻辑。

2.3 用命令行 dcc64 编译:绕过 IDE 加载失败,直击编译器报错根源

IDE 图形界面加载失败时,命令行是最干净的诊断环境。打开Delphi 13.1 自带的 RAD Studio Command Prompt(非普通 CMD),执行:

cd /d "D:\DevExpress\Source\DesignTime" dcc64 dclDXCore.dpk -U"D:\DevExpress\Source\VCL" -U"C:\Program Files\Embarcadero\Studio\23.0\source\vcl" -U"C:\Program Files\Embarcadero\Studio\23.0\source\rtl\win" -LE"C:\Users\Public\Documents\Embarcadero\Studio\23.0\Bpl" -LN"C:\Users\Public\Documents\Embarcadero\Studio\23.0\Dcp" -Q -W- -H- -M -JPHN -GD -DDELPHI13_UP
  • -U:指定单元搜索路径,必须显式包含Source\VCL和 Delphi 13.1 的source\vcl、source\rtl\win,否则TStyleEngine等类型找不到;
  • -LE:输出.bpl到 BPL 目录(IDE 默认加载位置);
  • -LN:输出.dcp到 DCP 目录(设计时包依赖必需);
  • -DDELPHI13_UP:传递预处理器定义,等效于源码中{$DEFINE DELPHI13_UP};
  • -Q:启用详细错误报告,定位到具体行号;
  • -W-:关闭所有警告(避免W1025 Unsupported construct类干扰);
  • -H-:禁用 hint(H2077 Unit 'System.Generics.Collections' implicitly imported这类提示无实际价值)。

若编译成功,你会看到dclDXCore.bpl和dclDXCore.dcp生成;若失败,典型报错如:

[dcc64 Error] dxThemeManager.pas(128): E2003 Undeclared identifier: 'TStyleEngine'

说明-U路径未正确指向 Delphi 13.1 的source\rtl\win,需检查路径是否存在空格或中文字符(建议全英文路径)。


3. IDE 集成与设计时加载:注册包、处理 RTL 冲突、规避 TStyleEngine 初始化死锁

编译出.bpl只是第一步。Delphi 13.1 的 IDE 加载设计时包时,会按bpl依赖顺序逐个初始化,而 DevExpress 的dclDXCore.bpl依赖dxCore.bpl,后者又在初始化时调用TStyleEngine.RegisterStyleHook—— 此时若Vcl.Themes尚未完全加载,就会触发访问违规。这不是 DevExpress 的 bug,而是 Florence 的 RTL 初始化时序变更所致。

3.1 手动注册包:用 IDE Options 替代 AutoInstall,掌控加载顺序

启动 Delphi 13.1 IDE →Tools → Options → Environment Options → Package → Package File→ 点击Add...→ 选择你编译好的dclDXCore.bpl(位于C:\Users\Public\Documents\Embarcadero\Studio\23.0\Bpl\)。关键操作:勾选Load this package on startup,但不要勾选Install(即不自动加载其依赖包)。然后点击OK。

为什么分步加载?因为dclDXCore依赖dxCore.bpl,而dxCore.bpl是运行时包,无需 IDE 加载。若勾选Install,IDE 会尝试同时加载dxCore.bpl,但该包不含设计时单元,加载失败会导致整个包注册中断。我们只要dclDXCore.bpl这个设计时包能被 IDE 识别即可。

3.2 强制延迟初始化:在项目 DPR 中注入 StyleEngine 补丁

新建一个空白 VCL Forms Application → 打开Project1.dpr,在begin之前插入:

uses Vcl.Themes, Vcl.Styles, System.SysUtils; initialization // Delphi 13.1 Florence 中 TStyleEngine.Current 可能为 nil,导致 dx 控件初始化崩溃 if not Assigned(TStyleEngine.Current) then TStyleEngine.Current := TStyleEngine.Create; // 确保 Vcl.Themes 已就绪再加载 DevExpress 主题 if Assigned(TStyleManager.ActiveStyle) then TStyleManager.TrySetStyle('Windows11'); end.

逻辑说明:这段代码确保TStyleEngine.Current在 DevExpress 控件创建前已被实例化。dxCore的dxThemeManager.pas中有if Assigned(TStyleEngine.Current) then ...判断,若为nil会跳过主题注册,后续控件渲染时因样式钩子未注册而崩溃。此初始化必须放在initialization段,早于任何窗体创建。

3.3 验证设计时可用性:拖拽 dxNavBar 到窗体,检查 Object Inspector 是否显示属性

重启 IDE → 新建 VCL Form → 从 Component Palette 的DevExpress VCL页签拖一个TdxNavBar到窗体。若 Object Inspector 中能正常显示Groups,Options,Appearance等属性页,且窗体预览区实时渲染导航栏,则设计时集成成功。若属性页为空或报错Invalid property value,说明dclDXCore.bpl未正确加载,返回第 3.1 步检查包路径和勾选状态。


4. 常见问题排查:五条血泪经验,每一条都来自真实翻车现场

Delphi 13.1 + DevExpress VCL 的组合,表面是版本兼容,实则是 RTL 层、编译器层、IDE 插件层三重博弈。以下五条是我在三个客户项目中反复踩坑后提炼的「后悔药清单」,现象精准、原因直指底层、解决一步到位。

4.1 现象:IDE 启动后立即弹窗 “Access violation in module ‘dxCore.bpl’ at address …”

原因:dxCore.bpl(运行时包)被 IDE 错误加载。Delphi 13.1 的bpl加载器会扫描Bpl目录下所有.bpl,若dxCore.bpl也在其中,它会尝试初始化,但该包不含设计时单元,其initialization段调用TStyleEngine.RegisterStyleHook时TStyleEngine.Current尚未创建,导致 AV。
解决:将dxCore.bpl移出Bpl目录,仅保留dclDXCore.bpl。运行时包由你的应用程序.exe在uses中引用dxCore单元时动态加载,无需 IDE 管理。

4.2 现象:窗体设计器中 dx 控件显示为灰色方块,右键菜单无 “Edit…” 选项

原因:dclDXCore.dpk编译时未启用DELPHI13_UP,导致dxNavBarDesigner.pas中的GetVerbCount方法返回 0,IDE 认为该控件不支持设计时编辑。
解决:重新编译dclDXCore.dpk,确认命令行含-DDELPHI13_UP,且源码中{$IFDEF DELPHI13_UP}块内GetVerbCount := 1;已取消注释。

4.3 现象:编译项目时报错 “[dcc64 Error] dxLayout.pas(452): E2003 Undeclared identifier: ‘TValue’”

原因:TValue是 Delphi 10.4+ 引入的泛型类型,但dxLayout.pas中{$IF CompilerVersion >= 34.0}判断错误(Delphi 13.1 是 35.0),导致旧版TValue兼容代码未启用。
解决:打开dxLayout.pas,找到{$IF CompilerVersion >= 34.0},改为{$IF CompilerVersion >= 35.0};并在uses中添加System.Rtti(TValue定义所在单元)。

4.4 现象:运行时 dxGrid 点击列头排序,程序崩溃在dxCustomGrid.pas第 2891 行

原因:Florence 的TThread.Synchronize实现变更,dxCustomGrid中Synchronize(DoSort)调用传入的匿名方法捕获了Self,而Self在排序过程中被释放,导致悬空指针。
解决:在dxCustomGrid.pas的TdxCustomGrid.DoSort方法开头添加:

if not Assigned(Self) then Exit; // 防御性检查

并在Synchronize调用前加锁:

FCriticalSection.Enter; try Synchronize(DoSort); finally FCriticalSection.Leave; end;

(FCriticalSection: TCriticalSection需在类声明中添加)

4.5 现象:部署到客户机器后 dxSpreadSheet 控件无法打开 Excel 文件,报错 “OLE error 80040154”

原因:dxSpreadSheet依赖Microsoft.Office.Interop.Excel,而 Delphi 13.1 默认编译为Win64-Clang,但 Office PIA(Primary Interop Assembly)仅支持Win32或Win64(MSVC),Clang 编译的.exe无法加载 PIA。
解决:在项目 Options →Target Platforms中,取消勾选Win64-Clang,仅保留Win64(MSVC);或改用dxSpreadSheet的纯 VCL 渲染模式(Options.ExportFormat := sefXlsx;),避开 OLE。


5. 进阶技巧:用 dxSkinController 动态切换 Windows 11 / Dark / Light 主题,且不触发 RTL 重绘抖动

DevExpress 的皮肤系统(Skin System)在 Delphi 13.1 中有个隐藏陷阱:调用dxSkinController1.SetSkin('Windows11')后,窗体控件会闪烁重绘,尤其在TdxNavBar或TdxDockPanel上表现明显。这不是视觉 Bug,而是 Florence 的Vcl.Themes重绘机制与 DevExpress 的dxSkinController事件循环不同步所致。解决方案不是禁用动画,而是接管重绘节奏。

5.1 关键参数:禁用皮肤过渡动画,但保留平滑渐变

在窗体OnCreate事件中:

procedure TForm1.FormCreate(Sender: TObject); begin // 禁用皮肤切换时的过渡动画(避免重绘抖动) dxSkinController1.Options.Animation.Enabled := False; // 启用硬件加速渲染(Florence 默认开启,但需显式确认) dxSkinController1.Options.RenderOptions.UseHardwareAcceleration := True; // 设置皮肤后强制同步重绘,而非等待消息队列 dxSkinController1.SetSkin('Windows11'); Application.ProcessMessages; // 立即刷新,不卡顿 end;

参数说明:Animation.Enabled := False并非粗暴关闭所有动画,而是禁用皮肤切换时的FadeIn/FadeOut过渡帧,避免TCanvas多次重绘冲突;UseHardwareAcceleration在 Florence 中默认为True,但某些显卡驱动会误判,显式设置可规避;Application.ProcessMessages是关键——它强制将皮肤应用后的重绘消息立即 dispatch,而不是排队等待,从而消除「先闪白再上色」的撕裂感。

5.2 主题切换热键:Ctrl+Shift+1/2/3 实时切换,且记录用户偏好

在窗体OnKeyDown中:

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if (ssCtrl in Shift) and (ssShift in Shift) then case Key of 49: SetSkinAndSave('Windows11'); // Ctrl+Shift+1 50: SetSkinAndSave('Dark Style'); // Ctrl+Shift+2 51: SetSkinAndSave('Light Style'); // Ctrl+Shift+3 end; end; procedure TForm1.SetSkinAndSave(const SkinName: string); begin dxSkinController1.SetSkin(SkinName); // 保存到注册表,下次启动自动加载 TRegistry.Create.OpenKey('\Software\MyApp\Skins', True); try TRegistry.WriteString('LastSkin', SkinName); finally TRegistry.CloseKey; end; end;

5.3 防止多显示器 DPI 缩放错乱:为 dx 控件显式设置 ParentBackground

Delphi 13.1 的高 DPI 支持增强,但TdxNavBar等容器控件默认ParentBackground := False,导致在 125% DPI 的副屏上背景色异常。解决方案是批量设置:

procedure TForm1.ApplyDPIFix; var I: Integer; C: TControl; begin for I := 0 to ControlCount - 1 do begin C := Controls[I]; if C is TdxCustomNavBar then TdxCustomNavBar(C).ParentBackground := True; if C is TdxDockPanel then TdxDockPanel(C).ParentBackground := True; end; end;

调用时机:在FormCreate之后、dxSkinController1.SetSkin之前执行。

我的习惯:每次升级 Delphi 大版本,我都会把 DevExpress 源码目录加入 Git 仓库,每个.dpk和关键.pas文件的修改都 commit 并打 tag(如delphi13.1-fix-202405)。这样下次升级到 Delphi 14 时,只需git diff delphi13.1-fix-202405..origin/main就能快速定位哪些补丁需要迁移。源码不是拿来摆设的,是拿来改的——尤其是当商业组件跟不上编译器进化速度时。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询