Delphi-PRAXiS
Seite 2 von 4     12 34      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TObjectList.Free erzeugt AV (https://www.delphipraxis.net/183819-tobjectlist-free-erzeugt-av.html)

SvB 6. Feb 2015 20:52

AW: TObjectList.Free erzeugt AV
 
Sorry, ich bin nicht der 100%ige Delphi-Crack.

Wenn ich das jetzt richtig verstanden habe, dann müsste ich ja sinnvollerweise meine TObjectList informieren, wenn irgendein TComponent entfernt wird, damit es dann aus der Liste fliegt. Vielleicht ist es jetzt auch einfach zu spät.

Ne, anders. Damit das mit FreeNotification funktioniert (TComponent), müsste ich das in mein Hauptformular implementieren, in dem ich die Unterformulare in die Liste stecke und dort dann im OnFreeNotification es aus der Liste entferne. (oder so ähnlich)

Ja, ich glaube, ich habs so langsam verstanden. Das schaue ich mir aber morgen noch mal genau an. Jetzt ist erst mal Feierabend.

Sir Rufo 6. Feb 2015 20:56

AW: TObjectList.Free erzeugt AV
 
Delphi-Referenz durchsuchenTComponent.Notification überschreiben und
Delphi-Quellcode:
Operation
beachten ;)

himitsu 7. Feb 2015 03:15

AW: TObjectList.Free erzeugt AV
 
Delphi-Quellcode:
type
  TComponentList<T: TComponent> = class(TObjectList<T>)
  private type
    TNotify = class(TComponent)
      FParent: TComponentList<T>;
      procedure Notification(AComponent: TComponent; Operation: TOperation); override;
    end;
  private
    FNotify: TNotify;
  protected
    procedure Notify(const Value: T; Action: TCollectionNotification); override;
  public
    destructor Destroy; override;
  end;

destructor TComponentList<T>.Destroy;
begin
  FNotify.Free;
  inherited;
end;

procedure TComponentList<T>.Notify(const Value: T; Action: TCollectionNotification);
begin
  inherited;
  if not Assigned(FNotify) then begin
    FNotify := TNotify.Create(nil);
    FNotify.FParent := Self;
  end;
  if Action = cnAdded then
    FNotify.FreeNotification(Value)
  else if not Contains(Value) then
    FNotify.RemoveFreeNotification(Value);
end;

procedure TComponentList<T>.TNotify.Notification(AComponent: TComponent; Operation: TOperation);
begin
  inherited;
  if (Operation = opRemove) and not FParent.Contains(AComponent) then
    while FParent.Extract(AComponent) <> nil do ;
end;
Aber wenn man sowieso schon eine Owner- oder Parent-Beziehung hat, dann kann man sich eigentlich auch die zusätzliche Liste sparen, indem man die bereits existierenden Parent.Components- oder Parent.Controls-Listen mit benutzt.


Das Einzige, was ich mich bei Entwicklung dieser Liste gefragt hatte ..... wer zum Teufel war so wirklich saudämlich und hat vergessen das TList<T>.Create(), oder besser schon TEnumerable<T>.Create(), als virtual zu deklarieren, so daß man in Nachfahren ständig immer alle Konstrutoren überschreiben muß, wenn man da drin irgendwas initialisieren wöllte. :wall:

Ach ja, und wer bei den FreeNotifications keine Registrierungszählung implementierte ... mehrere Verbindungen zwischen den selben Komponenten und man muß mit dem RemoveFreeNotification aufpassen.

Genau deswegen setzte ich gern eine gekapselte Notify-Komponente ein, wenn ich nicht kontrollieren kann, ob zwischen referenzierenden Komponenten eventuell noch andere Referenzen, wie z.B. die Parent- oder Owner-Beziehungen existieren könnten.
Alternativ könnte man nur registrieren (FreeNotification) und dürfte nie deregistrieren (RemoveFreeNotification), außer mal selber wird freigegeben, aber dann räumt sich das eh von selber auf.

Sir Rufo 7. Feb 2015 08:08

AW: TObjectList.Free erzeugt AV
 
@himitsu

Und warum überschreibst du nicht Delphi-Referenz durchsuchenTObject.AfterConstruction?

jaenicke 7. Feb 2015 08:28

AW: TObjectList.Free erzeugt AV
 
Zitat:

Zitat von himitsu (Beitrag 1289101)
Das Einzige, was ich mich bei Entwicklung dieser Liste gefragt hatte ..... wer zum Teufel war so wirklich saudämlich und hat vergessen das TList<T>.Create(), oder besser schon TEnumerable<T>.Create(), als virtual zu deklarieren, so daß man in Nachfahren ständig immer alle Konstrutoren überschreiben muß, wenn man da drin irgendwas initialisieren wöllte. :wall:

Da hätte noch viel mehr virtuell deklariert werden müssen, auch bei den anderen generischen Standardklassen...
Ich überschreibe in so einem Fall meistens AfterConstruction und BeforeDestruction, was ja seit Delphi 4 für diesen Zweck existiert (wenn etwas nicht im Konstruktor gemacht werden kann)...

