Forum > Beginners

Free TControl created at runtime

(1/3) > >>

TomTom:
Hello :)
I'm creating TEdit with code (it's used to edit some TLabels caption). How do I free it after the editing is done? Everything is working fine except freeing created TEdit. I could hide it and disable it but that's not what I would Like.


--- 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.CreateLabelEditBox(aObject:TControl; aOnEditingDone: TNotifyEvent);begin  edLabelEdit:=TEdit.Create(self);  edLabelEdit.Left:=aObject.Left;  edLabelEdit.Top:=aObject.top;  edLabelEdit.BorderStyle:=bsNone;  edLabelEdit.Height:=aObject.Height;  edLabelEdit.Width:=aObject.Width;  edLabelEdit.Color:=RGBToColor(100,100,100);  edLabelEdit.OnEditingDone:=aOnEditingDone;  edLabelEdit.Font:=aObject.Font;  edLabelEdit.Parent:=self;  edLabelEdit.SetFocus;end;  
In some Label OnClick event:

--- 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.lbPlatformClick(Sender: TObject);beginCreateLabelEditBox(lbPlatform,@DoSomething2); end;   
And DoSomething2() procedure.

--- 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.DoSomething2(Sender: TObject);begin  Memo1.lines.add('Ok Editing done');  edLabelEdit.Free;end;   

wp:
Is it necessary to destroy the TEdit when editing is done? Simply hiding or disabling it would be much simpler.

Basically you destroy a control by calling its Free method: edLabelEdit.Free. If, however, there is a chance that the control will be used later, e.g. by calling CreateLabelEditbox again, you must set edLabelEdit to nil after destruction, in short: FreeAndNil(edLabelEdit). Note that in every access to it you must check against nil.

Setting the variable to nil is particularly important when you create the instance with an owner like you do. Your "edLabelEdit := TEdit.Create(self)" makes the form ("self") the owner of the edLabelEdit, and thus the form automatically destroys the edit when the form itself is destroyed. But when you destroyed the edit yourself during the lifetime of the application and did not set it to nil the form will still attempt to destroy it again - and your application will crash, because the variable edLabelEdit points to invalid memory.

You should also protect the procedure CreateLabelEditBox from creating the edLabelEdit a second time:

--- 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.CreateLabelEditBox(aObject:TControl; aOnEditingDone: TNotifyEvent);begin  if edLabelEdit = nil then    edLabelEdit:=TEdit.Create(self);  edLabelEdit.Left:=aObject.Left;  edLabelEdit.Top:=aObject.top;  edLabelEdit.BorderStyle:=bsNone;  edLabelEdit.Height:=aObject.Height;  edLabelEdit.Width:=aObject.Width;  edLabelEdit.Color:=RGBToColor(100,100,100);  edLabelEdit.OnEditingDone:=aOnEditingDone;  edLabelEdit.Font:=aObject.Font;  edLabelEdit.Parent:=self;  edLabelEdit.SetFocus;end;

jamie:

--- Quote --- But when you destroyed the edit yourself during the lifetime of the application and did not set it to nil the form will still attempt to destroy it again - and your application will crash, because the variable edLabelEdit poin

--- End quote ---

  I don't see this happening. When you destroy a child control, an owned control, it normally removes it from the list of owned control of the current owner.
 
  I do this all the time where I may or may not destroy the control and the owner will handle this action just fine.

  Unless something has changed? I still use older Laz among testing with the trunk.

TomTom:
I don't know if I get it right... So in edLabelEdit.onEditingDone procedure I should do it like this?

This does nothing to me. It didn't give me an error but edLabelEdit is still present on Form and is still functional.  How do I remove it completly from form?

--- 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.DoSomething(Sender: TObject);begin  Memo1.lines.add('Done somethin');  edLabelEdit:=nil;  edLabelEdit.free;end; 

wp:

--- Quote from: jamie on November 27, 2022, 03:52:11 pm ---
--- Quote --- But when you destroyed the edit yourself during the lifetime of the application and did not set it to nil the form will still attempt to destroy it again - and your application will crash, because the variable edLabelEdit poin

--- End quote ---
  I don't see this happening. When you destroy a child control, an owned control, it normally removes it from the list of owned control of the current owner.
--- End quote ---
Your're right.


--- Quote from: TomTom on November 27, 2022, 04:07:12 pm ---
--- 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.DoSomething(Sender: TObject);begin  Memo1.lines.add('Done somethin');  edLabelEdit:=nil;  edLabelEdit.free;end; 
--- End quote ---
First Free, then nil:

--- 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.DoSomething(Sender: TObject);begin  Memo1.lines.add('Done somethin');  edLabelEdit.free;  edLabelEdit:=nil;end;// or]procedure TForm1.DoSomething(Sender: TObject);begin  Memo1.lines.add('Done somethin');  FreeAndNil(edLabelEdit);end; 

Navigation

[0] Message Index

[#] Next page

Go to full version