![]() |
TObjectList als Komponente
Hi Leute,
ich habe eine spezialisierte Klasse von TObjectList erstellt. Jetzt möchte ich diese als Komponente haben. Bis dato war meine Vorgehensweise immer diese:
Delphi-Quellcode:
Im Constructor der Komponente wird nun meine TransactionList kreiert und im destruktor wieder zerstört. Alle Zugriffe laufen dann über die Componente. Entweder ich mache FTransactionList öffentlich, oder implementiere Alle Methoden von FTransactionList noch einmal in der Componente im Public Teil.
type
TBaseTransactionList = class(TObjectList) private protected function GetItem(Index: Integer): TTransactionObj; procedure SetItem(Index: Integer; AObject: TTransactionObj); public function Add(AObject: TTransactionObj): Integer; virtual; function Extract(Item: TTransactionObj): TTransactionObj; function Remove(AObject: TTransactionObj): Integer; function IndexOf(AObject: TTransactionObj): Integer; procedure Insert(Index: Integer; AObject: TTransactionObj); function First: TTransactionObj; function Last: TTransactionObj; property Items[Index: Integer]: TTransactionObj read GetItem write SetItem; default; end; TTransactionList = class(TBaseTransactionList) private FBreakTransaction : Boolean; // Flag für Abbruch der Abarbeitung FExecuteTransIndex : Integer; // Index der aktuell in der Abarbeitung befindlichen Transaktion FExecuteTransObj: TTransactionObj; // Transaction-Object, dass gerade abgearbeitet wird (Execute läuft) protected function AddNewTransaction(ADevice : TRemoteDevice; APhone : TBasePhoneObj; Action : TActionObj) : Integer; procedure TransmitNextTransaction; virtual; public Constructor Create; reintroduce; virtual; function GetTransactionObj(ADevice : TRemoteDevice; APhone : TBasePhoneObj) : TTransactionObj; overload; function GetTransactionObj(ADevice : TRemoteDevice; APhoneNumber : String) : TTransactionObj; overload; procedure AddAction(ADevice : TRemoteDevice; APhone : TBasePhoneObj; Action : TActionObj); procedure BreakTransaction; virtual; procedure ExecuteTransaction(APhoneNumber : string); overload; virtual; procedure ExecuteTransaction(ATransaction : TTransactionObj); overload; virtual; procedure ExecuteTransactions; virtual; end; TCompTransactionList = class(TComponent) private FTransactionList : TTransactionList; // Transaktionsliste protected public Constructor Create(AOwner : TComponent); override; Destructor Destroy; override; published end; Nun, ich dächte, das könnte man dann aber auch mit Interfaces haben. Etwa so:
Delphi-Quellcode:
Nun hab ich mir einiges zu Interfaces durchgelesen. Das war soweit auch verständlich. Leider mach ich mir hier ein paar Sorgen das für meinen konkreten Fall korrekt hinzubekommen. Folgende Probleme und Fragen stellen sich mir:
TCompTransactionList = class(TComponent, ITransactionList)
private protected public ........... 1. Kann man so einfach eine abgeleitete ObjectList zum Interface machen? Mein Bsp.:
Delphi-Quellcode:
Ich kann mir nicht so richtig vorstellen, dass das reichen soll. Die Basisklasse TObjectList hat da ja noch ne Menge mehr an Methoden und Eigenschaften.
type
ITransactionList = interface(IInterface) // abgeleitet von IInterface ['{677854F0-525B-4372-9C7A-F87A00A8A117}'] // der GUID des Interface function GetTransactionObj(ADevice : TRemoteDevice; APhone : TBasePhoneObj) : TTransactionObj; overload; function GetTransactionObj(ADevice : TRemoteDevice; APhoneNumber : String) : TTransactionObj; overload; procedure AddAction(ADevice : TRemoteDevice; APhone : TBasePhoneObj; Action : TActionObj); procedure BreakTransaction; virtual; procedure ExecuteTransaction(APhoneNumber : string); overload; virtual; procedure ExecuteTransaction(ATransaction : TTransactionObj); overload; virtual; procedure ExecuteTransactions; virtual; end; Dann die nächste Frage: TComponent ist wohl nicht von IInterfacedObject abgeleitet (glaub ich). Damit müßte das nicht so ohne weiteres klappen:
Delphi-Quellcode:
Tja, wenn mir da einer helfen kann????????
TCompTransactionList = class(TComponent, ITransactionList)
private protected public function GetTransactionObj(ADevice : TRemoteDevice; APhone : TBasePhoneObj) : TTransactionObj; overload; function GetTransactionObj(ADevice : TRemoteDevice; APhoneNumber : String) : TTransactionObj; overload; procedure AddAction(ADevice : TRemoteDevice; APhone : TBasePhoneObj; Action : TActionObj); procedure BreakTransaction; virtual; procedure ExecuteTransaction(APhoneNumber : string); overload; virtual; procedure ExecuteTransaction(ATransaction : TTransactionObj); overload; virtual; procedure ExecuteTransactions; virtual; Gruß oki |
Re: TObjectList als Komponente
Bei Controls die von TComponent abgeleitet sind und damit aufs Formular gelegt werden können und damit einen Parent hat welcher automatisch die Freigabe beim eigenen Zerstören erledigt sollte man mit Interfaces aufpassen, da du hiermit deinem Interface-Zeiger "hinterrücks" das lebende Objekt zerstörst. Hat mir (und Kollegen) schon ein paar Tage Fehlersuche gekostet.
Am besten der Komponenten kein Interface verpassen und erst in internen Objekten mit Interfaces arbeiten. |
Re: TObjectList als Komponente
Hallo Bernhardt,
so dachte ich auch. Deshalb mein bisheriger Ansatz mit der "eingebetteten" Liste. Als ich aber mal bei den Jedis in den Source geschaut habe ist mir aufgefallen, dass dort Componenten teilweise auch Interfaces in der Klassenableitung haben. Richtig hinter gestiegen bin ich da zwar nicht, aber auch daher kommt meine Vermutung, dass man das machen kann. Nun will ich's mir aber auch nicht unnötig kompliziert machen. Ich bin im aktuellen Projekt auch mächtig unter Zeitdruck. Hatte halt die Hoffnung, dass es mit einem Inteface eleganter gelöst werden könnte. Ich lass die Frage noch mal offen, wenn sich nicht interessantes mehr ergibt, erledige ich es auf meine Alt-Hergebrachte-Art. Dank und Gruß oki |
Re: TObjectList als Komponente
Zitat:
Wenn das Property VCLComObject = nil ist, dann wird die Referenzzählung ausser Kraft gesetzt und man kann Objekt- und Interfacereferenzen mischen. Also man kann folgendes schreiben:
Delphi-Quellcode:
TCompTransactionList = class(TComponent, ITransactionList)
... var tl : TComponent; intf : ITransactionList begin tl := TCompTransactionList.Create(nil); ... intf := tl as ITransactionList; intf.ExecuteTransactions; intf := nil; // wir haben Glück, das Objekt tl wird nicht zerstört ... tl.Free; |
Re: TObjectList als Komponente
Hi shmia,
Licht und Schatten liegen so dicht beieinander. Zitat:
Nun wollte ich im Code jedoch nicht meine Zugriffe trennen. Was ich erreichen will ist eigentlich das:
Delphi-Quellcode:
Jo, so dachte ich.
TCompTransactionList = class(TComponent, ITransactionList)
... var tl : TCompTransactionList; begin tl := TCompTransactionList.Create(nil); ... tl.ExecuteTransactions; ... tl.Free; end; Gruß oki |
Alle Zeitangaben in WEZ +1. Es ist jetzt 09:50 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz