Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Button Selbstzerstörung (https://www.delphipraxis.net/186338-button-selbstzerstoerung.html)

weisswe 25. Aug 2015 11:23

Button Selbstzerstörung
 
Hallo!

Habe folgende Aufgabenstellung:
a) Erstelle dynamische Buttons auf einem Layout
b) Beim Klick auf einen der neu generieren Buttons führe Schritt a) aus
Klar ist, das ich beim Freigeben auch den aktuell geklickten Button zerstören muss -> Exception -> logisch
Wie kann man das "umschiffen"?

Delphi-Quellcode:
type barray = Array of TButton;
var btns: barray;

procedure TForm1.abtnClick(Sender: TObject);
var i: Integer;
begin
   for i := length(btns) - 1 downto 0 do btns[i].Free;
   SetLength(btns, 0);
   for i := 0 to random(9) + 1 do
   begin
      btns[i] := TButton.Create(nil);
      btns[i].name := 'abutton' + IntToStr(i);
      btns[i].text := 'Button' + IntToStr(i+1);
      btns[i].Parent := GridLayout1;
      btns[i].OnClick := abtnClick;
   end;
end;

TiGü 25. Aug 2015 11:27

AW: Button Selbstzerstörung
 
Delphi-Quellcode:
if Sender = deinButton then
  NichtZerstören;

weisswe 25. Aug 2015 11:57

AW: Button Selbstzerstörung
 
Zitat:

Zitat von TiGü (Beitrag 1313419)
Delphi-Quellcode:
if Sender = deinButton then
  NichtZerstören;

Aber ich möchten ja auch den gedrückten Button zerstören!?

Der schöne Günther 25. Aug 2015 12:04

AW: Button Selbstzerstörung
 
Ich verstehe das hinten und vorne nicht. Ein OnClick-Event eines Buttons kann doch den Button ganz normal zerstören? Schreib doch einfach mal in das
Delphi-Quellcode:
OnClick
-Event eines normalen Buttons
Delphi-Quellcode:
Sender.Destroy()
. Wo soll denn da die Exception sein?

Wo ich eher eine Exception sehe ist hier:
Delphi-Quellcode:
   SetLength(btns, 0);
    for i := 0 to random(9) + 1 do
    begin
       btns[i] := TButton.Create(nil);
[...]
Wie soll das funktionieren? Du setzt das Array (unnötigerweise) auf Länge Null und fängst dann an, darin herumzuschreiben.

DeddyH 25. Aug 2015 12:14

AW: Button Selbstzerstörung
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1313427)
Ein OnClick-Event eines Buttons kann doch den Button ganz normal zerstören?

Diesem Gedankenfehler war ich neulich für ein FMX.TListViewItem auch erlegen. Das Dumme ist, dass dort ggf. der Click-Handler ausgeführt, danach aber mit der Instanz weiter hantiert wird. Letztere ist aber nicht mehr da, wenn sie im OnClick freigegeben wird -> *Rumms*.

stahli 25. Aug 2015 12:17

AW: Button Selbstzerstörung
 
Die OnClick-Behandlung veranlasst ja noch der Button selbst.
Nach Erledigung kommt der Programmablauf wieder zurück zum Button.
Was dann passiert kannst Du nicht beeinflussen. Vielleicht will Windows den Button jetzt nochmal zeichnen o.ä. - und plötzlich ist er weg ;-)
Also der bisherige Speicherbereich ist undefiniert.

Ein Workaround wäre, den Button unsichtbar zu machen und irgendwo zu merken (in einer Liste oder globalen Variable o.ä.).
Dann kannst Du etwas später, wenn mal Zeit ist (und Windows garantiert nicht mehr benutzt), diesen freigeben.
Also so etwas wie einen Papierkorb bauen, der immer mal geleert wird.

Sonst wäre auch möglich, eine Message an den Button zu senden, der ihn veranlasst, sich freizugeben.
Dazu gab es schon Beiträge in der DP.

Mavarik 25. Aug 2015 12:29

AW: Button Selbstzerstörung
 
Zitat:

Zitat von TiGü (Beitrag 1313419)
Delphi-Quellcode:
if Sender = deinButton then
  NichtZerstören;

Fast...

Delphi-Quellcode:
type barray = Array of TButton;
var btns: barray;

procedure TForm1.abtnClick(Sender: TObject);
var
  i: Integer;
  MichNicht:TButton;
begin
  for i := length(btns) - 1 downto 0 do
    if TButton(Sender) = self
      then btns[0] := btns[i]
      else btns[i].Free;

  for i := 1 to random(9) + 1 do
    begin
       btns[i] := TButton.Create(nil);
       btns[i].name := 'abutton' + IntToStr(i);
       btns[i].text := 'Button' + IntToStr(i+1);
       btns[i].Parent := GridLayout1;
       btns[i].OnClick := abtnClick;
    end;
end;
:stupid:

Sir Rufo 25. Aug 2015 12:43

AW: Button Selbstzerstörung
 
Mit dem IdleWorker (s. da -> http://www.delphipraxis.net/1305417-post11.html) geht das einfach so
Delphi-Quellcode:
uses
  IdleWorker;

procedure TForm1.abtnClick(Sender: TObject);
begin
  TIdleWorker.Default.Execute(
    procedure
    var
      i: Integer;
    begin
      // alte Buttons entsorgen
      for i := low(btns) to high(btns) do
        btns[i].Free; // ein DisposeOf wäre hier besser

      // neue Länge für das Array
      SetLength(btns, random(9) + 1 );

      // neue Buttons erzeugen
      for i := low(btns) to high(btns) do
      begin
        btns[i] := TButton.Create(nil);
        btns[i].name := 'abutton' + IntToStr(i);
        btns[i].text := 'Button' + IntToStr(i+1);
        btns[i].Parent := GridLayout1;
        btns[i].OnClick := abtnClick;
      end;
    end );
end;

weisswe 25. Aug 2015 12:50

AW: Button Selbstzerstörung
 
Zitat:

Zitat von Sir Rufo (Beitrag 1313437)
Mit dem IdleWorker (s. da -> http://www.delphipraxis.net/1305417-post11.html) geht das einfach so

Einfach nur perfekt!!! :thumb:

DANKE Sir Rufo!!!

Mavarik 25. Aug 2015 12:57

AW: Button Selbstzerstörung
 
Zitat:

Zitat von Sir Rufo (Beitrag 1313437)
Mit dem IdleWorker (s. da -> http://www.delphipraxis.net/1305417-post11.html) geht das einfach so

Logisch - vorausgesetzt die Application ist nicht anderweitig beschäftigt...


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:19 Uhr.
Seite 1 von 3  1 23      

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