Announcement

Collapse
No announcement yet.

TypInfo aus einer Objektreferenz bestimmen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • TypInfo aus einer Objektreferenz bestimmen

    Hallo Leute,</p>

    anbei habe ich eine Routine <b>ErmittleProperties(Obj: TObject)</b> geschrieben, welche mir die
    Properties der unten definierten Klasse TObj ausliest. Diese Routine möchte ich verallgemeinern,
    d.h. ich möchte das zu untersuchendes Objekt als Parameter übergeben, der Rest soll automatisch
    laufen.</p>
    Mehrfach mußte ich in der Routine <b>ErmittleProperties</b> auf die Methode </b>TypeInfo</b>
    zurück greifen. Beim Aufruf von TypeInfo wird der Klassentyp <I>hier TObj</I> übergeben. Da
    <b>Classinfo</b> von MyOby den Wert <b>nil</b> besitzt, kann über diese Eigenschaft nicht TypInfo
    ermittelt werden!</p>
    Ist es dennoch möglich aus der Referenz <b>Obj</b> TypeInfo zu ermittlen?</p>

    <I>
    uses</br>
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, ExtCtrls;</p>

    type</br>
    TObj=class(TObject)</br>
    private</br>
    FZahl : integer;</br>
    FText : string;</br>
    FOnChange: TNotifyEvent;</br>
    published</br>
    property Zahl: integer read FZahl write FZahl;</br>
    property Text: string read FText write FText;</br>
    property OnChange: TNotifyEvent read FOnChange write FOnChange;</br>
    end;</p>

    TForm1 = class(TForm)</br>
    Panel1: TPanel;</br>
    ListBox1: TListBox;</br>
    btnStart: TButton;</br>
    procedure FormCreate(Sender: TObject);</br>
    procedure FormDestroy(Sender: TObject);</br>
    procedure btnStartClick(Sender: TObject);</br>
    private</br>
    MyObj: TObj;</br>
    procedure ErmittleProperties(Obj: TObject);</br>
    public</br>
    end;</p>

    var</br>
    Form1: TForm1;</p>

    implementation</p>

    {$R *.DFM}</p>

    uses TypInfo;</p>

    procedure TForm1.FormCreate(Sender: TObject);</br>
    begin</br>
    MyObj := TObj.Create;</br>
    MyObj.Zahl := 17;</br>
    MyObj.Text := 'Hallo';</br>
    end;</p>

    procedure TForm1.FormDestroy(Sender: TObject);</br>
    begin</br>
    MyObj.Free;</br>
    end;</p>

    procedure TForm1.btnStartClick(Sender: TObject);</br>
    begin</br>
    ErmittleProperties(MyObj);</br>
    end;</p>

    procedure TForm1.ErmittleProperties(Obj: TObject);</br>
    const cInfo = '[PropName, PropTyp, PropWert] = ';</br>
    var PropList : TPropList;</br>
    PropInfo : PPropInfo;</br>
    PropCount,</br>
    iCount : Smallint;</br>
    PropName,</br>
    PropTyp,</br>
    PropWert : string;</br>
    begin</br>
    ListBox1.Clear;</br>

    // Property-Liste füllen</br>
    // Hier muß ich den Typ meines zu untersuchenden Objekts kennen</br>
    // Komme ich an TypInfo nicht auch anders heran?</br>
    GetPropInfos(TypeInfo(TObj), @PropList);</br>

    // Anzahl der Properties bestimmen</br>
    // Hier muß ich den Typ meines zu untersuchenden Objekts kennen</br>
    PropCount := GetTypeData(TypeInfo(TObj))^.PropCount;</br>

    if PropCount > 0 then</br>
    for iCount := 0 to pred(PropCount) do</br>
    begin</br>
    PropName := PropList[iCount]^.name;</br>

    // Hier muß ich ebenfallse den Typ meines zu untersuchenden Objekts kennen</br>
    // Komme ich an TypInfo nicht auch anders heran?</br>
    PropInfo := GetPropInfo(TypeInfo(TObj), PropName);</br>

    // Properties filtern => hier keine Methoden und unbekannte Properties anzeigen</br>
    if PropList[iCount]^.PropType^^.Kind in tkProperties then</br>
    begin</br>
    PropTyp := PropList[iCount]^.PropType^^.Name;</br>

    try</br>
    case PropList[iCount]^.PropType^^.Kind of</br>
    tkInteger,</br>
    tkChar,</br>
    tkWChar,
    tkClass : PropWert := IntToStr(GetOrdProp(Obj, PropInfo));</br>
    tkEnumeration : PropWert := GetEnumProp(Obj, PropInfo);</br>
    tkSet : PropWert := GetSetProp(Obj, PropInfo);</br>
    tkFloat : PropWert := FloatToStr(GetFloatProp(Obj, PropInfo));</br>
    tkMethod : PropWert := PropInfo^.PropType^.Name;</br>
    tkString,

  • #2
    Hi

    Obj.ClassInfo: Pointer == TypeInfo(TObjectClass):PTypeInfo

    Gruß Hage

    Comment


    • #3
      Hallo Hagen,

      danke für Deine Antwort,

      Leider funktioniert die Abfrage nicht, da in dem Beispiel

      obj.ClassInfo == nil !!!

      Gruß Uw

      Comment


      • #4
        Was, das darf nicht sein !!

        also:

        <pre>

        var
        Obj: TObject;
        begin
        Obj := TObject.Create;
        if Obj.ClassInfo <> TypeInfo(TObject) then
        raise "Hier ist was OBER faul"
        Obj.Free;
        end;<b>

        </pre>

        Gruß Hage

        Comment


        • #5
          Hallo Hagen,</p>

          Leider ist obj.ClassInfo == nil !!! wenn von TObj von TObject abgeleitet.</br>

          wird TObj von TComponent abgeleitet, dann ist auch ClassInfo zugewiesen.</br>

          Kann dies an der Delphi-Version oder an Compilereinstellungen liegen?
          Ich benutze Delphi5 Professional in Verbindung mit Patch1</p>

          MFG Uw

          Comment


          • #6
            Hi

            Korrekt, TObject besitzt keine RTTI ABER eine TypeInfo. Das liegt am Compilerschalter {$M-}. TObject hat aber auch keinerlei Eigenschaften und schon garnicht published. Als Behelf ginge:

            <pre>

            function GetClassInfo(Obj: TObject): Pointer;
            begin
            Result := Obj.ClassInfo;
            if Result = nil then
            if Obj.ClassType = TObject then
            Result := TypeInfo(TObject);
            end;

            </pre>

            Gruß Hage

            Comment


            • #7
              Das einfachste ist, Dein Objekt von TPersistent abzuleiten.
              Dieses ist (siehe VCL-Quellcode) mit {$M+} compiliert und hat daher eine RTTI (und damit auch jedes davon abgeleitete Objekt).

              Steht leider irgendwie nirgendwo und man müßte das erstmal wissen.

              Aber ab diesem Moment ist <b>.classinfo</b> nicht mehr <b>nil</b>.

              (Das Problem hat mich auch 2 Tage gekostet

              Comment

              Working...
              X