公司动态
Delphi XE8下EhLib DBGridEh安装编译与迁移实战
简介面向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 ~ 2010EhLib 5.xDelphi XE ~ XE52011 ~ 2013EhLib 6.xDelphi XE5 ~ XE8 / 10 Seattle2014 ~ 2015EhLib 7.xDelphi XE8 ~ 10.2 Tokyo2016 ~ 2017EhLib 8.xDelphi 10.2 Tokyo2017EhLib 9.xDelphi 10.3 Rio2018 ~ 2019EhLib 10.xDelphi 10.4 Sydney2020EhLib 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 pathE2202 Required package xxx not found运行期包没先编译/安装先编译并安装运行期包再编译设计期包E2089 Invalid typecast / Incompatible types编译器版本和DCU不一致一定用对应Xe8版本的dproj重新编译不要复用旧DCUAlready contains package旧版本EhLib残留Component Install Packages里移除旧包重启IDECould 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改属性也能八九不离十。希望这篇稿子能帮你少踩几个坑把更多的精力放在真正的业务逻辑上。本文还有配套的精品资源点击获取