Delphi7 从资源文件中载入GDI+对象
GDI+的Image及派生类中涉及到IStream流,在Delphi和C++Builder中广泛使用的TStream不能直接作为参数进行传递,VCL提供了一个TStreamAdapter类,用于把VCL流TStream转换为IStream。TStreamAdapter的构造过程原型如下:
constructor Create(Stream: TStream; Ownership: TStreamOwnership = soReference);
其中的TStreamOwnership枚举类型有2个值:soReference和,如果是soOwned,TStream对象由TStreamAdapter释放,否则由用户自己处理。请看下面的用流建立Image的Delphi代码:
var
Stream: TMemoryStream;
Adapter: TStreamAdapter;
Image: TGpImage;
begin
Stream := TMemoryStream.Create;
Stream.LoadFromFile('Test.jpg');
Adapter := TStreamAdapter.Create(Stream, soOwned);
Image := TGpImage.Create(Adapter);
try
.....
finally
Image.Free;
end;
end;
代码中,首先建立一个内存流,并从磁盘中装入一个图像文件,然后用TStreamAdapter将这个流封装起来,转换为IStream,供建立TGpImage使用。注意,我在建立TStreamAdapter对象时使用了soOwned,这样,由Adapter负责释放Stream,否则,必须在Image.Free后面Stream.Free。但是TStreamAdapter对象Adapter为什么没有释放代码呢?因为TStreamAdapter是个接口实现类,作为IStream传递给TGpImage.Create后,由系统自动跟踪释放,如果我们将它Free,会引起错误,如果非要显式释放它,必须用var I: IStream; I := Adapter; I := nil;的方法释放,而且必须在Image.Free之前,因为在Image.Free的同时,Adapter也随着IStream一起被释放掉了。
上面的代码在Delphi7 调试状态下会出现错误,在网上找了个C的代码,现在改为Pascal的,在个人机子上调试稳定:
function LoadGPImageFormRes(aHMoudle: DWORD; ResName, ResType: string):
TGPImage;
var
HRes: HRSRC;
sResName: string;
sResType: string;
Len: DWORD;
lpRsrc: PByte;
m_hMem: HGLOBAL;
pMem: PByte;
pstm: IStream;
begin
Result := nil;
sResName := ResName;
sResType := ResType;
HRes := FindResource(HInstance, PChar(sResName), PChar(sResType));
if HRes <> 0 then
begin
Len := SizeofResource(HInstance, HRes);
lpRsrc := PByte(LoadResource(HInstance, HRes));
try
if lpRsrc <> nil then
begin
m_hMem := GlobalAlloc(GMEM_FIXED, Len);
pMem := Pbyte(GlobalLock(m_hMem));
CopyMemory(pMem, lpRsrc, Len);
CreateStreamOnHGlobal(m_hMem, False, pstm);
Result := TGPImage.Create(pstm);
GlobalUnlock(m_hMem);
pstm := nil;
FreeResource(Dword(lpRsrc));
end;
except
if Assigned(Result) then
begin
FreeAndNil(Result);
end;
end;
end;
end;
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
· 现代计算机视觉入门之:什么是图片特征编码
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· Spring AI + Ollama 实现 deepseek-r1 的API服务和调用
· 数据库服务器 SQL Server 版本升级公告
· C#/.NET/.NET Core技术前沿周刊 | 第 23 期(2025年1.20-1.26)
· 程序员常用高效实用工具推荐,办公效率提升利器!
2007-10-12 3DES Source Code