简介:面向 Delphi 12.3 开发者的 Ehlib 控件资源包,内容覆盖常用网格、编辑框、按钮等增强型界面组件,能帮助桌面应用开发者快速集成高级表格与数据处理功能,适合中高级 Delphi 程序员在项目研发或控件学习时使用。压缩包共含 2000 个文件,其中 470 个 dfm 窗体文件负责界面布局,469 个 pas 单元源码提供核心逻辑,245 个 res 资源文件保存图标与配置,另有 189 个 dproj 和 170 个 dpk 工程/包文件,支持在 RAD Studio 中直接打开编译,同时包含 chm 帮助文档、示例工程及少量数据库文件,覆盖从设计到发布的完整链路。整体仅 32.7MB,体积小巧但结构清晰,便于移植和快速集成。当前已有 60 人学习下载。资源内含 Ehlib 组件源码、窗体定义、可编译工程、官方 chm 帮助及配套示例;预览中还能看到教程素材与图标资源,对照帮助与示例代码,可快速掌握属性配置、事件处理与界面扩展方法,减少自行摸索时间,对需要提升 Delphi 开发效率的用户尤为实用。
1. 一个RAR包,解决Delphi 12.3数据库表格的最后一公里
拿到“Delphi 12.3控件之Ehlib 111015.rar”这个包,先说结论:这是一套为Delphi 12.3准备的第三方VCL控件库,核心价值是接管数据表格的展示、编辑、统计、打印导出。用Delphi原生TDBGrid做数据管理界面,免不了被列宽冻结、单元格合并、底部统计行、导出Excel、打印预览这些需求反复折腾,而Ehlib就是用来接手这些工作的。适合的人很明确:正在用Delphi 12.3开发或维护桌面数据库应用、又被表格交互细节逼疯的开发者。这篇文章从解压讲到验证,把安装步骤、必调参数和踩坑记录全部按可复现的方式写出来,新手能照做,熟手能直接查排错。
2. 先搞清楚Ehlib 111015这套控件能带来什么
2.1 原生TDBGrid的四个短板,正好是Ehlib的强项
第一个短板是单元格合并。原生TDBGrid只支持列向重复值显示,不支持真正的跨行合并。做部门汇总报表、按月份分组的统计列表时,需要把相同值的行合并成一个单元格。TDBGridEh通过OptionsEh里的dghMergeAdjacentCellsEh选项,结合列属性里的MergeCells配置,可以在数据呈现层做动态合并。需要注意的是,它合并的是“显示”,不是数据源里的真实行,排序和统计仍按原始行进行。如果两个相邻行值恰好相同但你想强制它们不合并,需要在列的OnGetMergeParams事件里拦截并返回不合并标志,这个事件是Ehlib列合并功能里最容易被人忽略的入口。
第二个短板是底部统计行。原生TDBGrid没有汇总行,要显示合计和平均值,只能在数据集SQL里写汇总子查询,数据变化了还要重新查询。Ehlib提供了一个TDBSumList组件,单独监听数据集,增量维护统计值,然后把统计结果显示到网格FooterRowCount设置的Footer行上。这样统计不随SQL重查,大数据集下性能比每次执行SUM聚合好得多。实际业务里订单列表要同时显示金额合计、数量合计、记录条数,TDBSumList一个组件就能同时维护三个统计值,不用为每个字段写一条汇总SQL。
第三个短板是导出与打印。用户一句“把这个表导出来”,在原生方案里得自己接第三方Excel库或者离线报表组件去拼数据。Ehlib给网格直接提供了SaveToXLS、SaveToRTF、SaveToHTML、SaveToTXT四类导出方法,还内置了PrintPreview打印预览界面,底层通过TDBPrinter渲染。它不依赖客户机安装Office,导出的是Excel能打开的HTML/XML格式。优点是部署简单,缺点是格式控制力度有限,一旦客户要求“每列宽度、页眉页脚、合并单元格都要和界面完全一致”,光靠Ehlib默认导出满足不了,还得配合自定义样式或二次处理。
第四个短板是显示格式。金额千分位、日期显示格式、超长文本截断加省略号、单元格里画进度条、下拉日历、下拉选择框,这些在原生TDBGrid里要么写OnGetText事件手工处理,要么另外放控件叠加。Ehlib把这部分做成了列级属性,直接在列编辑器里配置,不用写事件代码。以金额字段为例,设置列的DisplayFormat为“#,##0.00”即可实现千分位,放在原生TDBGrid里得写一整个事件去格式化,维护成本不在一个数量级。
这四个短板覆盖了数据管理界面里八成以上的列表增强需求。如果只是简单展示几条只读数据,原生TDBGrid本来也够用,Ehlib的价值在于让开发者不用反复造轮子。换句话说:你手上有真实业务系统,列表不是“展示”而是“操作台”,才需要装它。
2.2 版本号为什么必须对齐:Delphi 12.3和Ehlib 111015的关系
RAR包名字里“Delphi 12.3”和“Ehlib 111015”两个信息缺一不可,它们分别约束了环境版本和控件版本。
先说环境版本。VCL控件最终要以DCU、BPL形式进入IDE。Delphi每个大版本编译器生成的DCU文件格式不互通,你在某个旧版Delphi下编译出来的Ehlib DCU,拿到Delphi 12.3工程里引用,编译时会报“Unit not compiled with this version of Delphi”一类的错。RAR包命名为Delphi 12.3专用,就是为了避免这种错配。安装时务必确认打开编译的DPK工程是对应版本,包内如果带预编译BPL也要按版本目录区分,不要混着用。
再说控件版本。Ehlib 111015表示这套控件源码发布时的一个版本号或构建编号。Ehlib版本演进不以IDE版本为单位,而是独立发版,所以会出现“Ehlib 111015支持Delphi 12.3”这种组合。这个版本号里具体有哪些功能变化,以包内自带的历史说明文档为准。我见过不止一次有人在网上找Ehlib,下载后不读说明直接装,结果把旧版的DCU覆盖到新版目录,最后报表功能全部乱套,这种低级翻车完全可以靠读说明文档避免。
安装前最好建一个干净的独立目录,把Ehlib解压后单独放着,不要把DCU和BPL散落到IDE默认目录里去,方便后续切换控件版本时管理。这也是我给所有用第三方控件的人的第一条忠告:所有VCL控件最好都独立管理目录,不要一股脑丢进Delphi的Library默认路径里。
2.3 安装开销和选型判断:到底要不要装
Ehlib的授权方式以包内说明文档为准,安装使用前一定要确认拿到的是合规授权,这一点不要含糊。从工程开销上看,装Ehlib要注意三点。第一,IDE的组件面板会多一组控件图标,包加载时间略微增加。第二,发布程序时要带上对应的运行时BPL。第三,编译时间和项目产出体积增加。如果项目只是CRUD界面,列表不带统计、不导出、不合并,那原生TDBGrid配少量代码完全够用,没必要引入第三方依赖;反过来,你的系统里存在报表型列表、明细账、订单明细这类界面,Ehlib的投入产出比就非常高。
我的判断方法很简单:在纸上列三项——是否需要单元格合并、是否需要底部统计或合计、是否需要一键导出Excel或打印预览。命中两项以上,就装。只命中一项,可以临时用原生网格加事件代码兜底,减少一个外部依赖。这样能避免装完又卸载的反复折腾,也在团队协作时减少“为什么我这个环境跑不起来”的沟通成本。
3. 在Delphi 12.3里装好Ehlib 111015:从解压到出图标
3.1 解压前的三件事:退出IDE、整理目录、读说明
安装任何VCL包之前,第一条血泪经验:先退出Delphi 12.3。不是关掉工程就算完,而是把IDE进程完全退出。因为IDE运行时锁定了正在使用的BPL文件,直接安装很可能报“文件被占用”。这一步省事的做法是任务管理器里确认没有残余的IDE进程,再继续操作。
注意:不要在IDE运行状态下直接覆盖或删除旧的BPL文件,这会导致安装进度走到一半时IDE失去响应。
第二件事,把RAR包解压到纯英文无空格目录。我通常放在类似D:\Components\Ehlib111015\的位置。不要解压到桌面,也不要放中文路径,Ehlib源码编译时对路径里的中文支持不算好,一旦报“无法定位文件”这类错误,排查起来非常消耗时间。保证整个目录结构干净,后续编译遇到问题更容易定位是路径问题还是源码问题。
第三件事,解压后先读包内的说明文档,确认两个信息:一是这个包是否明确支持Delphi 12.3,二是包里有没有预编译的BPL、DCP文件,还是只有源码。如果说明文档缺失,直接打开包内目录,看是否存在类似EhlibD12.dpk、EhlibD10.dpk这类带版本后缀的DPK文件。有对应版本后缀的DPK,说明这个包确实适配了该IDE版本;只有通用名称没有版本后缀,就要按源码编译并注意路径匹配。这一步可以提前过滤掉把旧Ehlib改名冒充新包的情况,避免无效安装。
3.2 在IDE里编译运行包并安装设计包:详细操作与命令
Ehlib常规安装分两步:先编译运行时包,再安装设计时包。运行时包是核心代码,发布时也要分发;设计时包只存在于IDE环境,作用是让控件出现在面板上。
| 包类型 | 文件后缀 | 职责 | 发布程序时 |
|---|---|---|---|
| 运行时包 | .bpl /.dcp | 提供核心单元实现,程序运行依赖 | 需要随exe一起分发 |
| 设计时包 | .bpl | 在IDE中注册组件面板 | 不需要分发到客户机 |
第一步,启动Delphi 12.3,用File > Open打开包内对应版本的DPK工程文件,例如EhlibD12.dpk。操作说明如下:
// 步骤1:在Project Manager中,右键EhlibD12工程节点 // 先选择Build,等编译日志输出成功信息 // 步骤2:Build成功后,再次右键同一个节点,选择Install // 步骤3:如果IDE提示Package xxx already installed, // 先在Component > Install Packages里找到旧包并Remove, // 再重新执行Install逻辑说明:Build负责把源码编译成DCU和BPL,Install负责把BPL注册到IDE包列表,注册之后组件面板才出现Ehlib分类。二者缺一不可,只Build不Install,代码能编译但面板无控件;只Install不Build,IDE会提示包文件不存在。步骤3是给升级场景用的,旧包不先移除,会出现同名包重复注册,轻则面板控件重复,重则IDE启动失败。
参数说明:Project Manager里还有Release和Debug两种配置,建议使用Release配置编译,保证发布时加载的是同一套编译产物。编译过程中如果IDE报找不到某些单元文件,打开Tools > Options > IDE > Library,在库搜索路径里添加Ehlib源码目录及其Common子目录,然后重新Build。
备用命令行方式编译:
msbuild EhlibD12.dproj /t:Build /p:Config=Release /p:Platform=Win32 /maxcpucount:4逻辑说明:msbuild是编译Delphi工程文件的标准命令,/t:Build指定构建目标,/p:Config=Release指定使用Release配置,/p:Platform=Win32指定目标平台为32位,/maxcpucount:4是并行编译参数,多核机器上能明显提速。如果你的发布目标是64位,还需要再执行一次Platform=Win64,两次编译会生成不同架构的BPL。设计期IDE加载32位BPL,运行发布按客户机架构选择对应的BPL分发。
编译完成后,Component > Install Packages里应该能看到Ehlib相关条目。组件面板会出现Ehlib分类,里面至少包含TDBGridEh、TDBEditEh、TDBComboBoxEh、TDBCheckBoxEh、TDBMemoEh、TDBDateTimePickerEh、TDBNumberEditEh、TDBSumList、TDBPrinter等控件。这里有一个值得注意的边界:如果包内的DPK项目还带了可选组件,比如MemTableEh等,安装时注意不要一次性全装上,避免不需要的包拖慢IDE启动速度。
3.3 安装完的路径登记与IDE重启验证
安装完成只是第一步,还要确保下次启动IDE时Ehlib能正常加载。打开Component > Install Packages对话框,确认对话框里该条目处于勾选状态。然后把Ehlib编译输出BPL所在目录加入系统PATH,同时将该目录加入IDE的库搜索路径。这样做的原因是IDE启动时会按注册的包路径和BPL搜索路径查找文件,路径不在查找范围,包就加载不上,表现为“控件面板消失”。
完成上述步骤后,建议直接重启一次IDE,再新建一个VCL工程,确认面板上Ehlib分类存在。我习惯顺手拖一个TDBGridEh到窗体上,如果能正常放下来,说明设计时包也已生效。这一步花不了两分钟,但能把很多后续问题前置挡掉,比等到项目构建时才暴露要划算得多。
4. 装完怎么用:Ehlib 111015高频组件的最小配置
4.1 TDBGridEh最小可用配置
TDBGridEh是Ehlib里使用频率最高的组件,配置从拖到窗体上开始,按这四步走:连接DataSource;在列编辑器里配置字段列;设置列宽和标题;按需求打开OptionsEh。不要把网格的DataSource长期悬空,否则很多属性设置无效果,界面设计期也看不出差异。
// 最小配置:网格已拖放到Form,数据源组件为DataSource1 DBGridEh1.DataSource := DataSource1; // 允许自动调整行高,以便完整显示多行文本 DBGridEh1.OptionsEh := DBGridEh1.OptionsEh + [dghAutoFitRowHeight]; // 双击列头自动优化列宽 DBGridEh1.OptionsEh := DBGridEh1.OptionsEh + [dghDblClickOptimizeColWidth]; // 单元格合并开关:相邻行同列值相同时自动合并显示 DBGridEh1.OptionsEh := DBGridEh1.OptionsEh + [dghMergeAdjacentCellsEh]; // 行指示器显示当前行图标 DBGridEh1.IndicatorOptions := [gioShowRowIndicatorEh];逻辑说明:OptionsEh是集合属性,用“+[选项]”往集合里追加,不要整体赋值成只含一个选项,否则会丢失默认行为。dghMergeAdjacentCellsEh启用的是显示层合并,数据源中的行数不变,排序和统计依然按原行处理。
参数说明:dghAutoFitRowHeight控制行高自适应内容,适合备注、地址这类长文本字段;如果列表里没有长文本,这个选项可以不加,省去绘制开销。dghDblClickOptimizeColWidth会在用户双击列头时按内容最大宽度自动调整列宽,体验上接近Excel列宽自适应。IndicatorOptions里gioShowRowIndicatorEh会显示当前行左侧的指示图标,编辑、插入、删除状态都有不同图形,多行编辑界面更好用。
| OptionsEh选项 | 作用 | 适用场景 |
|---|---|---|
| dghAutoFitRowHeight | 行高自适应内容,自动换行显示 | 备注、长文本字段 |
| dghMergeAdjacentCellsEh | 相邻行同值单元格自动合并 | 报表、分组统计列表 |
| dghDblClickOptimizeColWidth | 双击列头自动最适配列宽 | 常规管理类列表 |
4.2 用TDBSumList做底部统计行
统计行是进销存界面里最常用的一类功能。配置分为三步:放一个TDBSumList;把TDBSumList的DataSource指向与网格相同的DataSource;在网格的FooterRowCount设为1,并在列编辑器的Footer属性里指定统计类型和字段。
DBGridEh1.FooterRowCount := 1; SumListEh1.DataSource := DataSource1; SumListEh1.VirtualMode := False; // 在列编辑器中设置Footer属性: // 选中某列,Footer.ValueType := fvtSum; // Footer.FieldName := 'TotalAmount'; // 数据改变后刷新统计 SumListEh1.Refresh;逻辑说明:TDBSumList不是重新查询数据集,它动态监听数据集的记录变化,在滚动、编辑、增删行时增量更新统计值,所以当数据有变化时网格能即时反映。VirtualMode设为False时,由SumList自动统计指定字段;设为True时则需要自己处理OnSumListRefresh事件,按需填充每列数值,适合统计口径复杂的界面。
参数说明:fvtSum是合计,fvtAvg是平均值,fvtCount是计数,fvtMax和fvtMin分别是最大值和最小值。每种类型都要求Footer.FieldName指向有效的数值字段或可比较字段,否则统计行显示为空或0。数据集处于过滤状态或使用了分组时,务必在数据集事件里调用一次SumListEh1.Refresh,否则统计数据会和界面显示不一致,这个坑很容易被误判成“统计组件坏了”。
4.3 一键导出Excel和打印预览
客户要求“把列表导成Excel”,适合用Ehlib自带的导出方法,好处是不依赖客户机安装Office,在终端机上只需有可执行程序即可。最小调用代码:
// 导出到xls格式文件 DBGridEh1.SaveToXLS('D:\Report\order_list.xls'); // 保留列宽信息的导出 DBGridEh1.SaveToXLS('D:\Report\order_list_width.xls', True); // 调起内置打印预览 DBGridEh1.PrintPreview;逻辑说明:SaveToXLS的底层是生成Excel可打开的HTML文件,因此文件后缀和编码要注意。第一行代码用默认参数导出,文件体积小但单元格列宽按内容默认分配;第二行传入True后,导出会尽量按网格列宽信息生成表格,更接近界面效果。PrintPreview调用Ehlib自己的预览窗体,用户可以缩放比例、调整边距、跳页后再走打印机输出。
参数说明:SaveToXLS的第二个参数是布尔类型,表示是否按列宽格式化输出。PrintPreview没有必填参数,但预览窗体的行为受全局打印设置影响,例如打印机名称、纸张方向,需要提前通过Printer组件设置。如果客户需要导出后数据还能继续编辑,建议用SaveToXLS导出而不是另存为CSV,CSV对类型和列宽保留更差,中文编码也容易出问题。
| 导出格式 | 调用方法 | 特点 |
|---|---|---|
| XLS | SaveToXLS | Excel可直接打开,支持列宽保留 |
| RTF | SaveToRTF | 适合Word进一步排版 |
| HTML | SaveToHTML | 适合网页展示和跨平台查看 |
| TXT | SaveToTXT | 纯文本,带分隔符,兼容性最强 |
5. Ehlib 111015安装与使用避坑记录:现象、原因、解决
5.1 重启IDE后控件面板消失
现象:安装时IDE提示包安装成功,组件面板也看到了Ehlib分类,但重启IDE后分类消失,新建窗体时找不到TDBGridEh等控件。
原因:最常见是BPL文件所在目录没有被IDE持久记录,IDE重启后按注册信息扫描不到该目录下的BPL。杀毒软件在IDE退出后隔离BPL文件也不算少见。另一个常见原因是解压后的Ehlib目录被移动了,注册表里记录的旧路径已经失效。
解决:先打开Component > Install Packages,检查包是否还在列表中。如果包在但面板没有控件,把BPL所在目录加入系统PATH并加入IDE的库搜索路径,然后重启IDE。如果包不在列表中,重新打开DPK再Build并Install一次,并把BPL输出目录固定到一个稳定位置,避免之后再移动目录。
5.2 编译工程时报找不到Unit或版本不匹配
现象:编译工程时报“Unit xxx not found”,或者提示DCU版本与当前编译器不一致。
原因:IDE库搜索路径中残留旧版Ehlib目录,编译器优先匹配了旧DCU,或者包本身不是为当前IDE版本编译的。很多情况下,机器上装过多个Delphi版本或者装过不同来源的Ehlib包,库搜索路径里同时存在多个Ehlib版本目录。
解决:打开Tools > Options > IDE > Library,在库搜索路径中删除所有旧Ehlib目录,只保留当前111015对应的源码目录,并清理工程目录下的DCU缓存文件。然后在Project Manager里对目标工程执行一次Clean,再重新Build。这一步Clean经常被忽略,但旧DCU不清除,编译结果受库路径改动影响很小,问题会反复出现。
提示:工程级Clean一定要做,只改库搜索路径不清理DCU,编译器可能直接命中旧缓存文件,排错白费力气。
5.3 导出Excel或打印预览时中文乱码
现象:网格内显示完全正常,导出XLS后用Excel打开中文变问号;打印预览时中文变成方框。
原因:导出XLS时默认按本地代码页生成,如果客户机的系统区域设置不同或者代码页不匹配,就会乱码。打印预览乱码则常与字体映射有关,Ehlib预览界面默认调用的字体缺少对应中文字形时,字符绘制成方框。
解决:先确认客户机系统区域设置,简体中文环境下保持ANSI或GBK即可;如果需要跨语言分发,导出后对文件做编码转换,把文本内容转成UTF-8,新版Excel也能识别。打印乱码的处理是把网格和预览窗体的默认字体统一设置成中文字体,比如宋体或微软雅黑,然后在Ehlib打印设置里指定该字体,一般即可解决。
5.4 安装包过程IDE崩溃或无响应
现象:在IDE里打开DPK执行Build时,IDE直接退出或长时间无响应。
原因:常见原因包括Ehlib源码目录处于只读状态,编译输出文件无法写入;杀毒软件实时扫描IDE编译过程;也有极端情况下是内存不足,多核并行编译占满资源导致IDE失去响应。
解决:先把Ehlib整个目录去掉只读属性,再以管理员身份运行IDE;暂时关闭杀毒软件对该目录和IDE临时目录的实时扫描。如果IDE内操作继续崩溃,退到命令行方式编译,用msbuild完成后再回到IDE安装BPL。命令行编译隔离了IDE交互,崩溃面更小,也更容易定位错误日志。
5.5 高DPI显示器下网格文字模糊
现象:在4K屏或150%缩放下,Ehlib网格文字显示发虚,单元格和列头边缘不清晰。
原因:Ehlib部分绘制逻辑未遵循新版IDE的高DPI缩放机制,系统对窗体做了位图拉伸,拉伸后再显示导致文字边缘模糊。
解决:在工程文件里开启高DPI支持,并在窗体创建后做一次网格刷新。推荐在DPR工程文件开头设置:
Application.HighDPIAware := True;再用以下代码在窗体显示后刷新网格:
procedure TForm1.FormShow(Sender: TObject); begin DBGridEh1.Refresh; end;逻辑说明:开启HighDPIAware后,系统不再对窗体做整体位图拉伸,文字按实际DPI重新布局,边缘会清晰很多。刷新网格是为了让列宽重新计算。参数说明:如果项目同时启用PerMonitorV2模式,不同显示器DPI不一致时,需要在窗口移动跨屏时额外处理,最好在窗体的ScalingChanged事件里再次调用网格Refresh,避免跨屏后文字变形。
6. 用十个检查点验证Ehlib 111015安装结果:主动收尾
安装完成后先别急着进入业务代码,花十分钟跑一个最小验证工程,比后面出了问题再回头排查省时间得多。新建一个VCL工程,摆一个TDBGridEh、一个TDBSumList、一个TButton、一个TDataSource,连上测试数据集,按下面的检查点逐一过:
| 检查点 | 操作 | 预期结果 |
|---|---|---|
| 1 | 查看组件面板Ehlib分类 | 图标完整无红色叹号 |
| 2 | 网格连接数据源并显示 | 数据正常显示,列可拖宽 |
| 3 | 点击列标题排序 | 排序箭头变化,排序生效 |
| 4 | 右键网格 | 排序、过滤、导出菜单可用 |
| 5 | 设置FooterRowCount=1并绑定SumList | 统计行显示正确数字 |
| 6 | 调用SaveToXLS导出 | 文件生成,Excel打开中文正常 |
| 7 | 调用PrintPreview | 预览窗体打开,翻页缩放正常 |
| 8 | 高DPI缩放窗体 | 文字不模糊、列宽对齐 |
| 9 | Release模式编译整个工程 | 编译无警告 |
| 10 | 复制EXE和BPL到无IDE机器 | 运行正常,功能完整 |
这十个检查点里,第5、6、7是Ehlib区别于原生网格的核心价值点,只要有一个不过,说明安装或环境配置有问题,回到第5章找对应条目,不要靠重装碰运气。
我个人的教训是:换Delphi大版本或换电脑后,一定要把这张检查单从头跑一遍。以前我从旧版本环境切到Delphi 12.3时,因为偷懒没有重新编译Ehlib包,统计行在某种数据分布下算出明显错误数字,查了一下午才定位到是旧DCU混用。那次之后,每次装完控件我都按这套检查单验证,包括BPL文件是否完整、导出文件在客户环境下能否打开、高DPI下是否正常。一个好的控件方案不是装上就行,而是要确认它在你的目标环境里真正可用。希望帮到你。
本文还有配套的精品资源,点击获取