EhLib VCL 10.0.030 for D7-DX10.4 编译安装与 DBGridEh 使用指南
简介EhLib VCL 10.0.030 是一套面向 Delphi 与 C Builder 开发者的组件库专为数据敏感型应用设计支持从 Delphi 7 到 DX10.4 的多个版本。它提供动态数据集、条件格式化、图表与向导功能统一支持 Firebird、MySQL、Oracle、InterBase 等数据库适合需要快速构建数据库客户端、报表和管理界面的开发者。压缩包约 60.63MB共 2000 个文件涵盖 dcu 编译单元、pas 源码、dfm 窗体、hpp 头文件及 dpk/dproj 工程文件便于直接安装或阅读定制。内含示例工程与帮助文档可降低上手门槛。目前已有 51 人学习。下载该资源可获得完整可用的 VCL 组件库安装包设计期可注册组件运行期提供库与数据库驱动能有效减少数据表格、报表格式化和跨数据库开发中的重复编码。组件许可涵盖开源到商业选项适合不同规模的团队采用。1. EhLib VCL 10.0.030 for D7-DX10.4 到底是一份什么包EhLib VCL 10.0.030 for D7-DX10.4 是一份能在 Delphi 7、Delphi 2007、XE 系列一直到 10.4 Sydney 之间来回迁移的组件库发行版。初次打开解压目录的人通常会被十几个.bdsproj工程文件唬住其实这些文件只讲了一件事这个库不是装完即用的安装包而是一套需要按依赖顺序自行编译的源码包。它的价值在工作区里非常具体——DBGridEh 的条件着色、列标题点击排序、行底统计、单元格下拉筛选原生 VCL 要写上一周的交互在这里拖两个属性就出来了。对正在学习 Delphi 的开发者它是研究 VCL 组件包机制的现成样本对维护存量项目的工程师它是接住老项目的关键依赖。下面从工程结构入手把这包拆开讲。2. 拆开 bdsgroup 与 bdsprojEhLib 运行时包和设计时包的编译顺序EhLib 这套包与普通第三方库最大的不同在于它把“编译链接进程序”和“注册到 IDE 组件面板”两件事拆成了两套工程。搞不清这个分工后面编译时就会反复出现“找不到类”“包无法加载”之类的问题。2.1 运行时包 EhLib90 与设计时包 DclEhLib90 的分工压缩包里同时存在EhLib90.bdsproj和DclEhLib90.bdsproj前者生成的是运行时包最终会被你的应用程序引用exe 运行时需要它后者生成的是设计时包只对 IDE 可见负责把组件注册到组件面板并提供设计期编辑器、属性编辑器。两者名字上的Dcl前缀就是 Design-time Component Library 的意思。包的编译顺序有硬性要求必须先编译运行时包再编译设计时包。原因很简单设计时包在注册组件时需要引用运行时包里的类型定义例如TDBGridEh这个类本身在EhLib90.bpl中DclEhLib90.bpl里只有把它注册进 IDE 的代码。顺序反了编译器会直接报“找不到 DBGridEh 单元”或“无法解析外部符号”。工程文件生成包生效位置编译顺序EhLib90.bdsprojEhLib90.bpl应用程序运行时先DclEhLib90.bdsprojDclEhLib90.bplIDE 设计期后EhLibBDEDataDrivers90.bdsproj对应驱动运行时包应用程序运行时先DclEhLibBDEDataDrivers90.bdsproj对应驱动设计时包IDE 设计期后注意看数据驱动这一组BDE、ADO、DBX 三项都同时给出了运行时包和设计时包唯独 IBX 驱动只有DclEhLibIBXDataDrivers90.bdsproj而没有对应的运行时包。这不属于打包遗漏而是驱动依赖策略的差异。IBX 相关单元被直接并进了主 EhLib90 运行时包如果你的目标数据库只有 InterBase/Firebird 且走 IBX 连接完全可以忽略这几个数据驱动工程不用为用不到的能力引入额外的 bpl 依赖。2.2 四个数据驱动包如何选BDE、ADO、DBX、IBXEhLib 本身不直接实现数据库协议它通过一组 Data Driver 把数据集的操作细节交给不同的连接层。工程列表里四个驱动分别对应四种连接方式选择时主要看老系统遗留了什么依赖而不是看哪个“更好”。BDE 是 Borland 时代的东西性能和数据访问能力在今天已经谈不上优势唯一的现实意义是兼容老项目。维护 D7 时代留下来的 BDE 工程时EhLibBDEDataDrivers90必须编进去否则老代码里依赖 BDE 数据集的排序、筛选行为会退化。ADO 适合 Windows 平台下对接 SQL Server、Access 或通过 OLEDB 访问 Oracle 的场景部署时不用单独安装 BDE 配置程序这也是很多内部管理系统选择它而不是 BDE 的原因。DBX 对应 dbExpress是 Delphi 跨平台方案里最常见的轻量数据访问层对 Firebird、MySQL、PostgreSQL 都能提供统一接口但 dbExpress 的驱动是单向数据集做编辑操作时通常需要配合TDataSetProvider和TClientDataSet。IBX 驱动前面提过只针对 InterBase/Firebird事务控制直接暴露TIBTransaction行为最贴近 InterBase 本身的语义。剪裁原则很简单不用的工程不进编译缺哪个驱动再回来补编哪个包运行时依赖会少很多。2.3 按依赖顺序编译从 .bdsgroup 到逐条 msbuildEhLibProjGroup90.bdsgroup是工程组文件在 IDE 里双击打开后Project Manager 会一次列出全部子工程并在工程之间显示依赖关系。它解决的是“先编谁”的问题但命令行构建时我不会直接指望 IDE 的拖拽排序而是按固定顺序逐条执行。在 10.4 Sydney 中打开这套包时IDE 会提示把.bdsproj升级为.dproj这属于正常的工程格式迁移。升级后可以用 msbuild 做批处理构建顺序如下set MSBUILDC:\Program Files (x86)\Embarcadero\Studio\20.0\bin\msbuild.exe set CONFIGRelease set PLATFORMWin32 %MSBUILD% EhLib90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% EhLibBDEDataDrivers90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% EhLibADODataDrivers90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% EhLibDBXDataDrivers90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% DclEhLib90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% DclEhLibBDEDataDrivers90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% DclEhLibADODataDrivers90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% DclEhLibDBXDataDrivers90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM% %MSBUILD% DclEhLibIBXDataDrivers90.dproj /t:Build /p:Config%CONFIG% /p:Platform%PLATFORM%这段脚本里的/t:Build指定构建目标/p:Config和/p:Platform分别控制 Release 配置和 Win32 平台。Platform参数在 XE2 之后的 IDE 中必须显式给出因为 IDE 进程本身可能是 64 位但 VCL 应用和包默认仍按 32 位编译。如果在 Delphi 7 或 BDS 2006 这类老版本中操作msbuild 这套方式不可用直接在 IDE 中打开.bdsgroup右键逐个 Build 同样能完成只是没有命令行批处理的可重复性。3. 从 Delphi 7 到 10.4 SydneyEhLib 源码包的 IDE 安装全流程拿到源码包之后最卡人的一步其实是安装。很多人把.bdsproj当成普通工程双击打开编译报错就认为是包坏了实际上多半是环境问题或顺序问题。3.1 编译前的环境检查dcc32、Community Edition 与库路径安装前先确认三件事IDE 版本、编译器路径、库路径。打开 RAD Studio 自带的命令提示符或者直接在终端里执行where dcc32能输出 dcc32.exe 的完整路径说明命令行工具在 PATH 中。如果提示找不到命令打开开始菜单里的 “RAD Studio Command Prompt” 再试Delphi 默认不会把编译器目录加进系统 PATH。Delphi 7 到 10.4 Sydney 这个跨度里编译器行为差异最大的分界点是 Unicode 支持。D7 默认的string是 ANSI 类型10.4 Sydney 里string已经是 UnicodeStringEhLib 源码内部大量使用条件编译指令处理这套差异所以不需要你手工改代码但要注意别把 D7 下编译出来的 bpl 拿到新 IDE 里用。10.4 Sydney 时代最常见入门选择是 Delphi Community Edition它对个人开发者免费功能上覆盖了 VCL 开发的大部分需求。它和专业版的差异主要在许可范围而不是编译器能力安装 EhLib 的流程没有区别。需要留意的是社区版安装位置同样在C:\Program Files (x86)\Embarcadero\Studio\20.0路径里的空格决定了一切带路径的命令都要加引号。3.2 分步编译与注册把 bpl 装进 IDE 组件面板整个安装过程分成五步每一步之间不要跳。第一步解压。路径里不要有中文和空格我一般放在D:\Components\EhLib10。路径问题在 Delphi 的老版本里尤其敏感某些 IDE 版本对带空格路径的 bpl 搜索支持得很差排查起来非常浪费时间。第二步打开工程组。在 10.4 Sydney 中直接双击EhLibProjGroup90.bdsgroupIDE 会先弹工程格式迁移提示确认转换即可。在 Delphi 7 中打开这个文件没有迁移过程因为 D7 根本识别不了.bdsproj需要直接用菜单里的 Open 打开对应版本的.dpk再手动按依赖顺序编译。第三步编译运行时包。在 Project Manager 中找到EhLib90.bdsproj右键 Build。等输出窗口出现 “Build succeeded” 后继续编译需要的数据驱动运行时包BDE、ADO、DBX 按需选择。第四步编译并安装设计时包。依序 BuildDclEhLib90.bdsproj以及各Dcl*DataDrivers90.bdsproj然后执行菜单 Component Install Packages点击 Add把生成目录下的DclEhLib90.bpl和对应驱动的设计时包添加进去。第五步配置库路径。Tools Options Environment Options Delphi Options Library把 EhLib 源码目录加入 Library path。这一步不做的后果是后续新建工程时 IDE 找不到 EhLib 单元明明组件面板上有控件编译却报“File not found: DBGridEh.dcu”。3.3 放置 DBGridEh 验证安装成功与失败的判据安装是否成功不要看 bpl 是否编译通过直接新建一个 VCL Forms Application在组件面板找一个叫 EhLib 的页签。拖一个TDBGridEh到窗体上IDE 自动在 uses 里生成对DBGridEh单元的引用uses DBGridEh;类型声明中能看到TDBGridEh的存在type TForm1 class(TForm) DBGridEh1: TDBGridEh; private { Private declarations } public { Public declarations } end;能拖出来、能在对象树中看到DBGridEh1说明运行时包和设计时包都已正确加载。如果组件面板没有 EhLib 页签回到 3.2 的第四步检查 Install Packages 列表。如果拖出来是灰块而对象树里存在该对象通常是运行时包与设计时包版本不匹配最常见原因是 IDE 缓存了旧的 bpl 副本关掉 IDE删除%AppData%\Embarcadero\BDS\20.0\下的*.bpl缓存后重新打开。4. DBGridEh 条件格式化与 MemTableEh 动态数据集报表交互的落地代码安装只是开始真正有价值的是 DBGridEh 在数据展示上比原生 DBGrid 多出来的那一层能力。这一章直接给可抄的代码从最常用的条件着色讲到动态数据集。4.1 GetCellParams 条件格式化让关键数据在滚动时直接变色原生 DBGrid 要做单元格变色一般写在OnDrawColumnCell里需要自己算矩形、自己调 Canvas 的填充和文字输出。DBGridEh 提供了更简洁的GetCellParams事件在绘制前先改字体和背景色剩下的绘制逻辑交给控件本身。procedure TForm1.DBGridEh1GetCellParams(Sender: TObject; Column: TColumnEh; AFont: TFont; var Background: TColor; State: TGridDrawState); begin if Column.FieldName AMOUNT then begin if Column.Field.AsFloat 10000 then begin AFont.Color : clMaroon; Background : $00F0F8FF; end else if Column.Field.AsFloat 0 then begin AFont.Color : clRed; Background : $00FFE8E8; end; end; end;这段逻辑发生时机的关键点在于GetCellParams在每次单元格绘制时触发Column.Field指向的是当前行的字段值所以不需要自己定位行号。AFont.Color修改的是文字颜色Background是单元格底色二者都只对当前绘制生效不会污染其他行的状态。State参数可以用来判断当前单元格是否处于选中或聚焦状态例如在gdSelected包含时把底色覆盖成高亮色避免选中行被自定义颜色盖掉后分不清焦点。需要注意这个事件里不要写数据库查询或复杂计算它会在网格滚动时被高频调用任何阻塞代码都会让滚动变得粘滞。排序、筛选之类的耗时操作放到 5.3 的 STFilter 方案里由控件内部处理。4.2 MemTableEh 动态数据集不碰数据库就造出可筛选的报表数据摘要里反复提到的“动态数据集”落到组件面板上就是TMemTableEh。它本质上是一张内存表字段结构可以在运行期动态定义数据不用经过数据库连接就能直接绑定到 DBGridEh这对于报表预演、导入导出中间层、单元测试非常实用。with MemTableEh1 do begin Close; FieldDefs.Clear; FieldDefs.Add(ID, ftInteger); FieldDefs.Add(REGION, ftString, 50); FieldDefs.Add(AMOUNT, ftFloat); CreateDataSet; AppendRecord([1, 华东, 12800.5]); AppendRecord([2, 华北, 7600.0]); AppendRecord([3, 华南, 15230.8]); end;FieldDefs.Add的前两个参数分别指定字段名和字段类型ftString类型还需要第三个参数表示最大长度。这里必须对字符串字段显式给长度否则CreateDataSet生成的结构会带上默认长度后续赋值长度超限时会截断数据。CreateDataSet在运行期一次性建立内存表结构不依赖任何数据库连接对象。AppendRecord的参数数组顺序必须与FieldDefs顺序保持一致类型不匹配时 Delphi 编译器会报参数错误而不是运行期转换。把MemTableEh1作为 DataSource 的 DataSetDBGridEh 就能立刻显示这些数据。我一般会在设计期把字段定义全部写好运行期只追加数据这样网格列的标题、宽度、对齐方式都能在设计器里直接调整不用在代码里维护布局。4.3 统计行、向导与图表哪些能力在包内哪些需要外接摘要里说 EhLib 支持图表和向导实际使用时要分清边界。EhLib 包内真正高频的是 DBGridEh 的 Footer 统计行选中某列把 Footer 的 ValueType 设为agSum网格底部会自动出现合计值这对报表场景几乎是零成本实现DBGridEh1.Columns[2].Footer.ValueType : agSum; DBGridEh1.Columns[2].Footer.DisplayFormat : #,##0.00;ValueType支持 agSum、agCount、agAvg 等聚合类型DisplayFormat控制数字显示格式。这套机制的表象和“图表”类似都是把数据集信息做二次呈现但它不会绘制饼图和柱状图。如果你的需求是独立画布上的数据可视化包本身不给这个能力常见做法是把同一个 DataSource 同时交给 TChart 或 DevExpress VCL 图表控件DBGridEh 负责列表预览图表负责视觉呈现。Delphi 10.4 Sydney 下让 DevExpress VCL 图表与 EhLib 共存的唯一前提是安装时不要注册同名设计时包两者设计时包没有命名冲突就互不干扰。“向导”同样要区分设计期和运行期。EhLib 提供的向导更多指列编辑器、字段选择器这类设计期对话框用来快速配置网格列与数据集字段的映射而不是面向终端用户的业务流程向导。了解这个边界之后就不会去源码包里找一个不存在的独立向导组件浪费时间。5. 跨库连接的边界、设计期报错与 STFilter 筛选技巧最后一章收在两个具体排查方向和一个小技巧上这些内容在项目交付阶段往往比编译安装更值得花时间。5.1 跨库连接EhLib 与驱动层的职责边界EhLib 对多数据库的支持建立在 Delphi 数据访问框架之上它本身不解析网络协议也不维护连接池跨库统一的是数据集接口和数据展示方式。连接层差异仍然由 ADO、DBX、IBX 等驱动承担。数据库常见连接层通常要多留意的点Firebird / InterBaseIBX、dbExpress字符集不一致时中文乱码IBX 注意事务生命周期MySQLdbExpress、第三方驱动日期时间与时区映射新版认证插件兼容性OracleADO(OLEDB)、DBXBLOB/CLOB 用流字段读取避免直接赋字符串PostgreSQLDBX、第三方 ODBC表名大小写敏感跨库移植时注意双引号5.2 安装后的两个高频异常组件面板没有 EhLib 页签时先到 Component Install Packages 列表里确认对应 bpl 是否勾选再确认 IDE 是否加载了旧缓存。另一个高频问题是运行期弹 “Cannot load package” 或找不到EhLib90.bpl。这个原因通常是 bpl 输出目录不在系统 PATH 中把编译输出目录 D:\Components\EhLib10\Bpl 加进 PATH或直接把 bpl 复制到 exe 所在目录即可解决。5.3 STFilter 的零数据库筛选演示DBGridEh 自带一套可配置的筛选机制它能在不写一条 SQL 的情况下完成内存数据过滤适合几千行以内的小数据集和离线演示。DBGridEh1.SortLocal : True; DBGridEh1.OptionsEh : DBGridEh1.OptionsEh [dghAutoSortMarking]; DBGridEh1.STFilter.Visible : True; DBGridEh1.STFilter.Local : True;SortLocal开启后点击列标题会在内存中对当前数据集直接排序。dghAutoSortMarking让排序列的标题上显示三角方向标记用户对当前排序状态一目了然。STFilter.Visible激活网格列标题下方的筛选行每一列输入内容后自动过滤。STFilter.Local是关键参数它把过滤操作限定在本地内存数据集不会生成数据库端的 WHERE 语句因此对 MemTableEh 这类无连接数据集同样生效。配合 4.2 的 MemTableEh这套组合可以在不连接任何数据库的情况下完整演示排序、筛选、统计、条件着色四类数据交互。本文还有配套的精品资源点击获取