☰
Delphi XE8下EhLib DBGridEh安装编译与迁移实战
2026/10/10 0:51:10 网站建设 项目流程

简介:面向Delphi开发者的DBGridEh增强表格控件资源,覆盖Delphi 7至XE8各版本,解决EhLib控件在旧版与新版IDE中的安装适配问题。压缩包约42.15MB,包含1401个文件,以dfm窗体文件、pas单元源码、dcu编译单元和hpp头文件为主,同时提供安装程序、批量复制脚本及说明文档,便于按需选用。目前已有553人学习下载。控件安装器支持自动识别当前Delphi版本,一键完成组件注册;包内附带Windows 7/8需以管理员身份运行、64位系统启动低版本Delphi提示EHLIB70.bpl丢失时如何配置系统PATH路径等实践排错思路,可帮助开发者省去手动注册和四处查找依赖的步骤。资源目录结构清晰,适合需要在Delphi环境中快速集成DBGridEh功能、或从旧版本升级的桌面应用开发者参考。 做Delphi的老开发,手里基本都有几个离不开的第三方控件,DBGridEh在我这儿就是头一个。它是EhLib组件库里的当家表格控件,业务系统里最常见的“列表展示+行内编辑+底部汇总”场景,靠它一个控件能省掉一大截工作量。最近我接了一个老项目升级的活,环境要往Delphi Xe8上迁,代码里铺天盖地全是DBGridEh,于是顺手把EhLib控件在Xe8下的版本支持、安装编译、代码迁移和踩坑记录重新过了一遍,就有了这篇东西。

这篇内容适合两类人。一类是还在维护老项目、被第三方控件版本兼容问题折腾到心力交瘁的Delphi程序员,可以直接拿走编译步骤和排错清单;另一类是想从标准DBGrid换到DBGridEh、又不知道从哪下手的新手,可以从场景和代码例子里理解这个控件到底强在哪。

1. 项目背景:先搞清楚EhLib和DBGridEh的位置

1.1 DBGridEh到底解决了什么核心痛点

接触过原生DBGrid的朋友应该都有感受:它是个非常“素”的表格,能显示数据、能编辑、能响应点击,但再往上走就什么都没有了。业务系统里最常见的需求,比如表格底部要有一行合计、某一列要下拉选择、表头要点一下就能自动过滤、同层级的数据要能折叠成树,这些事用原生DBGrid做,每一个都够你写半天事件代码。

DBGridEh把这些高频能力全部做进了控件本身。最常用的几个:页脚合计(SumList配合FooterValueType)、表头自动过滤(下拉箭头加条件筛选)、列下拉列表(PickList)、树形展示(TreeViewParams)、Excel/CSV导出(SaveToXLS系列)、网格布局保存恢复(SaveGridLayoutToFile/RestoreGridLayoutFromFile)。它还有配套的MemTableEh内存表、DBLookupComboboxEh查找下拉框,一套下来基本覆盖了传统桌面管理软件的表格交互需求。

打个比方,原生DBGrid是一块白板,所有功能都得自己往上画;DBGridEh是一块带了一堆预设模块的白板,你只需要拖出来配置属性,剩下的事它替你干。这就是为什么这么多年过去,老Delphi项目里它依然高频出现。

1.2 版本支持问题为什么总被反复问

Delphi这边版本迭代快,第三方控件往往滞后。尤其像EhLib这种带编译期组件、设计期包、源码级兼容的老牌库,每次Delphi大版本更新,组要等官方发新版才能跟上。我见过不少团队卡在Delphi 7、Delphi 2010上,不是不想升级,是手头控件和旧代码挪不动。

Xe8在这条时间线上又比较特殊:它是XE系列里最后一个版本,后面Embarcadero把命名改成了10 Seattle、10.1 Berlin这种地名体系。很多旧组件厂商在Xe8之后更新节奏变慢,反过来让Xe8变成了一个“第三方控件支持相对齐整”的落点。所以“支持Delphi版本到Xe8”这句话,在老项目圈子里意味着一个很具体的价值:你有一条不换控件也能升上去的路径。

2. 版本对应关系与升级到Xe8的选型逻辑

