如何通过RTTI为TStringGrid.Cells之类的compex设置/获取属性值?

时间:2013-03-29 11:59:29

标签: delphi rtti

我将值存储在xml和lua代码中,并通过RTTI访问对象的属性。

var
  o, v: TValue; // o is current object
  a: TStringDynArray; // params as array
  ctx: TRttiContext;
  tt: TRttiType;
  p: TRttiProperty;
  pt: PTypeInfo;
begin
...
  ctx := TRttiContext.Create;
  try
    o := GetLastClassInParams(ctx, obj, a, param_idx);
    tt := ctx.GetType(o.TypeInfo);
    if high(a) < param_idx then
        raise Exception.Create(S_FN + S_NOP);
    p := tt.GetProperty(a[param_idx]);
    if p = nil then
        raise Exception.Create(S_FN + S_PNE + a[param_idx]);
    pt := p.PropertyType.Handle;
    case p.PropertyType.TypeKind of
      tkInteger: v := TValue.From<integer>(integer(Value));
      tkEnumeration: v := TValue.FromOrdinal(pt, GetEnumValue(pt, VarToStr(Value)));
      tkUString: v := TValue.From<string>(VarToStr(Value));
      tkFloat: v := TValue.From<double>(double(Value));
      tkSet: begin
          temp_int := StringToSet(pt, VarToStr(Value));
          TValue.Make(@temp_int, pt, v);
        end;
    else v := TValue.FromVariant(Value);
    end;
    p.SetValue(o.AsObject, v);

我可以处理许多属性,例如TMemo等的WidthLines.Text,即使是TSTatusBar的Panels[0].Width(其中Panel是TCollection后代),但是TStringGrid.Cells[x, y]之类的东西是我无法解决的问题。 Embarcadero和GetIndexedProperty之类的函数有帮助(也许这就是我需要的),但是那里的解释和"Gets Indexed Property"一样好。

如果我将值存储为TStringGrid.Cells[x,y]之类的字符串,如何在运行时通过RTTI设置和获取"Cells[1,1]"

1 个答案:

答案 0 :(得分:5)

这是我可以考虑使用RTTI从字符串网格中获取和设置值的最简单示例:

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

为了简单起见,我删除了错误检查。我假设您已经知道如何检查错误。