Einzelnen Beitrag anzeigen

RedOne

Registriert seit: 2. Jun 2008
71 Beiträge
 
Delphi XE2 Professional
 
#7

AW: Data-Pointer in Interfacevariable casten

  Alt 15. Jul 2010, 09:23
Merci für Deine Antwort. Wir kommen näher

Der Speicher wird vor der Funktion initialisiert. Ich habe den Code zusammengestrichen, da ist sie mir wohl abhanden gekommen

Zitat:
1) warum verwendest du eine Objektlist wenn du mit Interfaces arbeitest? Gibt auch eine TInterfaceList
Weil ich diese bisher nicht kannte

Zitat:
2) wenn du eine ObjectList verwendest, ist auch OwnsObjects auf false, sonst sind die Objekte beim Free alle wieder weg (auch deine TInterfaceObjects)
OwnsObject setzte ich bis anhin in der Funktion auf false

Ich habe das ganze jetzt mal gemäss Deinem Beispiel umgebaut und es funktioniert fast. Weder gibt es einen Compillier- noch einen Laufzeitfehler
In der Methode "Delete" gebe zu Testzwecken FID aus. Diese ist jedoch immer 0. Beim abfüllen beziehe ich den Text für die Listview direkt aus dem Objekt, die ID ist also beim Start definitiv gesetzt.

Verkürzter Code:
Delphi-Quellcode:
IDataObject = interface( IInterface )
  ['{C94DCAC7-CA42-45D3-95D7-9BC321BA2E2A}']
  procedure Delete;
end;

TAccountData = class( TInterfacedObject )
protected
  FID: Integer;
public
  property ID: Integer read FID write FID;
end;

TAccountDataExtend = class( TAccountData, IDataObject )
public
  procedure Delete;
end;

procedure TFormAccounts.Refresh;
var
  tmp: IInterface;
  i: Integer;
  item: TListItem;
  x: TInterfaceList;
begin
  //Vorgängig Listview aufräumen, Objekte zerstören, Interface Releasen
         
  x:= TInterfaceList.Create;
  try
    GetAllAccounts( x ); //Siehe Funktion unten
    for i:= 0 to x.Count - 1 do begin
      tmp:= x[ i ];
      item:= ListViewMain.Items.Add;
      item.Caption:= IntToStr( TAccountDataExtend( tmp ).ID ); //Zeigt korrekte ID an
      item.Data:= Pointer( tmp );
    end;
  finally
    FreeAndNil( x ); //Ich nehme an die InterfaceList zerstört die Objekte nicht
  end;
end {LoadListView};

procedure GetAllAccounts( _o: TInterfaceList );
var
  tmp: IDataObject;//Oder IInterface?
begin
  for i:= 0 to 4 do begin
    tmp:= TAccountDataExtend.Create;
    TAccountDataExtend( tmp ).FID:= i;
    tmp._AddRef;
    _o.Add( tmp );
  end;
end {GetAllAccounts};


procedure TFormEditBase.ListViewMainClick(Sender: TObject);
var
  obj: IInterface;
  obj3: IDataObject;
begin
  Inherited;
  if ListViewMain.ItemIndex >= 0 then begin
    obj:= IInterface( Pointer( ListViewMain.Selected.Data ));
    if Succeeded( obj.QueryInterface( IDataObject, obj3 )) then begin
      obj3.Delete; //Funktion siehe unten
    end;
  end;
end;

//----------------- TAccountDataExtend
procedure TAccountDataExtend.Delete;
begin
  ShowMessage( IntToStr( FID )); //Gibt immer "0" aus
end {Delete};
Vielen Dank
RedOne

Geändert von RedOne (15. Jul 2010 um 09:39 Uhr)
  Mit Zitat antworten Zitat