Опитвам се да създам опростен инспектор на обекти за приложение за рисуване, което пиша.
Опитвам се динамично да получа RTTI за избрания обект и неговите дъщерни обекти. Ако дадено свойство е клас (tkClass), искам да извикам GetRTTIObject рекурсивно, предавайки това свойство като обект, за да получа подсвойствата за него (т.е. BaseObj.Brush.Color или BaseObj.Pen.Width и т.н.). Подозирам, че искам да предам екземпляра на този обект и че ще бъде болезнено очевидно, когато някой посочи какво е това. Как да накарам екземпляр да премине към моята функция? Или трябва да търся TRttiInstance за свойства, които са класове....?
Знам, че работи на ниво 0, защото мога да предам BaseObject.Brush към първото си извикване на GetRTTIObject и получавам списък със свойства на TBrush. Как мога да разбия рекурсивно?
Изглежда получавам някакъв указател със стойност := GetPropValue(AObj, Prop.Name);
Дереферирам ли това по някакъв начин, за да получа своя екземпляр...?
Поздрави, Роб
Опростеният тестов клас е дефиниран:
TBaseClass = class(TObject)
private
FFont: TFont;
FBrush: TBrush;
FPen: TPen;
FCaption: String;
FFloat1: Real;
FInt1: Integer;
published
property Font: TFont Read FFont Write FFont;
property Brush: TBrush Read FBrush Write FBrush;
property Pen: TPen Read FPen Write FPen;
property Caption: String Read FCaption Write FCaption;
property Float1: Real Read FFloat1 Write FFloat1;
property Int1: Integer Read FInt1 Write FInt1;
end;
Моята RTTI процедура е:
procedure TfrmMain.GetRTTIClass(AClass: TClass; Items: TStrings; Indent: Integer);
var
LContext: TRttiContext;
LType: TRttiType;
Prop: TRttiProperty;
PropString: String;
PropInfo: PPropInfo;
Tabs: String;
I: Integer;
Value: Variant;
begin
LContext := TRttiContext.Create();
try
for I := 0 to Indent do
Tabs := Tabs + ' '; //chr(9)
Log(Format('Get RTTI (Class) for "%s"', [AClass.ClassName]));
LType := LContext.GetType(AClass.ClassInfo);
Items.Add(Tabs + 'RTTI for: ' + Ltype.Name);
Items.Add(Tabs + 'Package Name: ' + LType.Package.Name);
Items.Add(Tabs + '-- Properties --');
for Prop in LType.GetProperties do
begin
PropString := 'property: ' + Prop.Name;
PropInfo := GetPropInfo(AClass, Prop.Name);
PropString := PropString + ': ' + GetEnumName(TypeInfo(TTypeKind), Ord(Prop.PropertyType.TypeKind));
if propInfo <> nil then begin
PropString := PropString + ': ' + PropInfo^.PropType^.Name;
case propInfo.PropType^.Kind of
tkClass: begin
PropString := PropString + ' (Class)' ; // ' GetProp Value: ' + IntToHex(PropInfo.GetProc, 8); // Items.Add('--- Get RTTI ---');(Class)';
Log(Format('GetRTTI: %s (%s)', [Prop.Name, PropInfo^.PropType^.Name]));
// TODO: Get a reference to the object and call GetRTTI
// TODO: Or change function to work from classtype rather than object
// GetRTTIObject(### WHAT GOES HERE?!?!?, Items, Indent + 1);// := PropString + ' Class';
end;
end;
end;
Items.Add(Tabs + PropString);
end;
finally
LContext.Free;
end;
end;
Опа!!
Виждам, че съм поставил грешна функция .....въпросната взема TObject и присвояването е:
LType := LContext.GetType((AObject.ClassInfo); (AObject.ClassType също изглежда работи...)....
Не в моята станция за разработка точно сега, но мисля, че всичко останало е същото след това....