Recent

Author Topic: Use of ReleaseComponent  (Read 1499 times)

valter.home

  • Jr. Member
  • **
  • Posts: 75
Use of ReleaseComponent
« on: May 02, 2021, 03:47:27 pm »
I need to delete a component by clicking on it. I think I have found the solution but I would like someone to confirm that it is correct to avoid anomalous behavior of the application.
I have a TScrollBox in which the user can create TPanels at runtime which can contain other different components.
In each of them a TSpeedButton is created which allows to eliminate the TPanel with all its contents.

This is a part of the code when creating the TPanel

Code: Pascal  [Select][+][-]
  1.   NewBtn := TSpeedButton.Create(NewPanel);
  2.   NewBtn.Parent:=NewPanel;
  3.   NewBtn.Align:=AlLeft;
  4.   NewBtn.Images:=ImageList1;
  5.   NewBtn.ImageIndex:=4;
  6.   NewBtn.BorderSpacing.Left:=2;
  7.   NewBtn.BorderSpacing.Right:=2;
  8.   newbtn.Name:='btn'+dt;
  9.   newbtn.OnClick:=@RemovePanel;


and this is the onclick event of the TSpeedButton

Code: Pascal  [Select][+][-]
  1. var
  2.   Mypanel: TComponent;
  3.   Str, Search: string;
  4.   Ssender: TSpeedButton;
  5. begin
  6.   with Sender as TSpeedButton do
  7.   begin
  8.     Ssender := Sender as TSpeedButton;
  9.     Str:=StringReplace(Ssender.Name, 'btn', '', [rfIgnoreCase, rfReplaceAll]);
  10.     Search := 'Panel'+Str;
  11.     Mypanel := Scrollbox1.FindComponent(Search);
  12.     FreeAndNil(Mypanel);
  13.     // Application.ReleaseComponent(Ssender);
  14.   end;
  15. end;

If after executing this code I search with FindComponent for the TSpeedButton it is still assigned even though it is no longer visible.
If I uncomment the ReleaseComponent the TSpeedButton seems to no longer exist.
All components created in the panel have the panel itself as owner and parent, so deleting the panel should also delete all its children.
But the ReleaseComponent is still in the event of the TSpeedButton, so is it correct to delete it this way?

lainz

  • Hero Member
  • *****
  • Posts: 3828
Re: Use of ReleaseComponent
« Reply #1 on: May 02, 2021, 04:17:13 pm »
Have you tried it?

Remember that assigned will return true if the variable is not set to nil like when using freeandnil.

What I do is with a notify event pass the deletion of the control to the parent container, the container that will not be removed. And I just free the control myself so no need to use release component.

valter.home

  • Jr. Member
  • **
  • Posts: 75
Re: Use of ReleaseComponent
« Reply #2 on: May 02, 2021, 04:54:30 pm »
Quote
Have you tried it?

Yes, it would seem to work but I was wondering if it couldn't create random problems.

I used this code for verification

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.Button1Click(Sender: TObject);
  2. var
  3.   SearchButton: TComponent;
  4.   BtnName: string;
  5. begin
  6.   BtnName := Edit1.Text;
  7.   SearchButton := FindComponent(BtnName);
  8.   if assigned(SearchButton) then
  9.     memo1.lines.add('The button exists')
  10.   else
  11.     memo1.lines.add('The button does not exist');
  12. end;

Since if I delete the panel that contains the TSpeedButton I no longer know how to access it to verify its existence, I changed this line in the creation of the panel

from
Code: Pascal  [Select][+][-]
  1. NewBtn := TSpeedButton.Create(NewPanel);
to
Code: Pascal  [Select][+][-]
  1. NewBtn := TSpeedButton.Create(self);

Now when the panel exists the above code confirms the existence of the TSpeedButton, when I delete the panel also the TSpeedButton is no longer found.

Do you think this is not the right way?



lucamar

  • Hero Member
  • *****
  • Posts: 4160
Re: Use of ReleaseComponent
« Reply #3 on: May 02, 2021, 05:17:40 pm »
If the panel is the Owner of the button you don'r need to use ReleaseComponent. That's what being Owner means: the panel is responsible for the lifetime of its owned components; free it and it will in turn free them.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

valter.home

  • Jr. Member
  • **
  • Posts: 75
Re: Use of ReleaseComponent
« Reply #4 on: May 02, 2021, 06:00:53 pm »
Thank you,
so if I have a MyPanel panel with a TButton created like this

Code: Pascal  [Select][+][-]
  1. NewBtn := TButton.Create(MyPanel);
  2. NewBtn.Parent:=MyPanel;
  3. NewBtn.OnClick:=@RemovePanel;

if I use in the RemovePanel procedure

Code: Pascal  [Select][+][-]
  1. FreeAndNil(MyPanel);

will also remove the TButton even though we are still in its event?
Actually, if I search for it then I can't find it but it seemed to me that I saw around that it was not correct to remove a Parent using an event of one of his children just because the child depends on the parent.

Thanks so much



lainz

  • Hero Member
  • *****
  • Posts: 3828
Re: Use of ReleaseComponent
« Reply #5 on: May 02, 2021, 07:43:49 pm »
What I do is:

My button click sends a notify event to the parent of my panel. The parent of my panel removes the panel, and the button as well.

No problem because it doesn't remove himself.

lucamar

  • Hero Member
  • *****
  • Posts: 4160
Re: Use of ReleaseComponent
« Reply #6 on: May 02, 2021, 08:28:18 pm »
My button click sends a notify event to the parent of my panel. The parent of my panel removes the panel, and the button as well.

Yes, that's a good solution to prevent the possibility that the code calling the button's event handler will, on return, try to do something else with a control that isn't there anymore.

Only, instead of a notification I'd send a message, to make sure any processing (e,g, the response to the mouse click on the button) is done before an attempt to destroy anything is made. It's probably overcaution but one never knows ... :-\
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

valter.home

  • Jr. Member
  • **
  • Posts: 75
Re: Use of ReleaseComponent
« Reply #7 on: May 04, 2021, 01:14:27 pm »
Yes, I can actually confirm abnormal behavior.
In the TButton's OnClick event the parent's FreeAndNil call is successful but if I try to use OnMouseDown or OnMouseUp it raises Access Violation.
It doesn't seem safe, better use a notify event or message.

In any case, even the use of Application.ReleaseComponent([Parent of TButton]) would seem to work regardless of the mouse event used, perhaps because it runs at the bottom of the event queue.
« Last Edit: May 04, 2021, 02:04:16 pm by valter.home »

 

TinyPortal © 2005-2018