我在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的
Width
、Lines.Text
,甚至是TStatusBar中的Panels[0].Width
(其中Panels是TCollection的后代),但是像TStringGrid.Cells[x, y]
这样的东西我无法解决。Embarcadero上有帮助文档和一些函数,如GetIndexedProperty
(也许这就是我需要的),但是那里的解释像"Gets Indexed Property"
一样简略。如果我有类似于
"Cells[1,1]"
的字符串存储的值,那么如何在运行时通过RTTI设置和获取TStringGrid.Cells[x,y]
?
Cells[1,1] := ...
。如果是这样,那么[]
的存在告诉您它是一个索引属性。您还可以使用TRttiType.GetIndexedProperties
并检查您的属性是否在该列表中。 - David HeffernanTStatusBar.Panels[x]
是属性,尝试读取为GetIndexedProperty('Panels')
时为空,而TStringGrid.Cells[x,y]
是索引属性,尝试读取为GetProperty('Cells')
时为空。我不能将索引和非索引属性都放入数组中进行搜索,因为它们具有不同的类型。而且,数组值是由不同函数使用的确切类型。或者 - 我可以这样做,但没有意义。唯一的选择是同时获取它们并通过nil或非nil来决定。 - user2091150