[gelöst] Panel mit Button zur Laufzeit löschen

Rund um die LCL und andere Komponenten
Antworten
catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

[gelöst] Panel mit Button zur Laufzeit löschen

Beitrag von catweasel »

Hallo

Ich versuche zur Zeit durch einen Button-klick ein Panel mit einem weiteren Button darauf zu erstellen.
Das funktioniert soweit.

Problematisch ist, daß der zur Laufzeit erstellte Button das Panel und sich selbst wieder löschen soll.
Das endet bei mir leider in einem Fehler "..Exception-Klasse External..."

Ich kann mir vorstellen das es so nicht möglich ist das sich ein Button quasi selbst löscht, bezieungsweise das ja eigentlich über das Panel passiert
Wie kann ich das Problem aber lösen?

Gruß
Michael

Das ist mein Code (Auf der Oberfläche ist nur ein einfacher Button (Button1), der Rest wird zur Laufzeit erstellt.

Code: Alles auswählen

unit Unit1;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;
 
type
 
  { TForm1 }
 
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure LaufzeitButtonOnClick(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.lfm}
 
{ TForm1 }
  
 
// Panel und Button zur Laufzeit erstellen
procedure TForm1.Button1Click(Sender: TObject);
var
  Panel : TPanel;
  Button: TButton;
begin
  // Panel zur Laufzeit erstellen
  Panel:=TPanel.Create(Self);
  Panel.Parent   := Self;
  Panel.Width    := 300;
  Panel.Left     := 0;
  Panel.Top      := 0;
 
  // Button auf Panel zu Laufzeit erstellen
  Button := TButton.Create(Panel);
  Button.Parent  := Panel;
  Button.Width   := 100;
  Button.Caption := 'Lösche Panel';
  Button.OnClick := @LaufzeitButtonOnClick;
end;
 
// Panel und Button löschen
procedure TForm1.LaufzeitButtonOnClick(Sender: TObject);
begin
  TButton(Sender).Owner.Free;
end;
 
end.
Zuletzt geändert von catweasel am Mi 13. Dez 2017, 17:52, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Panel mit Button zur Laufzeit löschen

Beitrag von theo »

Ich glaube ein Application.QueueAsyncCall müsste das leisten:

http://wiki.freepascal.org/Asynchronous_Calls

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Panel mit Button zur Laufzeit löschen

Beitrag von Mathias »

Problematisch ist, daß der zur Laufzeit erstellte Button das Panel und sich selbst wieder löschen soll.
Das endet bei mir leider in einem Fehler "..Exception-Klasse External..."

Ich habe deinen Code 1 zu 1 übernommen, unter Linux funktioniert es wunderbar, zum Test habe ich noch Lazarus unter Wine probiert, da bekomme ich auch den SIGSEV.

Nicht mal den Button alleine kann entfernt werden.

Code: Alles auswählen

  TButton(Sender).Free; 


Anscheinend springt er unter Windows nach ausführen von LaufzeitButtonOnClick, nochmals zum Button zurück, welchen es unterdessen nicht mehr gibt.

Ich glaube ein Application.QueueAsyncCall müsste das leisten:
Was hat die mit dem Problem zu tun ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Panel mit Button zur Laufzeit löschen

Beitrag von theo »

Mathias hat geschrieben:Was hat die mit dem Problem zu tun ?

Steht im Link oben, wenn man die paar Wörter Englisch versteht?

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Panel mit Button zur Laufzeit löschen

Beitrag von catweasel »

theo hat geschrieben:Ich glaube ein Application.QueueAsyncCall müsste das leisten:

http://wiki.freepascal.org/Asynchronous_Calls
Ich habe mir das Beispiel angesehen, verstehe aber nicht was ich dann bei meinem Programm anpassen muß.
Einfach TQueueAsyncCallForm statt TForm1 reicht nicht um wenigstens erst einmal beim StatusQuo zu bleiben.
Hier bekomme ich beim Start eine Meldung "...Exception-Klasse EResNotFound..." und weiter unten "...TQueueAsyncCallForm not found..."

Ich habe das jetzt mit einem weiteren, nicht zur Laufzeit erstellten, Button2 gelöst.
Ist zwar nicht exakt was ich ursprünglich wollte, aber deswegen nennt man es ja auch "Entwicklung"... :lol:

Trotzdem Danke an alle
Gruß
Michael

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: Panel mit Button zur Laufzeit löschen

Beitrag von theo »

catweasel hat geschrieben:Ich habe mir das Beispiel angesehen, verstehe aber nicht was ich dann bei meinem Programm anpassen muß.


Code: Alles auswählen

procedure TForm1.FormCreate(Sender: TObject);
var
  abtn: TButton;
begin
  abtn := TButton.Create(nil);
  abtn.Parent := self;
  abtn.Caption := 'Lösch mich';
  abtn.OnClick := @abtnClick;
end;
 
procedure TForm1.abtnClick(Sender: TObject);
begin
  Application.QueueAsyncCall(@FreeObj, PtrUInt(Sender));
end;
 
procedure TForm1.FreeObj(Data: PtrInt);
begin
  TObject(Data).Free;
end;     
 

catweasel
Beiträge: 230
Registriert: Di 17. Mär 2009, 10:51
OS, Lazarus, FPC: Win10 64Bit // Linux Mint 20.0 - (L 2.2.0 FPC 3.2.2)

Re: Panel mit Button zur Laufzeit löschen

Beitrag von catweasel »

Danke, das schaue ich mir an

Gruß
Michael

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: [gelöst] Panel mit Button zur Laufzeit löschen

Beitrag von mse »

Dazu hat Lazarus eine spezielle Funktion:
http://lazarus-ccr.sourceforge.net/docs ... onent.html

Benutzeravatar
theo
Beiträge: 10467
Registriert: Mo 11. Sep 2006, 19:01

Re: [gelöst] Panel mit Button zur Laufzeit löschen

Beitrag von theo »

mse hat geschrieben:Dazu hat Lazarus eine spezielle Funktion:
http://lazarus-ccr.sourceforge.net/docs ... onent.html


Ja stimmt, das geht auch und ist einfacher in der Anwendung. Der Effekt dürfte der Gleiche sein.

Antworten