2.1 EhLib版本与Delphi版本的对应关系

先说个原则:EhLib不是一个大版本同时支持所有Delphi,而是随着Delphi发版不断出小版本。所以拿到安装包先别急着编译,第一件事是确认你手上这个EhLib版本对应的Delphi版本范围。

我整理了一下我记得的大致对应表,注意具体以官方发布说明为准:

EhLib版本主要支持的Delphi/RAD Studio版本大致时间段
EhLib 3.6Delphi 5 ~ Delphi 20072008年之前
EhLib 4.xDelphi 2009 / 2010 / XE2009 ~ 2010
EhLib 5.xDelphi XE ~ XE52011 ~ 2013
EhLib 6.xDelphi XE5 ~ XE8 / 10 Seattle2014 ~ 2015
EhLib 7.xDelphi XE8 ~ 10.2 Tokyo2016 ~ 2017
EhLib 8.xDelphi 10.2 Tokyo2017
EhLib 9.xDelphi 10.3 Rio2018 ~ 2019
EhLib 10.xDelphi 10.4 Sydney2020
EhLib 11.xDelphi 11 Alexandria2021

如果你在Xe8下装6.x或7.x都是合理的,关键看官方release notes里有没有明确写“Delphi XE8”。我这次环境里的EhLib正好覆盖到Xe8,省了打补丁的功夫。顺带说一句,Xe8对应的RAD Studio内部版本号是22.0,安装目录一般在C:\Program Files (x86)\Embarcadero\Studio\22.0,后面找路径时用得上。

2.2 升级到Xe8的动机评估

很多人问:项目跑得好好的,非升不可吗?我的看法是,如果还处于Windows 7到Windows 10/11的过渡期,Xe8值得升。老编译器编译出的程序在新系统上偶尔出现字体渲染、权限路径、高DPI缩放问题,Xe8这一代对Win10的适配比老版本好很多,而且支持Win64,内存占用大的业务系统能切到64位。再加上FireDAC在Xe8里已经很成熟,从BDE/dbExpress迁出来的路也顺畅。

但也要冷静。如果你的业务代码大量依赖某些更老版本的语法特性,或者数据库驱动只有32位版,那就先别急着上64位,Xe8跑32位目标也是完全OK的。把“升级IDE”和“切64位”拆成两步走,风险会小很多。

3. Xe8下编译安装EhLib的完整实操

3.1 先看清安装包结构

把EhLib压缩包解压后,通常能看到Common、Packages、Demos、Resources这些目录。Common里是运行时源码,比如DBGridEh.pas、DBSumList.pas、MemTableEh.pas这些核心单元;Packages里才是各个Delphi版本对应的安装工程。

这一步最容易犯的错是拿错工程文件。Packages目录下一般会有按版本区分的dproj/dpk,文件名里可能带版本后缀或所在子目录区分。你在Xe8里打开的时候,务必选带XE8标识的那个,不要拿XE7或者10 Seattle的工程硬编译,那样生成的DCU版本对不上,后面到处报错。

3.2 编译顺序:运行期包在前,设计期包在后

EhLib的包分成两类:运行期包(RunTime Package)负责提供控件实现,比如EhLib对应的运行时包;设计期包(DesignTime Package)负责注册到IDE组件面板,通常带Dcl前缀,比如DclEhLib那类。安装顺序不能反:先编译运行期包,再编译安装设计期包。

具体步骤是:在Xe8里打开运行期包工程,Project Manager里确认当前平台是Win32(第一次装时先用32位跑通),然后直接Build。它会自动把生成的.bpl、.dcu输出到指定目录。然后打开设计期包工程,Build成功后执行Install。这里有个容易忽略的点:设计期包安装前,运行期包必须已经出现在IDE的已知包列表里,否则design time包编译时会提示找不到依赖包。

编译完成后,去Component > Install Packages里确认DclEhLib那一项已经勾上,然后新建一个窗体,在组件面板找“EhLib”相关页签,能拖出DBGridEh、MemTableEh这些组件就算成功了。如果面板上找不到,多半是安装没成功,或者IDE缓存没刷新,重启一次Xe8再试。

3.3 别忘了设置Library路径

