• delphi RTTI 三 属性读取与赋值


    delphi RTTI 读取属性 运行期

    通过RTTI给属性赋值

    http://docwiki.embarcadero.com/CodeExamples/Berlin/en/Event_RTTI_Invocation_(Delphi)

    http://www.cnblogs.com/del/archive/2009/10/15/1583969.html

    var
      context: TRttiContext;
      method: TValue; // System.TMethod
      methodType: TRttiInvokableType;
    begin
      { Get the value of the OnChange property, which is a method pointer }
      method := context.GetType(mapModel.ClassType).GetProperty('OnChange')
        .GetValue(mapModel);
     
      { Display the method code and data pair }
      Writeln(method.ToString);
     
      { Get event RTTI }
      methodType := context.GetType(method.TypeInfo) as TRttiInvokableType;
      Writeln(methodType.Name);
     
      { Invoke event }
      { The first parameter must be the procedure/method pointer in a TValue variable }
      methodType.Invoke(method, [mapModel { Sender } , nil { Area } ]);

    读取简单属性

    procedure TForm2.Button6Click(Sender: TObject);
    var
      rc: TRttiContext;
      v: TValue;
      rm: TRttiMethod;
      rt: TRttiType;
      rp: TRttiProperty;
    begin
      //取Btn2的属性Name 和Caption
      //分步
      rt := TRttiContext.Create.GetType(self.Button2.ClassType);
      rp := rt.GetProperty('Name');
      v := rp.GetValue(self.btn2);
      ShowMessage(v.AsString);
    
      //合并一步
     ShowMessage(  rt.GetProperty('Caption').GetValue(self.btn2).AsString);
    
    end;

    修改属性

    rt.GetProperty('Caption').SetValue(Button1,'New');

     p.SetValue(Button1, TValue.FromOrdinal(TypeInfo(TAlign), Ord(alLeft))); 

        rc.GetType(Data.ClassType).GetField('FStatus').SetValue(Data, TValue.From(Status));

    const
      eval = 'alLeft';

       p.SetValue(Panel1, TValue.FromOrdinal( p.PropertyType.Handle , Ord(alLeft)));

    两种方法都可以
    //  tv := TValue.FromOrdinal(p.PropertyType.Handle, GetEnumValue(p.PropertyType.Handle, eval));
    //  p.SetValue(Panel1, tv);

    //调用btn2单击方法
    procedure TForm2.Button7Click(Sender: TObject);
    var
      tt: TRttiType;
      rm: TRttiMethod;
    begin
      tt := TRttiContext.Create.GetType(self.btn2.ClassType);
      rm := tt.GetMethod('Click');
      rm.Invoke(self.btn2, []);//空参
    end;

       TTypeKind = (tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,
        tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,
        tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray, tkUString,
        tkClassRef, tkPointer, tkProcedure {, tkMRecord});

    PropInfo.PropType^.Kind = tkClass

    aRPt: TRttiProperty;

    aRPt.PropertyType.Handle就是PTypeInfo

      aRPt.PropertyType.Handle.Kind

    设置复杂的属性字体颜色 字体 Font.Size/Font.Color

    procedure TForm13.Button7Click(Sender: TObject);
    var
      p : TRttiProperty;
      p2: TRttiProperty;
      c : TRttiContext;
    begin
       c := TRttiContext.Create;
       try
         p := c.GetType(Panel1.ClassInfo).GetProperty('Font');
         p2 := c.GetType(p.PropertyType.Handle).GetProperty('Color');
         p2.SetValue(p.GetValue(Panel1).AsObject,clred);
       finally
         c.Free;
       end;
    end;
    
    
    
    procedure TForm13.Button8Click(Sender: TObject);
    var
      p : TRttiProperty;
      p2: TRttiProperty;
      c : TRttiContext;
    begin
       c := TRttiContext.Create;
       try
    //        self.Panel1.Font.Style:
         p := c.GetType(Panel1.ClassInfo).GetProperty('Font');
         p2 := c.GetType(p.PropertyType.Handle).GetProperty('Size');
         p2.SetValue(p.GetValue(Panel1).AsObject,20); //this line now works.
       finally
         c.Free;
       end;
    end;

     http://stackoverflow.com/questions/6006326/how-i-can-set-the-value-of-a-nested-property-using-the-rtti?answertab=votes#tab-top

    复杂类型(集合类型)tkSet

     与控件实例无关,只是计算集合类型的字符串。获得某个控件当前某个集合属性的字符串参考System.TypInfo.GetSetProp

    procedure GetOrdTypeInfo(ATypeInfo: PTypeInfo; AStrings: TStrings);
    var
      OrdTypeData: PTypeData;
      I: Integer;
    begin
      OrdTypeData := GetTypeData(ATypeInfo);
      AStrings.Add('------------------------------------');
      AStrings.Add('Type Name: ' + ATypeInfo^.Name);
      AStrings.Add('Type Kind: ' + GetEnumName(TypeInfo(TTypeKind),
        Integer(ATypeInfo^.Kind)));
      AStrings.Add('Data Type: ' + GetEnumName(TypeInfo(TOrdType),
        Integer(OrdTypeData^.OrdType)));
      if ATypeInfo^.Kind <> tkSet then
      begin
        AStrings.Add('Min Value: ' + IntToStr(OrdTypeData^.MinValue));
        AStrings.Add('Max Value: ' + IntToStr(OrdTypeData^.MaxValue));
      end;
      if ATypeInfo^.Kind = tkSet then
        GetOrdTypeInfo(OrdTypeData^.CompType^, AStrings);
      if ATypeInfo^.Kind = tkEnumeration then
        for I := OrdTypeData^.MinValue to OrdTypeData^.MaxValue do
          AStrings.Add(Format('  Value %d: %s', [I, GetEnumName(ATypeInfo, I)]));
    end;
    
    procedure TForm2.Button3Click(Sender: TObject);
    begin
      GetOrdTypeInfo(TypeInfo(Char), Memo1.Lines);
      GetOrdTypeInfo(TypeInfo(Integer), Memo1.Lines);
      GetOrdTypeInfo(TypeInfo(TFormBorderStyle), Memo1.Lines);
      GetOrdTypeInfo(TypeInfo(TBorderIcons), Memo1.Lines);
      GetOrdTypeInfo(TypeInfo(TMyEnum), Memo1.Lines);
      GetOrdTypeInfo(TypeInfo(TDBGridOption), Memo1.Lines);
    end;

     TypeInfo(TPicture);

    TypeInfo(TBitmap)

    DBGrid

    PropertyName:Options

    Type Name: TDBGridOptions
    Type Kind: tkSet
    Data Type: otUWord
    ------------------------------------
    Type Name: TDBGridOption
    Type Kind: tkEnumeration
    Data Type: otUByte
    Min Value: 0
    Max Value: 14
      Value 0: dgEditing
      Value 1: dgAlwaysShowEditor
      Value 2: dgTitles
      Value 3: dgIndicator
      Value 4: dgColumnResize
      Value 5: dgColLines
      Value 6: dgRowLines
      Value 7: dgTabs
      Value 8: dgRowSelect
      Value 9: dgAlwaysShowSelection
      Value 10: dgConfirmDelete
      Value 11: dgCancelOnExit
      Value 12: dgMultiSelect
      Value 13: dgTitleClick
      Value 14: dgTitleHotTrack

    gridEh控件

    PropertyName:OptionsEh

    Type Name: TDBGridEhOption
    Type Kind: tkEnumeration
    Data Type: otUByte
    Min Value: 0
    Max Value: 23
      Value 0: dghFixed3D
      Value 1: dghFrozen3D
      Value 2: dghFooter3D
      Value 3: dghData3D
      Value 4: dghResizeWholeRightPart
      Value 5: dghHighlightFocus
      Value 6: dghClearSelection
      Value 7: dghFitRowHeightToText
      Value 8: dghAutoSortMarking
      Value 9: dghMultiSortMarking
      Value 10: dghEnterAsTab
      Value 11: dghTraceColSizing
      Value 12: dghIncSearch
      Value 13: dghPreferIncSearch
      Value 14: dghRowHighlight
      Value 15: dghDblClickOptimizeColWidth
      Value 16: dghDialogFind
      Value 17: dghRecordMoving
      Value 18: dghShowRecNo
      Value 19: dghColumnResize
      Value 20: dghColumnMove
      Value 21: dghAutoFitRowHeight
      Value 22: dghHotTrack
      Value 23: dghExtendVertLines

    通过RTTI给StringGrid单元格赋值

    参考

    http://stackoverflow.com/questions/15702778/how-can-i-set-get-property-value-through-rtti-for-compex-things-like-tstringgrid

    var
      ctx: TRttiContext;
      rttitype: TRttiType;
      rttiprop: TRttiIndexedProperty;
      value: TValue;
    begin
      rttitype := ctx.GetType(StringGrid1.ClassType);
      rttiprop := rttitype.GetIndexedProperty('Cells');
      value := rttiprop.GetValue(StringGrid1, [1, 1]);
      rttiprop.SetValue(StringGrid1, [1, 1], value.ToString + ' hello');
    end;

    判断属性类型

    procedure DeserializeProperty(P: TRttiProperty; s: string);
    var
      v: TValue;      
    begin
      case p.PropertyType.TypeKind of
        tkInteger: v := StrToInt(s);
        tkFloat: v := StrToFloat(s);
        tkString: v := s;
      end;
      p.SetValue(self, v);
    end;
  • 相关阅读:
    C# COM DLL 给vba调用
    c# autocad 通过进程向cad发送command
    AutoCAD Excel script
    c# 自动生成 autocad cuix
    AutoCAD 批处理打印文件
    c# 一套代码多个配置生成多个程序
    获取本机的com对象的progid和类型库的位置
    mybatis SqlMapConfig.xml配置
    GDAL 处理shape自相交图形
    PostGIS 常用函数
  • 原文地址:https://www.cnblogs.com/cb168/p/6421661.html
Copyright © 2020-2023  润新知