Forum > LCL
Free a TPanel within a btn click event handler
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