安装成功只是第一步,新建项目里引用DBGridEh还需要让IDE能找到DCU。打开Tools > Options > Environment Options > Delphi Options > Library,把EhLib的Common目录和编译输出目录都加到Library path里。这一步不做的典型报错是“Cannot find unit DBGridEh.dcu”。

还有一点要注意:如果项目要出64位版本,用Win32平台编译出来的DCU不能直接给Win64用。你需要把运行期包切到Win64平台再编译一遍,设计期包保持32位不动。这个“双平台各编一次”的操作,是很多老鸟也容易漏的,等XP运行64位程序时才发现DCU版本不匹配。

4. 代码迁移:从DBGrid到DBGridEh的改动面

4.1 最小化改造:先把控件换上再看属性

如果旧项目用的是原生DBGrid,迁移到DBGridEh其实没有想象中伤筋动骨。两者都走DataSource + DataSet这套VCL标准数据链路,所以DataSet、DataSource、字段绑定那一套完全不用动。你只需要把Form上的DBGrid控件类型换成DBGridEh,然后按需删掉以前写的事件代码——比如以前自己手写的OnDrawColumnCell自适应列宽、自己弄的合计逻辑,这些DBGridEh都内置了。

我的习惯是:先在测试分支里做一次“无脑替换”,也就是只换控件类,不改任何逻辑,编译一把看有哪些地方因为API差异报错。DBGrid的很多属性在DBGridEh里是兼容的,比如Columns、DataSource、ReadOnly这些都能直接映射,实际改动量通常比预期小。

4.2 高频功能代码示例

列合计是最常见的一个需求。设计期在表格底部右键打开Columns编辑器,选一列,把Footer.ValueType设成fvtSum,再把Footer.ValueFormat设成'#,##0.00'就行。代码里等价写法是:

DBGridEh1.FooterRowCount := 1; DBGridEh1.SumList.Active := True; DBGridEh1.Columns[3].Footer.ValueType := fvtSum; DBGridEh1.Columns[3].Footer.ValueFormat := '#,##0.00';

常见的Footer.ValueType还有fvtCount、fvtAvg、fvtMax、fvtMin,覆盖了统计场景里的大部分需求。

表头自动过滤也很常用。把OptionsEh加上dghAutoFilterMarking,再设置STFilter相关属性,用户就能在表头上看到过滤下拉框,输入条件后网格自动筛选。代码里可以这样打开:

DBGridEh1.OptionsEh := DBGridEh1.OptionsEh + [dghAutoSortMarking, dghAutoFilterMarking];

如果希望某个字段用下拉选择过滤,可以在该列的STFilter.ListValues里预设。这个功能对运营管理类系统特别实用,用户几乎不需要培训。

下拉列表配置用PickList。给某列加几个可选值:

DBGridEh1.Columns[1].PickList.Clear; DBGridEh1.Columns[1].PickList.Add('未处理'); DBGridEh1.Columns[1].PickList.Add('处理中'); DBGridEh1.Columns[1].PickList.Add('已完成');

树形展示是DBGridEh的另一个招牌功能。只要数据表里有主键和父键两个字段,设置一下就能出树:

DBGridEh1.TreeViewParams.TreeView := True; DBGridEh1.TreeViewParams.KeyFieldName := 'ID'; DBGridEh1.TreeViewParams.ParentKeyFieldName := 'PID';

需要注意的是,树形展示对数据顺序有要求,父行必须先于子行出现,通常建议按ParentKeyField排序后再绑定。不然会出现“子节点出来了但折叠不了”的怪现象。

4.3 Unicode和64位这两个躲不过去的坎

Xe8已经是全面Unicode的编译器,但从Delphi 7这种AnsiString时代迁过来的代码,这里最容易炸。比如以前拿PAnsiChar做缓冲、拿字符串当字节数组、各种显式AnsiString赋值,这些在Xe8下编译通常会出类型不匹配。DBGridEh本身对Unicode支持没问题,但你的数据集如果连的是老数据库驱动,字符集配置不对,显示中文就会出现乱码。我遇到过的经典案例是MySQL ODBC驱动没指定utf8,导致DBGridEh里中文全部变问号,最后是在连接串里加charset参数解决的。

