简介:这份资源是适配 Delphi 2010 的 DSPack 2.34 组件包,面向使用 VCL 框架开发 Windows 桌面程序的 Delphi 开发者,尤其适合需要网络通信、多线程、数据库访问与串口操作的中级开发者。该版本已在真实项目中验证过兼容性,可减少在 Delphi 2010 Unicode 环境下调试组件时的踩坑成本。压缩包为 rar 格式,共 319 个文件,约 1.75MB,其中 95 个 pas 单元与 40 个 dpr 工程文件构成核心源码与示例,39 个 dfm 窗体文件、11 个 res 资源及 9 个 dcu 编译单元便于直接查看与复用,另有 dpk、dproj、groupproj 等工程组文件及 bat 注册脚本,方便按组件包方式安装导入。已有 329 人学习关注。读者可获得完整的组件源码、示例工程与安装脚本,参照示例快速把 TCP/UDP、串口、线程等组件拖入表单验证功能,并借助工程结构排查编译与注册问题。
1. 老项目复活:Delphi 2010 配 DSPack 2.34 的安装现场
上周帮一个做音视频采集的老项目做环境迁移,开发机从 XP 时代的 Delphi 7 换到 Delphi 2010,代码一编译,DirectShow9相关的单元全红。这不是个例——Delphi 2010 是 Unicode 化的分水岭版本,String从 AnsiString 变成 UnicodeString,而 DSPack 这类封装 DirectShow 的组件库,2.34 之前的版本在 2010 下基本是「能装上、编不过、跑起来还乱码」的三连翻车。DSPack 2.34 是少数明确适配 Delphi 2010 的版本,但它的安装包结构、包引用顺序、以及 DirectShow 基类的路径配置,坑比想象中密。这篇记录的是我在一台干净 Win7 32 位虚拟机上,从零把 DSPack 2.34 装进 Delphi 2010 并跑通摄像头预览的完整过程,适合手里有老采集/播放项目、需要在 2010 上续命的人照着走。
2. 装前把环境钉死:Delphi 2010 与 DSPack 2.34 的版本对位
2.1 为什么必须是 2.34 这个版本
DSPack 的版本号和 Delphi 的编译器版本是强绑定的。2.3.x 系列里,2.31 和 2.32 的包文件(.dpk)里写死的{$IFDEF VER210}分支不完整,在 Delphi 2010(编译器版本 21.0,条件符号VER210)下加载设计期包会报「Invalid package reference」。2.34 补上了 2010 的DirectShow9单元 Unicode 适配,并且把DSPack_D2010.dpk单独拆了出来。我一般会先确认手头这份是不是带D2010后缀的包文件,没有这个文件的基本可以判定不是 2.34 的 2010 适配版。
版本对位关系我整理成一张表,装之前先对一遍,比装到一半再回头查省事:
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| Delphi | 2010(编译器 21.0) | 条件符号VER210,Unicode 默认开启 |
| DSPack | 2.34 | 含DSPack_D2010.dpk设计期包 |
| DirectShow 基类 | 随 DSPack 附带 | 不要用系统里的旧DirectShow9.pas覆盖 |
| 操作系统 | Win7 32 位 / Win10 32 位兼容模式 | 64 位下注册 32 位包需注意路径 |
2.2 目录结构与安装前的清理动作
DSPack 2.34 解压后通常是DSPack根目录,下面分src(源码单元)、packages(各版本 dpk)、demos(示例)。安装前有两件事必须先做,否则后面注册包会失败。
第一,把之前装过的旧版 DSPack 从 IDE 里彻底摘掉。打开 Delphi 2010,Component→Install Packages,在列表里找所有名字带DSPack的项,全部 Remove,但不要勾选删除文件。第二,检查$(BDS)\lib和$(BDS)\Imports下有没有残留的DSPack*.dcu,有就删掉。这一步是血泪经验——旧 dcu 残留会让新包编译时链接到旧符号,报一堆莫名其妙的Unsatisfied forward or external declaration。
清理完,把 DSPack 2.34 解压到一个不含空格和中文的短路径,比如D:\DSPack234。Delphi 2010 的包编译对路径里的空格极其敏感,Program Files这种路径下注册包十有八九失败。
2.3 库路径的配置顺序
路径配置是这套环境里最容易写错的一环,顺序错了编译器会优先找到旧单元。打开Tools→Options→Environment Options→Delphi Options→Library,在Library path里按下面顺序追加:
# 注意顺序:src 在前,packages 在后,中间用分号隔开 D:\DSPack234\src\DSPack D:\DSPack234\src\DirectShow9 D:\DSPack234\packages\D2010逻辑说明:src\DSPack放的是DSPack.pas这类高层封装,src\DirectShow9是 DirectShow 的接口声明单元,两者必须都在搜索路径里,且DirectShow9要在DSPack之后被解析——因为DSPack.pas的uses里引用了DirectShow9。把packages\D2010也加进去,是为了让 IDE 在设计期能找到.dpk依赖的.dcp。参数上,路径末尾不要带反斜杠,Delphi 2010 对末尾反斜杠的处理有 bug,会拼出双反斜杠导致找不到文件。
提示:改完 Library path 后必须重启 IDE,路径缓存不会热更新,很多人改完直接编译发现没生效就是这个原因。
3. 编译与注册:DSPack_D2010.dpk 的安装步骤
3.1 先编运行期包再编设计期包
DSPack 的包分两层:运行期包(runtime)和设计期包(designtime)。运行期包提供实际代码,设计期包只负责把组件注册到工具箱。顺序不能反,先编设计期包会因为找不到运行期包的.dcp而报F1026 File not found: 'DSPack_D2010.dcp'。
打开D:\DSPack234\packages\D2010\DSPack_D2010.dpk,在 Project Manager 里右键 →Build。编译成功后,输出目录(默认和 dpk 同目录)会生成DSPack_D2010.bpl和.dcp。接着打开同目录下的DSPack_D2010_D.dpk(设计期包),同样 Build。两个包都 Build 通过,才算编译环节过关。
如果 Build 报错集中在DirectShow9.pas的接口方法签名上,八成是路径里混进了系统自带的旧版DirectShow9.pas。回到 2.3 节,确认src\DirectShow9排在搜索路径最前,并且没有其他目录也放了同名单元。
3.2 注册设计期包到 IDE
编译通过后,Component→Install Packages→Add,选中刚生成的DSPack_D2010_D.bpl。注册成功的标志是工具箱里出现DSPack标签页,下面有FilterGraph、VideoWindow、SampleGrabber等组件。如果 Add 时报「Cannot load package」,先看是不是 64 位 IDE 误加载了 32 位包——Delphi 2010 只有 32 位 IDE,这个错一般指向依赖的rtl140.bpl版本不匹配,检查是否装过其他版本的 Delphi 补丁包污染了$(BDS)\bin。
注册完,新建一个 VCL Forms Application,从工具箱拖一个FilterGraph和一个VideoWindow到窗体上,FilterGraph的Active设 False,VideoWindow的FilterGraph指向那个FilterGraph组件。这一步只是验证组件能实例化,真正的运行验证放到最后一章。
3.3 一个最小可编译的引用示例
组件拖上去能编译,不代表单元引用没问题。我习惯再写一个纯代码的最小单元,确认DSPack和DirectShow9的符号都能解析:
unit UnitDSPackSmoke; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, DSPack, DirectShow9; // 两个单元都要能解析 type TFormSmoke = class(TForm) FilterGraph1: TFilterGraph; VideoWindow1: TVideoWindow; private { Private declarations } public { Public declarations } end; var FormSmoke: TFormSmoke; implementation {$R *.dfm} end.逻辑说明:uses里同时列DSPack和DirectShow9,是为了验证 2.3 节配的两条路径都生效。如果只uses DSPack能过、加上DirectShow9就报重复声明,说明路径里有两个DirectShow9.pas,得回去清理。参数上,TFilterGraph和TVideoWindow是 DSPack 最基础的两个类,能实例化就说明包注册和单元解析都通了。
4. 避坑与排查:DSPack 2.34 在 2010 下的五条翻车记录
4.1 现象:编译报「UnicodeString 与 AnsiString 不兼容」
原因:DSPack 2.34 虽然适配了 2010,但部分 demo 和旧代码里仍有PChar隐式转换。Delphi 2010 默认String是 Unicode,PChar是PWideChar,旧代码里PAnsiChar的用法会触发W1057警告甚至E2010错误。
解决:在项目选项Compiler里把W1057设为 warning 而非 error,同时把旧代码里的PChar(...)显式改成PAnsiChar(...)或PWideChar(...)。我一般会全局搜一遍PChar(,逐个确认上下文再改,不要图省事直接关掉 Unicode。
4.2 现象:注册包时提示「Package DSPack_D2010_D.bpl is already loaded」
原因:之前 Remove 包时只从列表移除,.bpl还在 IDE 的已加载缓存里,或者$(BDS)\bin下有同名旧 bpl。
解决:关掉 IDE,删掉$(BDS)\bin下所有DSPack*.bpl,再重开 IDE 重新 Add。如果还报,用Process Explorer看bds.exe是否还持有旧 bpl 句柄,重启机器最干净。
4.3 现象:运行时FilterGraph.Active := True抛「Class not registered」
原因:DirectShow 的 COM 组件没注册,或者系统是精简版 Windows 缺了quartz.dll的注册项。这在某些 Ghost 系统上很常见。
解决:以管理员身份跑regsvr32 quartz.dll,路径在C:\Windows\System32。如果提示找不到模块,说明系统缺 DirectShow 运行库,装一个完整的 DirectX 9.0c 运行库再试。注意 32 位系统只注册 32 位 dll,别去SysWOW64下折腾。
4.4 现象:摄像头预览黑屏但无报错
原因:VideoWindow的FilterGraph属性没指向FilterGraph组件,或者FilterGraph的Active在VideoWindow绑定前就设了 True。DSPack 的绑定顺序有讲究。
解决:代码里严格按「先VideoWindow.FilterGraph := FilterGraph1,再FilterGraph1.Active := True」的顺序。设计期拖组件时,属性面板里VideoWindow.FilterGraph要手动选,默认是空的,这点和很多人的直觉相反。
4.5 现象:编译通过但链接报「Unsatisfied forward or external declaration」
原因:旧 dcu 残留,或者Library path里同时存在两个版本的DSPack.pas。Delphi 2010 的增量编译对 dcu 时间戳敏感,旧 dcu 比新源码新时会跳过重编。
解决:Project→Clean清掉项目 dcu,再手动删$(BDS)\lib下的DSPack*.dcu,最后Build全量重编。我一般会在装完包后强制走一遍 Clean + Build,不信任增量编译。
5. 装完怎么验证:跑通一个摄像头预览再收工
验证这套环境是否真的可用,光看组件能拖上窗体不够,得让 DirectShow 的滤镜链真正跑起来。我用的验证方法是:新建一个 VCL Forms Application,窗体上放FilterGraph1、VideoWindow1、一个Button,按钮点击时枚举摄像头并启动预览。核心代码如下:
procedure TFormPreview.btnStartClick(Sender: TObject); var I: Integer; DevEnum: TSysDevEnum; begin // 先绑定,再激活,顺序不能反 VideoWindow1.FilterGraph := FilterGraph1; DevEnum := TSysDevEnum.Create(CLSID_VideoInputDeviceCategory); try if DevEnum.CountFilters = 0 then begin ShowMessage('未检测到视频采集设备'); Exit; end; // 取第一个设备,实际项目里应做成下拉选择 FilterGraph1.ClearGraph; FilterGraph1.Active := True; FilterGraph1.BaseFilter.Moniker := DevEnum.GetMoniker(0); FilterGraph1.Active := True; VideoWindow1.Width := 640; VideoWindow1.Height := 480; FilterGraph1.Play; finally DevEnum.Free; end; end;逻辑说明:TSysDevEnum是 DSPack 对系统设备枚举器的封装,CLSID_VideoInputDeviceCategory指定枚举视频输入设备。GetMoniker(0)取第一个设备的 moniker,赋给BaseFilter后Play启动预览。参数上,VideoWindow1的宽高设 640×480 是兼容性最好的默认值,部分摄像头不支持 1080p 直接预览会黑屏。ClearGraph在重复点击时防止滤镜链叠加。
验证通过的标志有三个:窗体上出现实时画面、任务管理器里bds.exe的 GDI 对象数稳定不暴涨、关闭窗体时无Access Violation。第三个尤其重要——DSPack 的FilterGraph如果没在FormClose里Active := False就释放,退出时必崩。我一般会在FormDestroy里补一句FilterGraph1.Active := False兜底。
从那以后我每次装完 DSPack,都不信「组件拖上去能编译」这种表面通过,一定跑一遍摄像头预览加关闭窗体,确认滤镜链完整释放才算收工。这套 2010 加 2.34 的组合虽然老,但把版本对位、路径顺序、绑定顺序这三件事钉死,跑起来是稳的。希望帮到你。
本文还有配套的精品资源,点击获取