OnSetName事件
声明
property OnSetName: TSetNameEvent;
OnSetName事件发生在Read对象设置部件的Name属性前OnSetName事件处理过程的var参数Name参数是一个var参数因此事件处理过程再将Name赋给部件前可以修改Name的值这对于想过滤窗体中部件的名字是很有帮助的
下面的OnSetName事件处理过程命名了名字中包含Button的部件并用PushButton替代
procedure TFormReaderSetName(Reader: TReader; Component: TComponent;
var Name: string)
var
ButtonPos: Integer;
begin
ButtonPos := Pos(Button Name)
if ButtonPos <> then
Name := Copy(Name ButtonPos ) + PushButton +
Copy(Name ButtonPos + Length(Name))
end;
ReadValue方法
声明
function ReadValue: TValueType;
ReadValue方法读取流中紧着的项目的类型函数返回后流的指针移到值类型指示符之后
TValueType是枚举类型存储在Filer对象的流中的每个项目之前都有一个字节标识该项目的类型在读每个项目之前都要读取该字节以指导调用哪个方法来闱取项目该字节的值就TValuetype定义的值类型之一
NextValue方法
声明
function Nextvalue: TValuetype;
Nextvalue方法的作用也是返回Reader对象流中紧接着的项目的类型它与ReadValue的区别在于并不移动指针位置
ReadBoolean方法
声明
function ReadBoolean: Boolean;
ReadBoolean方法从Reader对象的流中读取一个布尔值并相应地移动流位置指针
ReadChar方法
声明
function ReadChar: char;
ReadChar方法从Reader对象的流中读取一个字符
ReadFloat方法
声明
function ReadFloat: Extended;
ReadFloat方法从流中读取浮点数
ReadIdent方法
声明
function ReadIdent: string;
ReadIdent方法从流中读取标识符
ReadInteger方法
声明
function ReadInteger: Longin
ReadInteger方法从流中读取整型数字
ReadString方法
声明
function Read String: string;
ReadString方法从Reader对象的流中读取一个字符串并返回字符串中的内容该字符串是由Writer对象的WriteString方法写入
TReader对象的实现
Filer对象的作用主要是Delphi用来在DFM文件中读写各种类型的数据(包括部件对象)这些数据的一个本质特征是变长而且Filer对象将读写数据操作抽象化包装成对象提供了大量的读写方法方便了程序的调用因此在应用程序中可以广泛使Filer对象充分利用Delphi的面向对象技术而且Filer对象与Stream对象捆绑在一起一方面可以在各种存储媒介中存取任意格式的数据另一方面由于充分利用面向对象的动态联编各种读写方法的使用方法是一致的因此方法调用很简单下面我们着重介绍Reader 对象中与读写数据操作有关的属性和方法的实现
TReader属性的实现
在TReader对象的属性实现中我们重点介绍Position的实现
Position属性的定义了使用了读写控制它们分别是GetPosition和SetPosition方法
TReader = class(TFiler)
private
…
function GetPosition: Longint;
procedure SetPosition(Value: Longint)
public
…
property Position: Longint read GetPosition write SetPosition;
end;
Postition的读写控制方法如下
function TReaderGetPosition: Longint;
begin
Result := FStreamPosition + FBufPos;
end;
procedure TReaderSetPosition(Value: Longint)
begin
FStreamPosition := Value;
FBufPos := ;
FBufEnd := ;
end;
在TReader的父对象TFiler对象中介绍过FBufPos和FBufEnd变量Filer对象内部分配了一个BufSize大小的缓沖区FBufPos就是指在缓沖区中的相对位置FBufEnd是指在缓沖区中数据结束处的位置(缓沖区中的数据不一定会充满整个缓沖区)
在GetPosition方法中可以看到Reader对象的Position值和Stream对象的Position值是不同的Reader对象多了一个FButPos的编移量
Defineproperty和DefineBinaryproperty方法的实现
这两个方法是虚方法在TFiler中是抽象方法在TReader和TWriter对象中才有具体的实现
它们在TReader中的实现如下
procedure TReaderDefineProperty(const Name: string; ReadData: TReaderProc;
WriteData: TWriterProc; HasData: Boolean)
begin
if CompareText(Name FPropName) = then
begin
ReadData(Self)
FPropName := ;
end;
end;
procedure TReaderDefineBinaryProperty(const Name: string;
ReadData WriteData: TStreamProc; HasData: Boolean)
var
Stream: TMemoryStream;
Count: Longint;
begin
if CompareText(Name FPropName) = then
begin
if ReadValue <> vaBinary then
begin
Dec(FBufPos)
SkipValue;
FCanHandleExcepts := True;
PropValueError;
end;
Stream := TMemoryStreamCreate;
try
Read(Count SizeOf(Count))
StreamSetSize(Count)
Read(StreamMemory^ Count)
FCanHandleExcepts := True;
ReadData(Stream)
finally
StreamFree;
end;
FPropName := ;
end;
end;
在两个方法都将Name参数值与当前的属性名比较如果相同则进行读操作在DefineBinaryproperty中创建了一个内存流先将数据读到内存流中然后调用ReadData读取数据
FlushBuffer的实现
FlushBuffer方法用于清除Reader对象的内部缓沖区中的内容保持Reader对象和流在位置(Position)上的同步其实现如下
procedure TReaderFlushBuffer;
begin
FStreamPosition := FStreamPosition (FBufEnd FBufPos)
FBufPos := ;
FBufEnd := ;
end;
ReadListBeginReadListEnd和EndOfList方法
这三个方法都是用于从Reader对象的流中读取一连串的项目并且这些项目都由WriteListBegin写入的标志标定开始和WriteListEnd写入标志标定结束在读循环中用EndOfList进行判断它们是在Reader对象读取流中数据时经常用于的它们的实现如下
procedure TReaderReadListBegin;
begin
CheckValue(vaList)
end;
procedure TReaderReadListEnd;
begin
CheckValue(vaNull)
end;
function TReaderEndOfList: Boolean;
begin
Result := ReadValue = vaNull;
Dec(FBufPos)
end;
项目表开始标志是VaList项目表结束标志是VaNullVaList和VaNull都是枚举类型TValueType定义的常量
[] [] [] []