知识大全 开发Delphi对象式数据管理功能(四)[3]
Posted 部件
篇首语:别总是羡慕别人光芒万丈,却忘了自己也会发光。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 开发Delphi对象式数据管理功能(四)[3]相关的知识,希望对你有一定的参考价值。
DELPHI基础教程:开发Delphi对象式数据管理功能(四)[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
它们实现中调用的CheckValue是TReader的私有方法 其实现如下
procedure TReader CheckValue(Value: TValueType)
begin
if ReadValue <> Value then
begin
Dec(FBufPos)
SkipValue;
PropValueError;
end;
end;
CheckValue方法的功能是检测紧接着要读的值是否是Value指定的类型 如果不是则跳过该项目并触发一个SInvalidPropertyValue错误
EndOfList函数只是简单地判断下一字节是否是VaNull将判断结果返回 并将字节移回原来位置
简单数据类型读方法的实现
简单数据类型指的是布尔型 字符型 整型 字符串型 浮点型 集合类型和标识符 将它们放在一起介绍是因为它们的实现方法类似
因为它们的实现都用到了ReadValue方法 因此先来介绍ReadValue方法的实现
function TReader ReadValue: TValueType;
begin
Read(Result SizeOf(Result))
end;
该方法调用私有方法Read 从Reader对象流中读一个字节 并移动位置指针
ReadValue方法专门从流中读取值的类型的 所有的数据读写方法中在读取数据前都要调用ReadValue方法判断是否是所要读的数据 如果是 则调用Read方法读取数据 否则触发一个异常事件 下面看Integer类型的读方法
function TReader ReadInteger: Longint;
var
S: Shortint;
I: Smallint;
begin
case ReadValue of
vaInt :
begin
Read(S SizeOf(Shortint))
Result := S;
end;
vaInt :
begin
Read(I SizeOf(I))
Result := I;
end;
vaInt :
Read(Result SizeOf(Result))
else
PropValueError;
end;
end;
因为Delphi 中 整型可分 位 位和 位 因此读取整型数据时分别作了判断
布尔类型的数据是直接放在值类型标志上 如果类型为VaTrue 则值为True;如果类型为VaFalse 则值为False
function TReader ReadBoolean: Boolean;
begin
Result := ReadValue = vaTrue;
end;
ReadString方法也利用ReadValue方法判断是字符串还是长字符串
function TReader ReadString: string;
var
L: Integer;
begin
L := ;
case ReadValue of
vaString:
Read(L SizeOf(Byte))
vaLString:
Read(L SizeOf(Integer))
else
PropValueError;
end;
SetString(Result PChar(nil) L)
Read(Pointer(Result)^ L)
end;
如果VaString类型紧接着一个字节存有字符串的长度 如果是VaLString类 则紧接着两个字节存放字符串长度 然后根据字符串长度用SetString过程给分配空间 用Read方法读出数据
ReadFloat方法允许将整型值转换为浮点型
function TReader ReadFloat: Extended;
begin
if ReadValue = vaExtended then Read(Result SizeOf(Result)) else
begin
Dec(FBufPos)
Result := ReadInteger;
end;
end;
字符类型数据设有直接的标志 它是根据VaString后面放一个序值为 的字节来判断的
function TReader ReadChar: Char;
begin
CheckValue(vaString)
Read(Result )
if Ord(Result) <> then
begin
Dec(FBufPos)
ReadStr;
PropValueError;
end;
Read(Result )
end;
出于读取DFM文件需要 Filer对象支持读取标识符
function TReader ReadIdent: string;
var
L: Byte;
begin
case ReadValue of
vaIdent:
begin
Read(L SizeOf(Byte))
SetString(Result PChar(nil) L)
Read(Result[ ] L)
end;
vaFalse:
Result := False ;
vaTrue:
Result := True ;
vaNil:
Result := nil ;
else
PropValueError;
end;
end;
一般说来 各种复杂的数据结构都是由这些简单数据组成 定义了这些方法等于给读各种类型的数据提供了元操作 使用很方便 例如 读取字符串类型的数据时 如果采用传流方法还要判断字符串的长度 使用ReadString方法就不同了 但应该特别注意的是这些类型数据的存储格式是由Delphi设计的与简单数据类型有明显的不同 因此 存入数据时应当使用Writer对象相应的方法 而且在读数据前要用NextValue方法进行判断 否则会触发异常事件
读取部件的方法的实现
Reader对象中用于读取部件的方法有ReadSignature ReadPrefix ReadComponent ReadRootComponent和ReadComponents
ReadSignature方法主要用于读取Delphi Filer对象标签一般在读取部件前 都要用调用ReadSignature方法以指导部件读写过程
procedure TReader ReadSignature;
var
Signature: Longint;
begin
Read(Signature SizeOf(Signature))
if Signature <> Longint(FilerSignature) then ReadError(SInvalidImage)
end;
FilerSignature就是Filer对象标签其值为 TPF 如果读的不是 TPF 则会触发SInValidImage异常事件
ReadPrefix方法是用于读取流中部件前的标志位 该标志表示该部件是否处于从祖先窗体中继承的窗体中和它在窗体中的位置是否很重要
procedure TReader ReadPrefix(var Flags: TFilerFlags; var AChildPos: Integer)
var
Prefix: Byte;
begin
Flags := [];
if Byte(NextValue) and $F = $F then
begin
Prefix := Byte(ReadValue)
Byte(Flags) := Prefix and $ F;
if ffChildPos in Flags then AChildPos := ReadInteger;
end;
end;
TFilerFlags的定义是这样的
TFilerFlag = (ffInherited ffChildPos)
TFilerFlags = Set of TFilerFlag;
充当标志的字节的高四位是$F 低四位是集合的值 也是标志位的真正含义 如果ffChildPos置位 则紧接着的整型数字中放著部件在窗体中的位置序值
ReadComponent方法用于从Reader对象的流中读取部件 Component 参数指定了要从流中读取的对象 函数返回所读的部件
function TReader ReadComponent(Component: TComponent) TComponent;
var
CompClass CompName: string;
Flags: TFilerFlags;
Position: Integer;
…
begin
ReadPrefix(Flags Position)
CompClass := ReadStr;
CompName := ReadStr;
Result := Component;
if Result = nil then
if ffInherited in Flags then
FindExistingComponent else
CreateComponent;
if Result <> nil then
try
Include(Result FComponentState csLoading)
if not (ffInherited in Flags) then SetCompName;
if Result = nil then Exit;
Include(Result FComponentState csReading)
Result ReadState(Self)
Exclude(Result FComponentState csReading)
if ffChildPos in Flags then Parent SetChildOrder(Result Position)
FLoaded Add(Result)
except
if ComponentCreated then Result Free;
raise;
end;
end;
ReadCompontent方法首先调用ReadPrefix方法 读出部件标志位和它的创建次序值(Create Order) 然后用ReadStr方法分别读出部件类名和部件名 如果Component参数为nil 则执行两个任务
● 如果ffInberited 置位则从Root 找已有部件 否则 就从系统的Class表中找到该部件类型的定义并创建
● 如果结果不为空 将用部件的ReadState方法读入各种属性值 并设置部件的Parent 属性 并恢复它在Parent部件的创建次序
cha138/Article/program/Delphi/201311/25094相关参考
DELPHI基础教程:开发Delphi对象式数据管理功能(四)[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(四)[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(一)[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(二)[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(三)[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(五)[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(二)[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(一)[5] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(一)[4] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快
DELPHI基础教程:开发Delphi对象式数据管理功能(一)[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快