Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   RTTI und Enum (https://www.delphipraxis.net/178951-rtti-und-enum.html)

Rainer Wolff 5. Feb 2014 13:27

Delphi-Version: XE

RTTI und Enum
 
Hallo,

ich habe eine Klasse mit mehreren Enum-Member (verschiedene Enums). Von dieser Klasse will ich per RTTI die Member auslesen, und falls es ein Enum ist, die Enum-Werte als Strings auslesen. Ich kann die Member auslesen und habe auch die Lösung für das Auflisten von Enums, aber ich bekomme die beiden nicht zusammen.

Dieser Code funktioniert zum Auslesen der Enums:
Delphi-Quellcode:
procedure TForm5.ListEnum(a: PTypeInfo);
var
  i:Integer;
  TypeData: PTypeData;
begin
  TypeData:=GetTypeData(a);
  for I := TypeData.MinValue to TypeData.MaxValue do
    memo1.LineS.Add(GetEnumName(a,i));
end;
mit RTTI versuche ich was in der Richtung:
Delphi-Quellcode:
procedure TForm5.Button2Click(Sender: TObject);
var
  context: TRttiContext;
  aType: TRttiType;
  aProperty : TRttiProperty;
  typedata: PTypeData;
begin
  aType:=context.GetType(TTestKlass);
  for aProperty in aType.GetProperties do
  begin
    // Hier wird im Original geprüft, ob die Property ein bestimmtes Attribut besitzt, das meine Enums haben
    // wenn ja, dann hier weiter
    TypeData:=aProperty.PropertyType......
    // Dann sollen hier die Strings des Enum verarbeitet werden
  end;
end;
TRttiType hat wohl eine Variable TypeData, aber nur private. Muss ich irgendwas mit einem Class-Helper basteln, um auf den private-Member zuzugreifen, oder gibt es eine bessere Lösung?

stahli 5. Feb 2014 13:40

AW: RTTI und Enum
 
Hier meine Funktion:

Delphi-Quellcode:
function GetPropValue(const od: TObject; PropName: String): String;
var
  PropValue: String;
  Context: TRttiContext;
  RttiType: TRttiType;
  PropInfo: TRttiProperty;
  F: Boolean;
  Attr: TCustomAttribute;
  Value: TValue;
  _od: TObject;
  _PropName: String;
begin
...
  Result := '';

...

  Context := TRttiContext.Create;
  RttiType := Context.GetType(_od.ClassType);

  if Assigned(RttiType) then
  begin
    for PropInfo in RttiType.GetProperties do
    begin
      if PropInfo.Name <> _PropName then
        Continue;
      F := True;
      if od is TssObject then // Attribut prüfen - kann man weg lassen
      begin
        F := False;
        for Attr in PropInfo.GetAttributes do
        begin
          if Attr is AttrSsf then
          begin
            F := True;
            Break;
          end;
        end;
      end;
      if F then
      begin
        PropValue := '';
        Value := PropInfo.GetValue(_od);
        case Value.Kind of
          tkUnknown:
            ;
          tkInteger:
            if Value.AsInteger = 0 then
              PropValue := ''
            else
              PropValue := IntToStr(Value.AsInteger);
          tkChar:
            ;
          tkEnumeration:
            PropValue := GetEnumName(Value.TypeInfo, Value.AsOrdinal);
          tkFloat:
            if Value.AsExtended = 0 then
              PropValue := ''
            else
              PropValue := FloatToStr(Value.AsExtended);
          tkString:
            PropValue := Value.AsString;
          tkSet:
            ;
          tkClass:
            begin
              if (Value.AsObject is TssObject) then
                PropValue := (Value.AsObject as TssObject).Id;
            end;
          tkMethod:
            ;
          tkWChar:
            ;
          tkLString:
            ;
          tkWString:
            ;
          tkVariant:
            ;
          tkArray:
            ;
          tkRecord:
            ;
          tkInterface:
            ;
          tkInt64:
            ;
          tkDynArray:
            ;
          tkUString:
            PropValue := Value.AsString;
          tkClassRef:
            ;
          tkPointer:
            ;
          tkProcedure:
            ;
        end;
        if PropValue <> '' then
          Result := PropValue; // Ergebnis
      end;
    end;
  end;

  Context.Free;
end;

Rainer Wolff 5. Feb 2014 14:06

AW: RTTI und Enum
 
Halle ist ein bisschen weit weg, aber falls ich mal da hin komm: Ich lad dich auf ein Bier ein.

Vielen Dank

Stevie 5. Feb 2014 14:54

AW: RTTI und Enum
 
So bekommst du aus einem TRttiType das PTypeData:
Delphi-Quellcode:
...
TypeData:=GetTypeData(aProperty.PropertyType.Handle);
Wenn du den Wert des Enums einer Property als string darstellen willst, gibs da aber einfachere Wege:

Delphi-Quellcode:
var
  obj: TMyObject;
begin
  ...
  s := aProperty.GetValue(obj).ToString;
  ...
end;


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:13 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz