转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Delphi的组件读写机制(三)         ★★★★

Delphi的组件读写机制(三)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:1715 更新时间:2009/4/23 18:37:52
    GlobalNameSpace.EndWrite;

  end;

end;

       ReadRootComponent首先调用ReadSignature读取Filer对象标签(’TPF0’)。载入对象之前检测标签,能防止疏忽大意,导致读取无效或过时的数据。

       再看一下ReadPrefix(Flags, I)这一句,ReadPrefix方法的功能与ReadSignature的很相象,只不过它是读取流中组件前面的标志(PreFix)。当一个Write对象将组件写入流中时,它在组件前面预写了两个值,第一个值是指明组件是否是从祖先窗体中继承的窗体和它在窗体中的位置是否重要的标志;第二个值指明它在祖先窗体创建次序。

       然后,如果Root参数为nil,则用ReadStr读出的类名创建新组件,并从流中读出组件的Name属性;否则,忽略类名,并判断Name属性的唯一性。

          FRoot.ReadState(Self);

       这是很关键的一句,ReadState方法读取根组件的属性和其拥有的组件。这个ReadState方法虽然是TComponent的方法,但进一步的跟踪就可以发现,它实际上最终还是定位到了TReader的ReadDataInner方法,该方法的实现如下:

procedure TReader.ReadDataInner(Instance: TComponent);

var

  OldParent, OldOwner: TComponent;

begin

  while not EndOfList do ReadProperty(Instance);

  ReadListEnd;

  OldParent := Parent;

  OldOwner := Owner;

  Parent := Instance.GetChildParent;

  try

    Owner := Instance.GetChildOwner;

    if not Assigned(Owner) then Owner := Root;

    while not EndOfList do ReadComponent(nil);

    ReadListEnd;

  finally

    Parent := OldParent;

    Owner := OldOwner;

  end;

end;

       其中有这样的这一行代码:

  while not EndOfList do ReadProperty(Instance);

       这是用来读取根组件的属性的,对于属性,前面提到过,既有组件本身的published属性,也有非published属性,例如TTimer的Left和Top。对于这两种不同的属性,应该有两种不同的读方法,为了验证这个想法,我们来看一下ReadProperty方法的实现。

procedure TReader.ReadProperty(AInstance: TPersistent);

……

begin

       ……

      PropInfo := GetPropInfo(Instance.ClassInfo, FPropName);

      if PropInfo <> nil then ReadPropValue(Instance, PropInfo) else

      begin

        { Cannot reliably recover from an error in a defined property }

        FCanHandleExcepts := False;

        Instance.DefineProperties(Self);

        FCanHandleExcepts := True;

        if FPropName <> '''''''' then

          PropertyError(FPropName);

      end;

       ……

end;

       为了节省篇幅,省略了一些代码,这里说明一下:FPropName是从文件读取到的属性名。

      PropInfo := GetPropInfo(Instance.ClassInfo, FPropName);

       这一句代码是获得published属性FPropName的信息。从接下来的代码中可以看到,如果属性信息不为空,就通过ReadPropValue方法读取属性值,而ReadPropValue方法是通过RTTI函数来读取属性值的,这里不再详细介绍。如果属性信息为空,说明属性FPropName为非published的,它就必须通过另外一种机制去读取。这就是前面提到的DefineProperties方法,如下:

       Instance.DefineProperties(Self);

       该方法实际上调用的是TReader的DefineProperty方法:

procedure TReader.DefineProperty(const Name: string;

  ReadData: TReaderProc; WriteData: TWriterProc; HasData: Boolean);

begin

  if SameText(Name, FPropName) and Assigned(ReadData) then

  begin

    ReadData(Self);

    FPropName := '''''''';

  end;

end;

       它先去比较读取的属性名是否和预设的属性名相同,如果相同并且读方法ReadData不为空时就调用ReadData方法读取属性值。

       好了,根组件已经读上来了,接下来应该是读该根组件所拥有的组件了。再来看方法:

procedure TReader.ReadDataInner(Instance: TComponent);

       该方法后面有一句这样的代码:

    while not EndOfList do ReadComponent(nil);

       这正是用来读取子组件的。子组件的读取机制是和上面所介绍的根组件的读取一样的,这是一个树的深度遍历。

       到这里为止,组件的读机制已经介绍完了。

 

       再来看组件的写机制。当我们在窗体上添加一个组件时,它的相关的属性就会保存在DFM文件中,这个过程就是由TWriter来完成的。

上一页  [1] [2] [3] [4]  下一页


没有相关教程
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台