zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/cb168/p/6421661.html
Copyright © 2011-2022 走看看