// EDIT:
Ja, genau... ich hatte die Antwortbox dank meines Sohnes wohl etwas zu lange offen. :D

himitsu 7. Feb 2015 11:34

AW: TObjectList.Free erzeugt AV
 
Nja. Dafür gibt es so eine Methode weniger. :oops:

Aber mal ganz im Ernst, nun weil das nicht virtuell ist, haben die in TObjectList alle drei Konstructoren überschreiben müssen, obwohl es gereicht hätte, das Neue im nur Create() zu machen, da in den anderen zwei Konstructoren nichts anderes drin steht.

Delbor 7. Feb 2015 11:41

AW: TObjectList.Free erzeugt AV
 
Hi zusammen

Hab ich das jetzt richtig gelesen? Du erzeugst Unterformulare und weist diesen deine Hauptform als Eigner Zu?
Zitat:

Die Unterformulare habe ich auf Position = poOwnerFormCenter eingestellt, und wollte die dann schön zentriert über dem Hauptformular anzeigen lassen. Das funktioniert nur, wenn die Unterformulare mit Owner = Hauptformular erzeugt werden.
Wenn ich dann das Hauptformular schließe, dann werden durch den Owner auch die Unterformulare aufgeräumt und danach wird Interfaced ObjectList automatisch aufgeräumt und es gibt die Exception.
Wenn das Hauptformular beendet wird, räumt es seine Unterformulare auf. Du hast nun mehrere Möglichkeiten:
  • Setze die Vorschläge meiner Vorredner um
  • Setze Ownerobject der Liste auf False
  • Schmeiss diie Liste raus, wenn du da keine weiteren Objcte ablegst, ansonsten
  • fügst du der Liste die Unterformulare nicht hinzu

Gruss
Delbor

Sir Rufo 7. Feb 2015 11:49

AW: TObjectList.Free erzeugt AV
 
Wenn es nur um das Aufräumen geht, dann braucht man die Liste nicht, für andere Dinge schon ;)

Delbor 7. Feb 2015 12:11

AW: TObjectList.Free erzeugt AV
 
Hi Sir Rufo

Schon klar - eine einzige solche Liste kann mehrere dutzend(?) Zeilen Quelltext einsparen .

Gruss
Delbor

SvB 7. Feb 2015 12:34

AW: TObjectList.Free erzeugt AV
 
Moin,

neuer Tag neues Glück und die Sonne scheint, da kann es ja nur besser werden.

Meine Idee hinter der ObjectList (Interface) ist, dass auf jeden Fall beim schließen des Hauptformulars alles aufgeräumt wird. Es sind nicht nur die Unterformulare, sondern auch andere Objekte wie Stringlisten, die in der ObjectList liegen. Falls mal, was auch immer, passiert, soll aufgeräumt werden. Die Anwender erzählen einem ja nicht immer alles, oder man selbst hat beim programmieren irgend einen Mist gebaut.
Bisher war es kein Problem, die Objekte in die Liste zu schieben.

Nun, jetzt wollte ich die schöne Funktion Position = poOwnerFormCenter für die Unterformulare verwenden, die jedoch mit einem Owner erzeugt werden müssen, damit das funktioniert. Das gab dann natürlich das Problem mit den 2 Ownern, einmal Hauptformular und einmal Liste. Deshalb die AV durch die Liste, weil das Hauptformular schon früher aufgeräumt hat.

Nach dem ich mal ne Nacht drüber geschlafen habe, habe ich mich fürs Erste für folgende Lösung entschieden:
Es bleibt erst mal alles in der Liste, und die räumt später auf.
Und ich habe mir einen ClassHelper geschrieben:
Delphi-Quellcode:
TShowModalCenter = class helper for TForm
  procedure ShowModalCenter(ACenterForm: TForm);
end;

procedure TShowModalCenter.ShowModalCenter(ACenterForm: TForm);
var
  X, Y: Integer;
begin
  X := ((ACenterForm.Width - Width) div 2) + ACenterForm.Left;
  Y := ((ACenterForm.Height - Height) div 2) + ACenterForm.Top;
  if X < Screen.DesktopLeft then
    X := Screen.DesktopLeft;
  if Y < Screen.DesktopTop then
    Y := Screen.DesktopTop;
  SetBounds(X, Y, Width, Height);
  ShowModal;
end;
Die Unterformulare rufe ich jetzt nicht mehr nur einfach mit ShowModal auf, sondern mit ShowModalCenter(Hauptform) und habe erst mal das erreicht was ich eigentlich wollte.

Eure Infos und Ideen muss ich mir aber auch noch mal durch den Kopf gehen lassen. Hab da im Moment nicht so viel Zeit, muss am Montag ne erste Version abliefern und hübsch kann ichs danach noch machen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:08 Uhr.
Seite 2 von 4     12 34      

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