AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

TObjectList als Komponente

Offene Frage von "oki"
Ein Thema von oki · begonnen am 4. Dez 2007 · letzter Beitrag vom 4. Dez 2007
Antwort Antwort
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#1

TObjectList als Komponente

  Alt 4. Dez 2007, 08:00
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:
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;
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.
Nun, ich dächte, das könnte man dann aber auch mit Interfaces haben.

Etwa so:
Delphi-Quellcode:
  TCompTransactionList = class(TComponent, ITransactionList)
  private
  protected
  public
    ...........
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:

1. Kann man so einfach eine abgeleitete ObjectList zum Interface machen?
Mein Bsp.:
Delphi-Quellcode:
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;
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.

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:
  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;
Tja, wenn mir da einer helfen kann????????


Gruß oki
42
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.196 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: TObjectList als Komponente

  Alt 4. Dez 2007, 09:05
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.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#3

Re: TObjectList als Komponente

  Alt 4. Dez 2007, 09:14
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
42
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#4

Re: TObjectList als Komponente

  Alt 4. Dez 2007, 10:59
Zitat von oki:
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.
Ja, TComponent implementiert das Interface IUnknown auf spezielle Weise.
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;
Andreas
  Mit Zitat antworten Zitat
oki

Registriert seit: 30. Dez 2002
Ort: Brandshagen
1.819 Beiträge
 
Delphi 2007 Professional
 
#5

Re: TObjectList als Komponente

  Alt 4. Dez 2007, 11:06
Hi shmia,

Licht und Schatten liegen so dicht beieinander.
Zitat:
a, TComponent implementiert das Interface IUnknown auf spezielle Weise.
Wenn das Property VCLComObject = nil ist, dann wird die Referenzzählung ausser Kraft gesetzt und man kann
Objekt- und Interfacereferenzen mischen.
soweit das, worauf ich gehofft habe.

Nun wollte ich im Code jedoch nicht meine Zugriffe trennen. Was ich erreichen will ist eigentlich das:
Delphi-Quellcode:
TCompTransactionList = class(TComponent, ITransactionList)
...
var
   tl : TCompTransactionList;
begin
   tl := TCompTransactionList.Create(nil);
   ...
   tl.ExecuteTransactions;
   ...
   tl.Free;
end;
Jo, so dachte ich.

Gruß oki
42
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz