Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi TObjectList Object soll sich selbst löschen (https://www.delphipraxis.net/155344-tobjectlist-object-soll-sich-selbst-loeschen.html)

Culxxaw 19. Okt 2010 17:41

TObjectList Object soll sich selbst löschen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo liebe DP-Gemeinde,

Seit einiger Zeit verzweifle ich nun schon an folgendem Problem:

Ich habe eine Scrollbox, die zur Laufzeit mit Panels gefüllt wird. Auf jedem Panel befindet sich ein Button, der das entsprechende Panel wieder aus der Scrollbox herrauslöscht. Das Ganze ist also wie eine Listbox, bei der jedes Panel einem Item entspricht und über einen Löschen-Button verfügt. (Siehe Bild im Anhang)

Die Panels und die Buttons befinden in jeweils einer ObjectListe (TObjectList). Drückt man nun auf den Button, um das entsprechende Item zu löschen, so bekomme ich eine Zugriffsverletzung. Über das OnClick-Ereignis des Buttons kann man zwar das Panel löschen, der Button kann sich aber scheinbar nicht aus seiner eigenen ObjectListe herrauslöschen. Die Zeile
Code:
(Sender as TButton).Free;
im OnClick-Ereignis der Button funktioniert leider genauso wenig.

Der Owner der Panels und Buttons ist die Scrollbox.

Nun ist meine Frage, was ich falsch mache, oder ob es noch eine Möglichkeit gibt soewtwas zu realisieren.

Danke im Voraus!

himitsu 19. Okt 2010 17:56

AW: TObjectList Object soll sich selbst löschen
 
Delphi-Quellcode:
(Sender as TButton).Free;
oder einfach nur
Delphi-Quellcode:
Sender.Free;
funktioniert und gibt das Objekt erfolgreich frei, auch wenn es am Ende eines Button-OnClick aufgerufen wird.

Der Button kennt aber die ObjektListe nicht, bzw. er weiß garnicht daß er in einer Drinsteckt, also kann er sich auch nicht selber aus soeiner Liste rauslöschen.
Das Entfernen aus der Objekliste mußt du also selber machen.

Du könntest dir auch eine eigene komponente von TButton ableiten, den Destructor überschreiben und darin den Button aus der entsprechenden Objektliste entfernen.

So oder so, wenn ein Objekt sich irgendwo rauslöschen soll, sobald es freigegeben wird, dann mußt du diesem die Objektliste bekannt machen (diese in einem Feld in dem Objekt speichern) und beim Freigeben des Objektes prüfen, ob da eine Objektliste eingetragen ist und wenn ja, dann wird das Objekt aus dieser Liste entfernt.
Im Gegenzug muß natürlich auch der Eintrag zurückgesetzt werden, wenn das Objekt aus der Liste entfernt wird, ohne es freizugeben.

Sir Rufo 19. Okt 2010 18:00

AW: TObjectList Object soll sich selbst löschen
 
Folgender Satz beschreibt dein Problem:
Zitat:

Säge nicht an dem Ast auf dem du gerade sitzt!
Das OnClick-Ereignis wird ja von der Button-Instanz selbst aufgerufen und genau diese Instanz schmeißt du aus dem Speicher. Der Rücksprung nach dem OnClick-Ereignis liegt aber nun noch in der Button-Instanz, und die gibt es nicht mehr. Darum der Zugriffsfehler ;)

Das Free muss "außerhalb" erfolgen. Möchte man dieses Event-basiert haben, dann bleibt nur die Verwendung von Hier im Forum suchenPostMessage

Culxxaw 19. Okt 2010 18:14

AW: TObjectList Object soll sich selbst löschen
 
Uffa,
also dass der Button die Objektliste nicht kennt und er sich nicht direkt selbst löschen kann erscheint mir einleuchtend.
Allerdings verstehe ich nicht so ganz, wie ich das "free" außerhalb platzieren soll. Reicht es denn, wenn ich z.b. TButton ableite und im Destructor den Button aus der Objektliste entferne? So z.b.:
Code:
destructor TMyButton.Destroy;
begin
  objektliste.DeleteItem(index);
  inherited;
end;
Denn eigentlich weiß der Button doch immer noch nicht, dass die Objektliste existiert...

shmia 19. Okt 2010 18:40

AW: TObjectList Object soll sich selbst löschen
 
Zitat:

Zitat von Sir Rufo (Beitrag 1056553)
Das Free muss "außerhalb" erfolgen. Möchte man dieses Event-basiert haben, dann bleibt nur die Verwendung von Hier im Forum suchenPostMessage

