Stream对象的WriteComponent方法声明是这样的
procedure WriteComponent(Instance: Tcomponent)
WriteComponent创建一个Writer对象并调用Writer的WriteRootComponent方法将Instance及其拥有的对象写入流
WriteComponentRes方法
声明
WriteComponentRes(const ResName: String; Instance: TComponent)
WriteComponentRes方法首先往流中写入标准Windows 资源文件头然后将Instance指定的部件写入流中要读由WriteComponentRes写入的部件必须调用ReadComponentRes方法
WriteComponentRes使用ResName传入的字符串作为资源文件头的资源名然后调用WriteComponent方法将Instance和它拥有的部件写入流
WriteDescendant方法
声明
procedure WriteDescendant(Instance Ancestor: TComponent)
Stream对象的WriteDescendant方法创建一个Writer对象然后调入该对象的WriteDescendant方法将Instance部件写入流中Instance可以是从Ancestor部件继承的窗体也可以是在从祖先窗体中继承的窗体中相应于祖先窗体中Ancestor部件的部件
WriteDescendantRes方法
声明
procedure WriteDescendantRes(const ResName: String;Instance
Ancestor: TComponent)
WriteDescendantRes方法将Windows资源文件头写入流并使用ResName作用资源名然后调用WriteDescendant方法将Instance写入流
TStream的实现原理
TStream对象是Stream对象的基础类这是Stream对象的基础为了能在不同媒介上的存储数据对象后继的Stream对象主要是在Read和Write方法上做了改进因此了解TStream是掌握Stream对象管理的核心Borland公司虽然提供了Stream对象的接口说明文档但对于其实现和应用方法却没有提及笔者是从Borland Delphi Client/Server Suite 提供的源代码和部分例子程序中掌握了流式对象技术
下面就从TStream的属性和方法的实现开始
TStream属性的实现
前面介绍过TStream具有Position和Size两个属性作为抽象数据类型它抽象了在各种存储媒介中读写数据所需要经常访问的域那么它们是怎样实现的呢?
在自定义部件编写这一章中介绍过部件属性定义中的读写控制Position和Size也作了读写控制定义如下
property Position: Longint read GetPosition write SetPosition;
property Size: Longint read GetSize;
由上可知Position是可读写属性而Size是只读的
Position属性的实现就体现在GetPosition和SetPosition当在程序运行过程中任何读取Position的值和给Position赋值的操作都会自动触发私有方法GetPosition和SetPosition两个方法的声明如下
function TStreamGetPosition: Longint;
begin
Result := Seek( )
end;
procedure TStreamSetPosition(Pos: Longint)
begin
Seek(Pos )
end;
在设置位置时Delphi编译机制会自动将Position传为Pos
前面介绍过Seek的使用方法第一参数是移动偏移量第二个参数是移动的起点返回值是移动后的指针位置
Size属性的实现只有读控制完全屏蔽了写操作读控制方法GetSize实现如下
function TStreamGetSize: Longint;
var
Pos: Longint;
begin
Pos := Seek( )
Result := Seek( )
Seek(Pos )
end;
TStream方法的实现
⑴ CopyFrom方法
CopyFrom是Stream对象中很有用的方法它用于在不同存储媒介中拷贝数据例如内存与外部文件之间内存与数据库字段之间等它简化了许多内存分配文件打开和读写等的细节将所有拷贝操作都统一到Stream对象上
前面曾介绍CopyFrom方法带Source和Count两个参数并返回长整型该方法将Count个字节的内容从Source拷贝到当前流中如果Count值为则拷贝所有数据
function TStreamCopyFrom(Source: TStream; Count: Longint) Longint;
const
MaxBufSize = $F;
var
BufSize N: Integer;
Buffer: PChar;
begin
if Count = then
begin
SourcePosition := ;
CouNG=ZHCN>资源文件中的部件时调用通常程序员不需自己调用如果读取的不是资源文件ReadResHeader将触发异常事件
procedure TStreamReadResHeader;
var
ReadCount: Longint;
Header: array[] of Char;
begin
FillChar(Header SizeOf(Header) )
ReadCount := Read(Header SizeOf(Header) )
if (Byte((@Header[])^) = $FF) and (Word((@Header[])^) = ) then
Seek(StrLen(Header + ) + ReadCount )
else
raise EInvalidImageCreateRes(SInvalidImage)
end;
ReadComponentRes在Windows资源文件中读取部件为了判断是否是资源文件它首先调用ReadResHeader方法然后调用ReadComponent方法读取Instance指定的部件下面是它的实现
[] [] [] [] []