Forum > LCL

Free a TPanel within a btn click event handler

(1/3) > >>

phoenix27:
At runtime i create a TPanel which contains a TscrollBox and a TButton to close the TPanel itself.
Now, i get an abstract error when i close the TPanel within the TButton click event handler and i sort of understand it, because you can' t remove a button(whose owner is the TPanel) within its click event. A solution would be to make the TPanel a global variable or a field member of its parent and then create a timer in the click event which would remove it without errors. Is there another solution?

phoenix27:
Another thing. If i create a TTimer at runtime in order to remove the TPanel, how do i free it after it has absolved its duty? I cannot do that in the OnTimer event handler, right? It's the same problem as with the TButton click event. Bahh

phoenix27:
And another thing.(How many ahaha). In an event handler usually there is the sender parameter which you can cast to obtain the real control. How can i store the address of the real control, not the variable? For example:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.ButtonOnClick(Sender: TObject);var   pnl: TPanel;begin   pnl := Sender as TPanel;   //let's suppose i have a Pointer ptr somewhere   ptr := @pnl; // wrong because after the procedure exits that pointer will point to garbage   //if i do   ptr := pnl; // i tried but it doesn't work, i thought pnl is a pointer under the hoodend; So how can i get the real address of the panel? Is there a way to get it and store it in a pointer variable?

KodeZwerg:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls; type   TMyPanel = record    Panel: TPanel;    Button: TButton;    // and whatever else  end;  TMyPanels = array of TMyPanel;   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);  strict private    Panels: TMyPanels;  private    procedure AddPanel(const AOwner: TComponent; const AParent: TWinControl);    procedure PanelClick(Sender: TObject);  public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.Button1Click(Sender: TObject);begin  AddPanel(nil, Self);end; procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);var  i: Integer;begin  for i := High(Panels) downto Low(Panels) do    Panels[i].Panel.Free;end; procedure TForm1.AddPanel(const AOwner: TComponent; const AParent: TWinControl);var  i: Integer;begin  i := Length(Panels);  SetLength(Panels, Succ(i));  Panels[i].Panel := TPanel.Create(AOwner);  try    Panels[i].Panel.Parent := AParent;    Panels[i].Panel.Align := alTop;    Panels[i].Panel.Height := 25;    Panels[i].Panel.Tag := i;    Panels[i].Button := TButton.Create(Panels[i].Panel);    try      Panels[i].Button.Parent := Panels[i].Panel;      Panels[i].Button.Align := alRight;      Panels[i].Button.Caption := 'Close';      Panels[i].Button.Width := 80;      Panels[i].Button.OnClick := @PanelClick;      Panels[i].Button.Tag := i;    finally    end;  finally    Panels[i].Panel.Visible := True;  end;end; procedure TForm1.PanelClick(Sender: TObject);var  i: Integer;begin  if Sender is TButton then    begin      i := (Sender as TButton).Tag;      Panels[i].Panel.Free;      Delete(Panels, i, 1);    end;end; end.

avk:
This simpler version also seems to work:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    procedure Button1Click(Sender: TObject);  private    procedure TryFreeOwner(Sender: TObject);  public   end; var  Form1: TForm1; implementation {$R *.lfm} { TForm1 } procedure TForm1.TryFreeOwner(Sender: TObject);begin  if (Sender is TComponent) and (TComponent(Sender).Owner <> nil) then    TComponent(Sender).Owner.Free  else    Sender.Free;end; procedure TForm1.Button1Click(Sender: TObject);var  Panel: TPanel;  Button: TButton;begin  Panel := TPanel.Create(Self);  Panel.Left := 5 + Random(10) * 2;  Panel.Top := 5 + Random(10) * 2;  Panel.Height := 100;  Panel.Width := 100;  Button := TButton.Create(Panel);  Button.Left := 10;  Button.Top := 10;  Button.Caption := 'Close';  Button.OnClick := @TryFreeOwner;  Button.Parent := Panel;  Panel.Parent := Self;end; end. 

Navigation

[0] Message Index

[#] Next page

Go to full version