Hier ist noch etwas Sourcecode dazu.

Culxxaw 19. Okt 2010 18:47

AW: TObjectList Object soll sich selbst löschen
 
Okay vielen Dank an alle! Habs mit Hilfe von Postmessage und dem Link von shmia gemacht und jetzt klappts wunderbar.:)

himitsu 19. Okt 2010 19:47

AW: TObjectList Object soll sich selbst löschen
 
Zitat:

Säge nicht an dem Ast auf dem du gerade sitzt!
Prinzipiell trifft das zu, aber

OnClick wird von Delphi-Referenz durchsuchenApplication, bzw. von der Message-Loop darin aufgerufen.
Nach dem Ausführen von OnClick wird nicht nochmal auf den Sender zugegriffen.

Darum "kann" man, in diesem Fall, den Sender auch löschen,
da man quasi auf einem anderem Ast sitzt.

Zitat:

Reicht es denn, wenn ich z.b. TButton ableite und im Destructor den Button aus der Objektliste entferne?
sollte reichen
Zitat:

Denn eigentlich weiß der Button doch immer noch nicht, dass die Objektliste existiert...
Darum mußt du ja dem Button diese Liste vorher mitteilen und er merkt sie sich bis dahin.

Oder es gibt nur eine "globale" Liste, wo er sich dann rauslöscht.

Sir Rufo 19. Okt 2010 20:51

AW: TObjectList Object soll sich selbst löschen
 
Zitat:

Zitat von himitsu (Beitrag 1056578)
Zitat:

Säge nicht an dem Ast auf dem du gerade sitzt!
Prinzipiell trifft das zu, aber

OnClick wird von Delphi-Referenz durchsuchenApplication, bzw. von der Message-Loop darin aufgerufen.
Nach dem Ausführen von OnClick wird nicht nochmal auf den Sender zugegriffen.

Darum "kann" man, in diesem Fall, den Sender auch löschen,
da man quasi auf einem anderem Ast sitzt.

Ich glaube du hast dann ein anderes Delphi als ich.
Bei mir sieht das so aus:

Zitat:

Zitat von Controls.pas
Delphi-Quellcode:
procedure TControl.WMLButtonUp(var Message: TWMLButtonUp); // Hier wird die Nachricht verarbeitet und Click aufgerufen

procedure TControl.Click; // und hier macht es klick

Irgendwie fehlt mir das Application da (gut das ist immer irgendwo) aber für mich erfolgt der Aufruf aus der Instanz vom Button aufgerufen.

stahli 19. Okt 2010 21:12

AW: TObjectList Object soll sich selbst löschen
 
Nachfolgendes Projekt macht bei mir keine Probleme.
Wichtig ist wohl nur, ob der Komponentencode nochmal auf "Self" zugreift.
Wenn nicht, gibt es keine Probleme.


Delphi-Quellcode:
unit fFreeTest;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    Button5: TButton;
    Button6: TButton;
    Button7: TButton;
    Button8: TButton;
    Button9: TButton;
    Button10: TButton;
    procedure ButtonClick(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ButtonClick(Sender: TObject);
begin
  FreeAndNil(Sender);
end;

end.

himitsu 19. Okt 2010 22:16

AW: TObjectList Object soll sich selbst löschen
 
Zitat:

Zitat von stahli (Beitrag 1056595)
Nachfolgendes Projekt macht bei mir keine Probleme.
Wenn nicht, gibt es keine Probleme.

Auch wenn FreeAndNil unnötig ist, da der Parameter Sender eh nicht wiederverwendet, bzw. nachfolgen genutzt wird. (.Free würde reichen, aber schlimm isses nicht)

Zitat:

Zitat von stahli (Beitrag 1056595)
Wichtig ist wohl nur, ob der Komponentencode nochmal auf "Self" zugreift.

Self ist in diesem Fall die Form.

PS: In Ereignisprozedur wie OnClose die Form freizugeben ist da schon schwerer.

Zitat:

Irgendwie fehlt mir das Application da (gut das ist immer irgendwo)
Delphi-Quellcode:
Application.Run;
(siehe .dpr), bzw. genauer die
Delphi-Quellcode:
TApplication.ProcessMessage
behandelt die Window-Messages, und von dort aus wird letztendlich dein
Delphi-Quellcode:
procedure WMLButtonUp(var Message: TWMLButtonUp); message WM_LBUTTONUP;
aufgerufen.




Wie gesagt, einen Button in seinem OnClick freizugeben ist kein Problem.


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:53 Uhr.
Seite 1 von 2  1 2      

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