第二十章 开发Delphi对象式数据管理功能(二)

TResourceStream对象是另一类MemoryStream对象,它提供对Windows 应用程序资源的访问,因此称它为资源流。TResourceSream也是从TCustomMemoryStream 继承的。因此在TCustomMemoryStream对象的基础上,定义了与指定资源模块或资源文件建立连接的构造方法,并且还覆盖了Write,以实现向资源文件中写数据。

下面介绍TResourceStream的实现

  1. 私有域

  TResourceStream没有定义新的属性,但它在private部分定义了两个数据域HResInfoHGlobol和一个私有方法Initialize,它们的定义如下:

 

TResourceStream = class(TCustomMemoryStream)

private

HResInfo: HRSRC;

HGlobal: THandle;

procedure Initialize(Instance: THandle; Name, ResType: PChar);

end;

 

  HRSRC是描述Windows资源信息的结构句柄。HGlobal变量代表资源所在模块的句柄。如果操作的是应用程序资源,HGlohal就代表EXE程序的句柄;如果是动态链接库(DLL),则HGlobal代表动态链接库的句柄。TResourceStream对象使用这两上变量访问应用程序或动态链接库中的资源。

  Initialize方法是TResourceStream对象内部使用的。它的构造方法CreateCreateFromID都是调用Initialize方法完成对TResourceStream的初始化。它的实现如下:

 

procedure TResourceStream.Initialize(Instance: THandle; Name,ResType: PChar);

 

procedure Error;

begin

raise EResNotFound.Create(FmtLoadStr(SResNotFound, [Name]));

end;

 

begin

HResInfo := FindResource(Instance, Name, ResType);

if HResInfo = 0 then Error;

HGlobal := LoadResource(Instance, HResInfo);

if HGlobal = 0 then Error;

SetPointer(LockResource(HGlobal), SizeOfResource(Instance, HResInfo));

end;

 

 该方法实现中,首先调用Windows函数FoundResource得到由参数Instance指定的模块中的名为Name和类型为ResType的资源,然后调用LoadResource将资源调用内存,并返回该资源在内存中的句柄,最后,将该资源复制到ResourceStream中。方法的Instance参数代表要调用的资源所在的模块句柄。模块可以是可执行文件,也可以是动态链接库。如果在读取资源时没在模块中发现要找的资源则产生异常事件。

  2. 构造方法CreateCreateFromID

  这两个方法在实现上没有大的不同。顾名思义,第一个方法是通过资源名构造TResourceStream; 第二个方法通过资源ID构造TResourceStream,而且在实现过程中,它们都调用了Initialize方法。下面是它们的实现:

 

constructor TResourceStream.Create(Instance: THandle; constResName: string;

ResType: PChar);

begin

inherited Create;

Initialize(Instance, PChar(ResName), ResType);

end;

 

constructor TResourceStream.CreateFromID(Instance: THandle; ResID: Integer;

ResType: PChar);

begin

inherited Create;

Initialize(Instance, PChar(ResID), ResType);

end;

 

  这两个方法中都有Instance参数,该参数值的含义在Insitialize中介绍过。

  3. Write方法

  TResourceStreamWrite方法只完成一件事,就产生这个异常事件,其实现如下:

 

function TResourceStream.Write(const Buffer; Count: Longint):Longint;

begin

raise EStreamError.CreateRes(SCantWriteResourceStreamError);

end;

 

  从方法实现中可以看到,TSourceStream对象是不允许写数据的。一旦往资源流中写数据将产生异常事件。

  4. 析构方法Destroy

  该方法产生给资源解锁,然后释放该资源,最后调用继承的Destroy方法释放ResourceStream。其实现如下:

 

destructor TResourceStream.Destroy;

begin

UnlockResource(HGlobal);

FreeResource(HResInfo);

inherited Destroy;

end;

 

  回顾Initialize方法,我们不难发现:

  ● ResourceStream没有额外地给资源重新分配内存,而是直接使用HGlobal句柄所指 的内存域

  ● ResourceStream中的资源在流的生存期,始终是Lock状态,因此要根据Windows 的内存使用规则合理安排ResourceStream的使用

  ● ResourceStream只是用于访问应用程序和动态链接库中的资源的

 

Classes在单元中提供了InternalReadComponentRes函数,该函

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值