zoukankan      html  css  js  c++  java
  • delphi RTTI 反射技术

    unit Unit_main;  
     
    interface  
     
    uses  
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
      Dialogs, StdCtrls, TypInfo;  
     
    type  
      TForm_main = class(TForm)  
        Button1: TButton;  
        Memo1: TMemo;  
        Memo2: TMemo;  
        Button2: TButton;  
        Button3: TButton;  
        Button4: TButton;  
        Button5: TButton;  
        Button6: TButton;  
        Button7: TButton;  
        Button8: TButton;  
        Button9: TButton;  
        Button10: TButton;  
        Button11: TButton;  
        Button12: TButton;  
        Button13: TButton;  
        procedure Button1Click(Sender: TObject);  
        procedure Button2Click(Sender: TObject);  
        procedure Button3Click(Sender: TObject);  
        procedure Button4Click(Sender: TObject);  
        procedure Button5Click(Sender: TObject);  
        procedure Button6Click(Sender: TObject);  
        procedure Button7Click(Sender: TObject);  
        procedure Button8Click(Sender: TObject);  
        procedure Button9Click(Sender: TObject);  
        procedure Button10Click(Sender: TObject);  
        procedure Button11Click(Sender: TObject);  
        procedure Button12Click(Sender: TObject);  
        procedure Button13Click(Sender: TObject);  
      private  
        { Private declarations }  
      public  
        { Public declarations }  
      end;  
     
      PTKeyDog = ^TKeyDog;  
     
      TKeyDog = record  
        id: Integer;  
        projectname: string;  
        city: string;  
        letter: string;  
        hash: string;  
        code: string;  
        note: string;  
        filepath: string;  
        userid: Integer;  
      end;  
     
      { 自定义的类 }  
      TMyClass = class(TComponent)  
      public  
        procedure msg(const str: string);  
        function Add(const a, b: Integer): Integer;  
      end;  
     
     
      // 编译指令 Methodinfo 是 Delphi 2009 新增的, 只有它打开了, ObjAuto 才可以获取 public 区的信息.  
      // 这样, ObjAuto 可以获取 TClass3 的 public、published 和默认区域的信息.  
    {$M+}  
    {$METHODINFO ON}  
     
      TClass3 = class  
        function Fun3: string;  
      private  
        function Fun3Private: string;  
      protected  
        function Fun3Protected: string;  
      public  
        function Fun3Public: string;  
      published  
        function Fun3Published: string;  
      end;  
    {$METHODINFO OFF}  
    {$M-}  
     
    var  
      Form_main: TForm_main;  
     
    implementation  
     
    uses  
      Rtti, ObjAuto;  
    {$R *.dfm}  
     
    // 获取对象的 RTTI 属性与事件的函数  
    function GetPropertyAndEventList(obj: TObject;  
      pList, eList: TStringList): Boolean;  
    var  
      ClassTypeInfo: PTypeInfo; { 类的信息结构指针 }  
      ClassDataInfo: PTypeData; { 类的数据结构指针 }  
      propertyList: PPropList; { TPropInfo 是属性的数据结构;
        PPropList 是其指针;
        TPropList 是属性结构指针的列表数组;
        PPropList 是指向这个数组的指针 }  
     
      num: Integer; { 记录属性的总数 }  
      size: Integer; { 记录属性结构的大小 }  
      i: Integer;  
    begin  
      ClassTypeInfo := obj.ClassInfo; { 先获取: 类的信息结构指针 }  
      ClassDataInfo := GetTypeData(ClassTypeInfo); { 再获取: 类的数据结构指针 }  
      num := ClassDataInfo.PropCount; { 属性总数 }  
      size := SizeOf(TPropInfo); { 属性结构大小 }  
     
      GetMem(propertyList, size * num); { 给属性数组分配内存 }  
     
      GetPropInfos(ClassTypeInfo, propertyList); { 获取属性列表 }  
     
      for i := 0 to num - 1 do  
      begin  
        if propertyList[i].PropType^.Kind = tkMethod then { 如果是事件; 事件也是属性吗, 给分出来 }  
          eList.Add(propertyList[i].Name)  
        else  
          pList.Add(propertyList[i].Name);  
      end;  
     
      pList.Sort;  
      eList.Sort; { 排序 }  
     
      FreeMem(propertyList); { 释放属性数组的内存 }  
     
      Result := True;  
    end;  
     
    procedure TForm_main.Button10Click(Sender: TObject);  
    var  
      obj: TMyClass;  
      t: TRttiType;  
      m1, m2: TRttiMethod;  
      r: TValue; // TRttiMethod.Invoke 的返回类型  
    begin  
      t := TRttiContext.Create.GetType(TMyClass);  
      { 获取 TMyClass 类的两个方法 }  
      m1 := t.GetMethod('msg'); { procedure }  
      m2 := t.GetMethod('Add'); { function }  
     
      obj := TMyClass.Create(Self); { 调用需要依赖一个已存在的对象 }  
     
      { 调用 msg 过程 }  
      m1.Invoke(obj, ['Delphi 2010']); { 将弹出信息框 }  
     
      { 调用 Add 函数 }  
      r := m2.Invoke(obj, [1, 2]); { 其返回值是个 TValue 类型的结构 }  
      ShowMessage(IntToStr(r.AsInteger)); { 3 }  
     
      obj.Free;  
    end;  
     
    procedure TForm_main.Button11Click(Sender: TObject);  
    var  
      obj: TMyClass;  
      t: TRttiType;  
      p: TRttiProperty;  
      r: TValue;  
    begin  
      obj := TMyClass.Create(Self);  
      t := TRttiContext.Create.GetType(TMyClass);  
     
      p := t.GetProperty('Name'); // 继承自TComponent的name  
     
      r := p.GetValue(obj);  
      ShowMessage(r.AsString); { 原来的 }  
     
      p.SetValue(obj, 'NewName');  
      r := p.GetValue(obj);  
      ShowMessage(r.AsString); { NewName }  
     
      obj.Free;  
    end;  
     
    procedure TForm_main.Button12Click(Sender: TObject);  
    var  
      t: TRttiType;  
      p: TRttiProperty;  
      r: TValue;  
    begin  
      t := TRttiContext.Create.GetType(TButton);  
     
      p := t.GetProperty('Align');  
      p.SetValue(Button1, TValue.FromOrdinal(TypeInfo(TAlign), Ord(alLeft)));  
     
      r := p.GetValue(Button1);  
      ShowMessage(IntToStr(r.AsOrdinal)); { 3 }  
    end;  
     
    procedure TForm_main.Button13Click(Sender: TObject);  
    var  
      MiArr: TMethodInfoArray;  
      Mi: PMethodInfoHeader;  
      obj: TClass3;  
    begin  
      obj := TClass3.Create;  
      MiArr := GetMethods(obj.ClassType);  
     
      Memo1.Clear;  
      for Mi in MiArr do  
        Memo1.Lines.Add(string(Mi.Name));  
     
      obj.Free;  
    end;  
     
    procedure TForm_main.Button1Click(Sender: TObject);  
    var  
      propertyL, EventL: TStringList;  
    begin  
      // 属性  
      propertyL := TStringList.Create;  
      // 事件  
      EventL := TStringList.Create;  
     
      Memo1.Clear;  
      Memo2.Clear;  
     
      GetPropertyAndEventList(Self, propertyL, EventL); { 调用函数, 第一个参数是对象名 }  
      Memo1.Lines := propertyL;  
      Memo2.Lines := EventL;  
     
      propertyL.Free;  
      EventL.Free;  
    end;  
     
    procedure TForm_main.Button2Click(Sender: TObject);  
    var  
      ctx: TRttiContext;  
      t: TRttiType;  
    begin  
      Memo1.Clear;  
      for t in ctx.GetTypes do  
        Memo1.Lines.Add(t.Name);  
    end;  
     
    procedure TForm_main.Button3Click(Sender: TObject);  
    var  
      ctx: TRttiContext;  
      t: TRttiType;  
      m: TRttiMethod;  
    begin  
      Memo1.Clear;  
      t := ctx.GetType(TButton);  
      // for m in t.GetMethods do Memo1.Lines.Add(m.Name);  
      for m in t.GetMethods do  
        Memo1.Lines.Add(m.ToString);  
    end;  
     
    procedure TForm_main.Button4Click(Sender: TObject);  
    var  
      ctx: TRttiContext;  
      t: TRttiType;  
      p: TRttiProperty;  
    begin  
      Memo1.Clear;  
      t := ctx.GetType(TButton);  
      // for p in t.GetProperties do Memo1.Lines.Add(p.Name);  
      for p in t.GetProperties do  
        Memo1.Lines.Add(p.ToString);  
    end;  
     
    procedure TForm_main.Button5Click(Sender: TObject);  
    var  
      ctx: TRttiContext;  
      t: TRttiType;  
      f: TRttiField;  
    begin  
      Memo1.Clear;  
      t := ctx.GetType(TButton);  
      // for f in t.GetFields do Memo1.Lines.Add(f.Name);  
      for f in t.GetFields do  
        Memo1.Lines.Add(f.ToString);  
    end;  
     
    // http://my.oschina.net/hermer/blog/320075  
    procedure TForm_main.Button6Click(Sender: TObject);  
    var  
      ctx: TRttiContext;  
      t: TRttiType;  
      ms: TArray<TRttiMethod>;  
      ps: TArray<TRttiProperty>;  
      fs: TArray<TRttiField>;  
    begin  
      Memo1.Clear;  
      t := ctx.GetType(TButton);  
     
      ms := t.GetMethods;  
      ps := t.GetProperties;  
      fs := t.GetFields;  
     
      Memo1.Lines.Add(Format('%s 类共有 %d 个方法', [t.Name, Length(ms)]));  
      Memo1.Lines.Add(Format('%s 类共有 %d 个属性', [t.Name, Length(ps)]));  
      Memo1.Lines.Add(Format('%s 类共有 %d 个字段', [t.Name, Length(fs)]));  
    end;  
     
    procedure TForm_main.Button7Click(Sender: TObject);  
    var  
      t: TRttiRecordType;  
      f: TRttiField;  
    begin  
      Memo1.Clear;  
      t := TRttiContext.Create.GetType(TypeInfo(TPoint)).AsRecord;  
      Memo1.Lines.Add(t.QualifiedName);  
      Memo1.Lines.Add(Format('Size: %d', [t.TypeSize]));  
      Memo1.Lines.Add(EmptyStr);  
     
      Memo1.Lines.Add(Format('字段数: %d', [Length(t.GetFields)]));  
      Memo1.Lines.Add(Format('方法数: %d', [Length(t.GetMethods)]));  
      Memo1.Lines.Add(Format('属性数: %d', [Length(t.GetProperties)]));  
      Memo1.Lines.Add(EmptyStr);  
     
      Memo1.Lines.Add('全部字段:');  
      for f in t.GetFields do  
        Memo1.Lines.Add(f.ToString);  
    end;  
     
    procedure TForm_main.Button8Click(Sender: TObject);  
    var  
      t: TRttiRecordType;  
      f: TRttiField;  
    begin  
      Memo1.Clear;  
      t := TRttiContext.Create.GetType(TypeInfo(TKeyDog)).AsRecord;  
      Memo1.Lines.Add(t.QualifiedName);  
      Memo1.Lines.Add(Format('Size: %d', [t.TypeSize]));  
      Memo1.Lines.Add(EmptyStr);  
     
      Memo1.Lines.Add(Format('字段数: %d', [Length(t.GetFields)]));  
      Memo1.Lines.Add(Format('方法数: %d', [Length(t.GetMethods)]));  
      Memo1.Lines.Add(Format('属性数: %d', [Length(t.GetProperties)]));  
      Memo1.Lines.Add(EmptyStr);  
     
      Memo1.Lines.Add('全部字段:');  
      for f in t.GetFields do  
        Memo1.Lines.Add(f.ToString);  
    end;  
     
    procedure TForm_main.Button9Click(Sender: TObject);  
    var  
      t: TRttiOrdinalType;  
    begin  
      Memo1.Clear;  
     
      // 先从类型名获取类型信息对象  
      t := TRttiContext.Create.GetType(TypeInfo(Byte)) as TRttiOrdinalType;  
      Memo1.Lines.Add(Format('%s - %s', [t.Name, t.QualifiedName]));  
      Memo1.Lines.Add(Format('Size: %d', [t.TypeSize]));  
      Memo1.Lines.Add('QualifiedName: ' + t.QualifiedName);  
      Memo1.Lines.Add(Format('Min,Max: %d , %d', [t.MinValue, t.MaxValue]));  
      Memo1.Lines.Add(EmptyStr); // 空字串  
     
      // 可以用 AsOrdinal 方法代替前面的 as TRttiOrdinalType  
      t := TRttiContext.Create.GetType(TypeInfo(Word)).AsOrdinal;  
      Memo1.Lines.Add(Format('%s: %s', [t.Name, t.QualifiedName]));  
      Memo1.Lines.Add(Format('Size: %d', [t.TypeSize]));  
      Memo1.Lines.Add(Format('Min,Max: %d , %d', [t.MinValue, t.MaxValue]));  
      Memo1.Lines.Add(EmptyStr);  
     
      // 也可以直接强制转换  
      t := TRttiOrdinalType(TRttiContext.Create.GetType(TypeInfo(Integer)));  
      Memo1.Lines.Add(Format('%s: %s', [t.Name, t.QualifiedName]));  
      Memo1.Lines.Add(Format('Size: %d', [t.TypeSize]));  
      Memo1.Lines.Add(Format('Min,Max: %d , %d', [t.MinValue, t.MaxValue]));  
      Memo1.Lines.Add(EmptyStr);  
    end;  
     
    { TMyClass }  
     
    function TMyClass.Add(const a, b: Integer): Integer;  
    begin  
      Result := a + b;  
    end;  
     
    procedure TMyClass.msg(const str: string);  
    begin  
      MessageDlg(str, mtInformation, [mbYes], 0);  
    end;  
     
    { TClass3 }  
     
    function TClass3.Fun3: string;  
    begin  
      Result := 'Fun3';  
    end;  
     
    function TClass3.Fun3Private: string;  
    begin  
      Result := 'Fun3Private';  
    end;  
     
    function TClass3.Fun3Protected: string;  
    begin  
      Result := 'Fun3Protected';  
    end;  
     
    function TClass3.Fun3Public: string;  
    begin  
      Result := 'Fun3Public';  
    end;  
     
    function TClass3.Fun3Published: string;  
    begin  
      Result := 'Fun3Published';  
    end;  
     
    end.  

    转自:http://blog.csdn.net/earbao/article/details/46729785

  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/yangxuming/p/6984875.html
Copyright © 2011-2022 走看看