zoukankan      html  css  js  c++  java
  • Using COM to Transfer Any Type of Data

    unit TransComponent;
    {本工具供Com/DCom间传递组件(从TComponent继承的所有对象)
    调用 VariantToComponent 时会出现 "Class <TClassName> not Found "提示 多次 ,
    在调用单元的initialization段加以下语句:
    RegisterClass(<ClassName>),如
    RegisterClass(TClientDataSet);
    RegisterClass(TStringField);
    VariantToComponent  的参数 Component 必须声明为TComponent,然后使用强制类型转换使用它
    如:TClientDataSet(Component)
    }
    interface
    uses SysUtils,Classes;
    procedure ComponentToVariant(const Component:TComponent;out vData:OleVariant);
    procedure VariantToComponent(out Component:TComponent; vData:OleVariant);
    implementation
    procedure UnloadVariantArray(
       var VData: OleVariant; PData: Pointer;
      NumBytes: Integer);
    var
      PVData: PByteArray;
    begin
       { Lock the variant array, copy the data to the array, and
        unlock the variant array. }
      PVData := VarArrayLock(VData);
       try
         { Move the data in memory that PVData points to (the
          variant array data), to the location in memory that
          PData points to (the integer array). }
        Move(PVData^, PData^, NumBytes);
       finally
        VarArrayUnlock(VData);
       end; // try
    end;
    procedure LoadVariantArray(PData: Pointer;
      NumBytes: Integer; var VData: OleVariant);
    var
      PVData: PByteArray;
    begin
       { Create the variant array of bytes. Set the upper bound
        to the size of the array, minus one, because the array
        is zero-based. }
      VData := VarArrayCreate([0, NumBytes - 1], varByte);
       { Lock the variant array for faster access. Then copy the
        array to the variant array, and unlock the variant
        array. }
      PVData := VarArrayLock(Vdata);
       try
         { Move the bytes at the location in memory that PData
          points to into the location in memory that PVData
          points to. PData points to the integer array and
          PVData points to the variant array of bytes. }
        Move(PData^, PVData^, NumBytes);
       finally
        VarArrayUnlock(VData);
       end; // try
    end ;
    procedure ComponentToVariant(const Component:TComponent;out vData:OleVariant);
    var
      CompBuffer:TByteArray;
      pCompBuffer:pointer;
    begin
      with TMemoryStream.Create do
      try
        WriteComponent(Component);
        Seek(0, soFromBeginning);
        ReadBuffer(CompBuffer,Size);
        LoadVariantArray(@CompBuffer,Size,vData);
      finally
        free;
      end;
    end;
    procedure VariantToComponent(out Component:TComponent; vData:OleVariant);
    var
      CompBuffer:TByteArray;
      pCompBuffer:pointer;
    begin
      with TMemoryStream.Create do
      try
        UnLoadVariantArray(vData,@CompBuffer,VarArrayHighBound(vData,1)+1);
        WriteBuffer(CompBuffer,VarArrayHighBound(vData,1)+1);
        Seek(0, soFromBeginning);
        Component:=ReadComponent(nil);
        //-the Component is AutoCreated
      finally
        free;
      end;
    end;
    end. 

    通过Com接口一般只能传递Microsoft为Com定义的有限参数类型,Delphi封装了
    TClientDataSet.data使之可以按Variant类型传递。我写的单元是把所有继承自
    TComponent的对象转换成OleVariant,这样组件的定义和数据就可以作为Com参数传递。
    有何用?
    举个例子,基于多层结构的客户界面如果需要作微调,必须重新发放客户界面代码。
    如果我把客户界面资源存成资源文件放在服务器,客户程序通过DCom调用远程载入
    客户界面,就不须每次版本更新时重新部署客户程序。当然,考虑到运行效率,我
    还没有把这个技术用于工程中。
    在基于Com的模块化编程中,可以用语Com间复杂参数的传递,但这样设计的Com是不能
    跨语言调用的。 

    事实上,如果单纯传递TComponent,可以使用
    TStream.ReadComponent中例子的ComponentToString&StringToComponent两个
    函数互相转换(把Bin/text格式的dfm互转),没有必要用到我那个苯函数。
    上述函数调用ObjectBinaryToText&ObjectTextToBinary
    处理TPersistent可能可以使用它们解决。
    vinson_zeng感兴趣的话花点时间作出来给大家共享如何? 

  • 相关阅读:
    使用createDocumentFragment的渲染数据(节省性能)
    面向对象写法模板
    面向对象this指向
    js 3D图片叠加旋转切换
    三列布局-中间固定俩边自适应-和两边固定中间自适应布局
    游戏中抽奖的算法
    c++11:lambda表达式
    c++11:模板
    c++11:左值、右值
    游戏服务器语言之争
  • 原文地址:https://www.cnblogs.com/railgunman/p/1888253.html
Copyright © 2011-2022 走看看