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;

原文地址:https://www.cnblogs.com/MaxWoods/p/1848479.html