Tom F 83 Posted December 21, 2021 (edited) Is there ever a time to explicitly free a sub-form or does it parent form always do that? The expression: TForm2.Create(Self) establishes that the sub-form TForm2 is owned by the parent form TForm1. When TForm1 one is destroyed, the RTL will destroy TForm2? If so, fNonModalForm.Free should never be done? procedure TForm1.btnCloseAllClick(Sender: TObject); begin if Assigned(fNonModalForm) then begin if fNonModalForm.Visible then fNonModalForm.Close; FreeAndNil(fNonModalForm); // <--- Should I do this ever? end; Self.Close; end; procedure TForm1.btnOpenNonModalWindowClick(Sender: TObject); begin if NOT Assigned(fNonModalForm) then fNonModalForm := TForm2.Create(Self); fNonModalForm.Show; end; Edited December 21, 2021 by Tom F Share this post Link to post
corneliusdavid 214 Posted December 21, 2021 Since it was created like this from Form1: 11 minutes ago, Tom F said: TForm2.Create(Self); you don't need to explicitly free it--it will be freed when the owner form, Form1, is freed. Sometimes, however, you want/need to manage it yourself. For example: var Form3: TForm; begin Form3 := TForm3.Create(nil); try // do stuff... finally Form3.Free; end; This may be the case if you don't have a current form available. Share this post Link to post
John Kouraklis 94 Posted December 21, 2021 I would say it depends on the application and the platform. When on mobile platforms, I prefer to free AND NIL forms that are not used a lot given that memory is a limited resource Share this post Link to post
Tom F 83 Posted December 21, 2021 @corneliusdavid: Is it safe to set a form's parent to nil, as in TForm.Create(nil)? Does a form inherit properties and behaviors from a parent that if we use nil are not inherited? @John Kouraklis: In some initial testing I was finding even if I explicitly did .Free and := nil (or used FreeAndNil) that the RTL still seemed to be trying to destroy the sub-form when it destroyed its parent form, the app's main form. I'm hoping that some RTL gurus will clarify all this for us. Share this post Link to post
corneliusdavid 214 Posted December 21, 2021 10 minutes ago, Tom F said: Is it safe to set a form's parent to nil, as in TForm.Create(nil)? Yes, I've implemented this technique many times over the years. For example, in a plugin where I don't have easy access to the main application form's handle or when I don't want a global form variable laying around for inadvertent use and just have a quick dialog form to show and destroy. 12 minutes ago, Tom F said: Does a form inherit properties and behaviors from a parent that if we use nil are not inherited? Someone may correct me but as far as I know, it doesn't do any more than set the Owner property; then when the owner is being freed, its destructor checks to see if the Owner is nil and if not, frees it. So, if you assign it, then free it yourself, it'll try to be freed twice unless you set the Owner := nil manually. Conversely, if you don't assign it and don't free it, you'll create a memory leak. (I only mention these as things NOT to do to give more insight into what's happening.) Share this post Link to post
Tom F 83 Posted December 21, 2021 @corneliusdavid Thanks for the response. I hope you are correct. I hope someone who knows the internals of the RTL will post her confirming that TForm.Create(nil) has no side effects other than relieving the parent form from the responsibility of freeing the form. Somehow I thought that Z-order (I'm using fsStayOnTop) depending on the sub-form knowing its parent. Tom Share this post Link to post
Anders Melander 1783 Posted December 21, 2021 20 minutes ago, Tom F said: Is it safe to set a form's parent to nil, as in TForm.Create(nil)? Yes. Unless you have a reason to specify an explicit owner, you should actually specify nil to make it clear (when reading the code) that there is no owner. 20 minutes ago, Tom F said: Does a form inherit properties and behaviors from a parent that if we use nil are not inherited? No. You can specify that a "child form" should be centered on the owner form (Position=poOwnerFormCenter), but it's still safe to specify nil as the owner. 27 minutes ago, Tom F said: In some initial testing I was finding even if I explicitly did .Free and := nil (or used FreeAndNil) that the RTL still seemed to be trying to destroy the sub-form when it destroyed its parent form, the app's main form. You're mistaken. There must have been something else going on. 4 minutes ago, corneliusdavid said: then when the owner is being freed, its destructor checks to see if the Owner is nil and if not, frees it. It's the same for all classes derived from TComponent; When a component is free'd it will free all the components it owns. TComponent is a base class of TForm. 1 Share this post Link to post
Tom F 83 Posted December 21, 2021 @Anders Melander Thank you for your helpful answer! Share this post Link to post
John Kouraklis 94 Posted December 21, 2021 39 minutes ago, Tom F said: @corneliusdavid: Is it safe to set a form's parent to nil, as in TForm.Create(nil)? Does a form inherit properties and behaviors from a parent that if we use nil are not inherited? As others have said, it's very safe. Just don't forger to free the form. 39 minutes ago, Tom F said: @John Kouraklis: In some initial testing I was finding even if I explicitly did .Free and := nil (or used FreeAndNil) that the RTL still seemed to be trying to destroy the sub-form when it destroyed its parent form, the app's main form. I don't think so. Just create a blank project and test again. 1 Share this post Link to post