64位则是另一个维度。EhLib的源码在Win64下编译基本没有汇编之类的问题,但你的项目里如果有其他第三方的32位DLL,或者用了内联汇编,就要先处理掉。建议先确保项目能在Xe8下编译出32位版本,再尝试切Win64,避免一次性引入多个变量,出了问题都不知道怪谁。

5. 常见问题与排错速查

5.1 编译期报错

我按实际排查顺序给你列一张速查表:

报错现象常见原因处理方式
Cannot find unit DBGridEh.dcuLibrary path没有配置把EhLib源码目录和输出目录加进Library path
E2202 Required package xxx not found运行期包没先编译/安装先编译并安装运行期包,再编译设计期包
E2089 Invalid typecast / Incompatible types编译器版本和DCU不一致一定用对应Xe8版本的dproj重新编译,不要复用旧DCU
Already contains package旧版本EhLib残留Component > Install Packages里移除旧包,重启IDE
Could not create output file目标目录没有写权限以管理员身份运行Xe8,或修改输出目录

这里特别说下“Already contains package”的坑。以前装过别的版本EhLib,卸载时没卸干净,IDE内存里还残留包引用,新版本一装就冲突。我一般先检查Install Packages列表,把带EhLib字样的一项全部删掉,关IDE,手工删掉BPL目录下对应的.bpl文件,再重新开IDE安装,成功率会高很多。

5.2 运行期行为异常

编译过了不代表万事大吉,运行期问题更隐蔽。最常见的几个:

过滤下拉框不显示。先确认OptionsEh里有没有打开dghFilterDropDown,以及对应列的STFilter属性是否激活。有的版本默认只开一个全局开关,列级别没开,光设全局也没用。

合计列显示成0。先看SumList.Active是否为True,再看列的字段类型,如果是字符串类型的字段,fvtSum是不生效的。另外,如果数据集里不是数值类型而是BCD,建议把Column的Footer.ValueFormat明确写成'#,##0.00',避免格式化把小数吃掉。

树形数据展开没反应。先检查KeyFieldName和ParentKeyFieldName是不是写反了,再检查数据顺序。这种情况我遇到很多次,看起来属性都对,实际是数据集没按父键排序,子记录跑到父记录前面了。

5.3 数据量大时的性能优化

DBGridEh功能多,但功能都是有代价的。数据量上了万行,如果还开着全局过滤、实时合计、自动列宽,界面卡顿是必然的。我的习惯是三层优化:

第一层,数据操作期间用BeginUpdate/EndUpdate包起来,避免每刷新一个单元格就触发一次重绘矩阵:

DBGridEh1.BeginUpdate; try // 批量set字段值或切换数据集 finally DBGridEh1.EndUpdate; end;

第二层,按需关闭不用的实时功能。比如把OptionsEh里的dghAutoFitColWidths去掉,不要让控件在每次数据变化时重新算列宽;如果不需要实时合计,就把SumList.Active留到需要时再打开。第三层,从数据源头控制。大数据量场景优先用只读数据集,把过滤、排序放到数据库SQL层面完成,DBGridEh只负责展现,不要让它一边拉几万行一边内存里做筛选,那样再好的控件也扛不住。

6. 最后再分享几点实在话

折腾完这一圈,我最大的感受是:像DBGridEh这种老牌控件,能力早就不是问题,真正让人头疼的永远是版本匹配和安装细节。所以如果你是刚接手一个老项目,第一件事别急着写代码,把IDE版本、EhLib版本、数据库驱动版本和编译平台四个维度列清楚,再动手。Xe8这个节点,对很多老项目来说确实是性价比很高的停留点,往前够得着新系统,往后兼容老代码,第三控件生态也成熟,值得认真评估一次升级。

最后再分享一个小技巧:EhLib自带Demos目录里有大量示例工程,很多“这个功能怎么做”的问题,直接去Demos里搜关键词比翻文档快得多。哪怕你不太会英文,照着Demo改属性也能八九不离十。希望这篇稿子能帮你少踩几个坑,把更多的精力放在真正的业务逻辑上。

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

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

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

立即咨询