知识大全 开发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对象式数据管理功能(四)[2]

DELPHI基础教程:开发Delphi对象式数据管理功能(四)[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(四)[1]

DELPHI基础教程:开发Delphi对象式数据管理功能(四)[1]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(一)[3]

DELPHI基础教程:开发Delphi对象式数据管理功能(一)[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(二)[3]

DELPHI基础教程:开发Delphi对象式数据管理功能(二)[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(三)[3]

DELPHI基础教程:开发Delphi对象式数据管理功能(三)[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(五)[3]

DELPHI基础教程:开发Delphi对象式数据管理功能(五)[3]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(二)[4]

DELPHI基础教程:开发Delphi对象式数据管理功能(二)[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(一)[5]

DELPHI基础教程:开发Delphi对象式数据管理功能(一)[5]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(一)[4]

DELPHI基础教程:开发Delphi对象式数据管理功能(一)[4]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快

知识大全 开发Delphi对象式数据管理功能(一)[2]

DELPHI基础教程:开发Delphi对象式数据管理功能(一)[2]  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快