Entwickler-Ecke

Sonstiges (Delphi) - Objekte die ihre eigenen Published Felder in ein Array....


Mordilion - Sa 15.10.05 11:35
Titel: Objekte die ihre eigenen Published Felder in ein Array....
Hallo,

ich hoffe mir kann einer helfen.

Ich ahbe folgendes Problem, ich habe mir ein Basis-Objekt gemacht das einige funktion beinhaltet, sowie die möglichkeit seine eigenen Published-Felder in ein Array zu schreiben.

Jetzt habe ich ein paar Objekte die von diesem Basis Objekt abgeleitet werden. Allerdings klappt es nicht das diese Objekte ihre Published-Felder in das Array schreiben. (Die funktion ist nur beim Basis-Objekt deklariert)

So sieht die Funktion im Basis-Objekt aus:
(TypeInfo ist immer NIL daher gehts nicht weiter)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
function TBasisTab.GetObjectFields(Obj: TObject): Boolean;
{**
  Liefert die Published-Felder eines Objects in dem angegebenen Array zurück
**}

var
  TypeData : PTypeData;
  TypeInfo : PTypeInfo;
  Props    : PPropList;
  i        : Integer;
begin
  Result := True;
  try
    SetLength(FFields, 0);
    TypeInfo := Obj.ClassInfo;
    if TypeInfo = nil then begin
      Result := False;
      EXIT;
    end;
      
    if TypeInfo^.Kind <> tkClass then begin
      Result := False;
      EXIT;
    end;

    TypeData := GetTypeData(TypeInfo); //GetTypeData(Self.ClassInfo);
    if (TypeData = nilor (TypeData^.PropCount = 0then begin
      Result := False;
      EXIT;
    end;

    GetMem(Props, TypeData^.PropCount * SizeOf(Pointer));
    try
      GetPropInfos(TypeInfo, Props);
      for i := 0 to TypeData^.PropCount-1 do begin
        SetLength(FFields, Length(FFields)+1);
        FFields[High(FFields)].Name := Trim(Props^[i]^.Name);
        FFields[High(FFields)].Kind := Props^[i]^.PropType^.Kind;
      end;
    finally
      FreeMem(Props);
    end;
  except
    Result := False;
  end;
end;



und so werden die abgeleiteten Objekte erzeugt:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
procedure LoadTabObjects;
begin
  if tabKunden = nil
    then tabKunden  := TKundenTab.Create(tabKunden);
  tabKunden.GetObjectFields(tabKunden);

  if tabArtikel = nil
    then tabArtikel := TArtikelTab.Create(tabArtikel);
  tabArtikel.GetObjectFields(tabArtikel);
end;



Wenn es unverständlich ist einfach schreiben, werde es dann versuchen anders zu formulieren.

MfG
Mordi


BenBE - Sa 15.10.05 12:06

hmmm,

rein formal müsste der Source eigentlich laufen.

Sag mal kurz an, an welcher Zeile er abbricht (falls Fehlerbedingung), bzw. mach mal ne MessageBox rein, in der er Dir den Klassen-Namen der Klasse angibt, von der er die Properties ausliest.


Mordilion - Sa 15.10.05 12:16

Er beendet das ganze schon an dem folgenden Punkt:

Delphi-Quelltext
1:
2:
3:
4:
5:
    TypeInfo := Obj.ClassInfo;
    if TypeInfo = nil then begin
      Result := False;
      EXIT;
    end;


Nur das wieso ist das was ich nicht verstehe :)


BenBE - Sa 15.10.05 12:52

k, hab nochmal genau geguckt und hab folgende Vermutung:

Dein TBasic-Tab wird von TObject abgeleitet?

Wenn dem so ist, ist es ganz klar, warum es nicht geht: Delphi Generiert nur Type-Infos für Klassen, die entweder explizit mit Type-Infos angefordert wurden, oder nachfolger einer Klasse sind, für die Type-Infos existieren.

In deinem Fall wäre es wahrscheinlich am sinnvollsten von TObject auf TPersistent als Basis-Klasse umzusteigen; dann geht das auch mit dieser Abfrage.


Mordilion - Sa 15.10.05 12:58

Jo danke, hat geklappt.

Musste allerdings auch beim Functionsaufruf TPersistent verwenden.

Danke nochmal ;) hätte sonst noch mehrere Stunden damit verbracht :D


BenBE - Sa 15.10.05 13:11

Warum implizierst Du nicht als Parameter Self? Hätte den Vorteil, dass Du diesen Aufruf im Constructor automatisieren könntest ...


Mordilion - Sa 15.10.05 13:27

Ich hatte alles mögliche ausprobiert vorher und hatte das vorher so wie du es gerade beschrieben hast.

Werde das auch wieder ändern :)