DELPHI基础教程:开发Delphi对象式数据管理功能(四)[2]
OnSetName事件
声明
property OnSetName: TSetNameEvent;OnSetName事件发生在Read对象设置部件的Name属性前 OnSetName事件处理过程的var参数Name参数是一个var参数 因此 事件处理过程再将Name赋给部件前 可以修改Name的值 这对于想过滤窗体中部件的名字是很有帮助的
下面的OnSetName事件处理过程 命名了名字中包含 Button 的部件 并用 PushButton 替代
procedure TForm ReaderSetName(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: LonginReadInteger方法从流中读取整型数字
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 TReader GetPosition: Longint;
begin
Result := FStream Position + FBufPos;
end;
procedure TReader SetPosition(Value: Longint)
begin
FStream Position := Value;
FBufPos := ;
FBufEnd := ;
end;
在TReader的父对象TFiler对象中介绍过FBufPos和FBufEnd变量 Filer对象内部分配了一个BufSize大小的缓冲区FBufPos就是指在缓冲区中的相对位置 FBufEnd是指在缓冲区中数据结束处的位置(缓冲区中的数据不一定会充满整个缓冲区)
在GetPosition方法中可以看到Reader对象的Position值和Stream对象的Position值是不同的 Reader对象多了一个FButPos的编移量
Defineproperty和DefineBinaryproperty方法的实现
这两个方法是虚方法 在TFiler中是抽象方法 在TReader和riter对象中才有具体的实现
它们在TReader中的实现如下
procedure TReader DefineProperty(const Name: string; ReadData: TReaderProc;
WriteData: riterProc; HasData: Boolean)
begin
if CompareText(Name FPropName) = then
begin
ReadData(Self)
FPropName := ;
end;
end;
procedure TReader DefineBinaryProperty(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 := TMemoryStream Create;
try
Read(Count SizeOf(Count))
Stream SetSize(Count)
Read(Stream Memory^ Count)
FCanHandleExcepts := True;
ReadData(Stream)
finally
Stream Free;
end;
FPropName := ;
end;
end;
在两个方法都将Name参数值与当前的属性名比较 如果相同则进行读操作 在DefineBinaryproperty中 创建了一个内存流 先将数据读到内存流中然后调用ReadData读取数据
FlushBuffer的实现
FlushBuffer方法用于清除Reader对象的内部缓冲区中的内容 保持Reader对象和流在位置(Position)上的同步 其实现如下
procedure TReader FlushBuffer;
begin
FStream Position := FStream Position (FBufEnd FBufPos)
FBufPos := ;
FBufEnd := ;
end;
ReadListBegin ReadListEnd和EndOfList方法
这三个方法都是用于从Reader对象的流中读取一连串的项目 并且这些项目都由WriteListBegin写入的标志标定开始和WriteListEnd写入标志 标定结束 在读循环中用EndOfList进行判断 它们是在Reader对象读取流中数据时经常用于的 它们的实现如下
procedure TReader ReadListBegin;
begin
CheckValue(vaList)
end;
procedure TReader ReadListEnd;
begin
CheckValue(vaNull)
end;
function TReader EndOfList: Boolean;
begin
Result := ReadValue = vaNull;
Dec(FBufPos)
end;
项目表开始标志是VaList 项目表结束标志是VaNull VaList和VaNull都是枚举类型TValueType定义的常量
lishixinzhi/Article/program/Delphi/201311/25093