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