2013-03-29 27 views
6

Mam wartości przechowywane w kodzie xml i lua i dostęp do właściwości obiektu przez RTTI.Jak ustawić/uzyskać wartość właściwości przez RTTI dla kompilacji takich jak TStringGrid.Cells?

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); 

mogę pracować z wieloma właściwościami jak Width, Lines.Text z TMemo etc, nawet z Panels[0].Width z TStatusBar (gdzie paneli TCollection potomka), ale coś takiego TStringGrid.Cells[x, y] jest coś, czego nie da się rozwiązać. Jest pomoc na Embarcadero i niektóre funkcje, takie jak GetIndexedProperty (może to jest to, czego potrzebuję), ale wyjaśnienie jest tak dobre, jak "Gets Indexed Property".

Jak ustawić i uzyskać TStringGrid.Cells[x,y] przez RTTI w czasie wykonywania, jeśli mam wartości przechowywane jako ciągi takie jak "Cells[1,1]"?

Odpowiedz

4

Oto najprostszy przykład mogę myśleć off do pobierania i ustawiania wartości z siatki strun przy użyciu 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'); 

I wycięto błąd sprawdzanie dla uproszczenia. Zakładam, że już wiesz, jak sprawdzić błędy.

+0

Dzięki. Czy istnieje sposób, aby znaleźć, kiedy należy użyć GetIndexedProperty i kiedy GetProperty? – user2091150

+1

OK, Zgaduję, że parsujesz tekst w ten sposób: 'Komórki [1,1]: = ...'. W takim przypadku obecność '[]' mówi ci, że jest to własność indeksowana. Możesz także użyć 'TRttiType.GetIndexedProperties' i sprawdzić, czy twoja własność znajduje się na tej liście. –

+0

Tak, ale był ciekawy, że Delphi wie, że właściwość jest indeksowana i być może RTTI może wrócić jakoś IsIndexed. Dzięki. – user2091150