Solved

Freeing components

Posted on 2000-03-27
17
257 Views
Last Modified: 2010-04-04
I create a components at run time such as Memos, labes, and even forms. I make the owner and parent of these component a Form. When I close this form (Not a main form) I free all component that I was created at run-time, but when I close the main form and my application terminated (And when the owner of these component destroyed) Access violation exception alwyas raised.

I think the owner only who must destroy it's components, and when it find it is already destroyed it will rais the exception. In my application I need to destroy that component when I close that form, and I create new ones when I open that form again.

The only thing that I can do now is to assign Visible property of these components to False when I close the form, it works very well but the problem is that will consume memory resource. Is there any safe freeing for such components?

Motaz
www.geocities.com/motaz1
0
Comment
Question by:Motaz
  • 5
  • 4
  • 2
  • +5
17 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 2663142
You don't have to free the components on that form. They will be freed automatically when the form is destroyed since the form is their owner.
Btw, use TForm.Release to free the form.
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 2663145
You don't have to free the components on that form. They will be freed automatically when the form is destroyed since the form is their owner.
Btw, use TForm.Release to free the form.
0
 
LVL 6

Expert Comment

by:Jaymol
ID: 2663260
I get this problem too Motaz.  I usually find that Whatever.Destroy is a little less volatile than .Free, but still has the same problems sometimes.

Worth a try anyway.

John.
0
NAS Cloud Backup Strategies

This article explains backup scenarios when using network storage. We review the so-called “3-2-1 strategy” and summarize the methods you can use to send NAS data to the cloud

 

Expert Comment

by:vinnair
ID: 2663343
Have you written some code in the formdestroy event or the form close event of the main form as well as the component owner form. If yes, please post that code.
0
 
LVL 2

Expert Comment

by:Tussin
ID: 2663345
If you want to safe memory, you can create components with owner=nil, So you can free them properly.

Another issue is "don't forget to set all events back to nil".
Normally when you create component at runtime, you often set its event right?
Before free them, set it back to nil first.
0
 
LVL 7

Author Comment

by:Motaz
ID: 2663386
To Tussin
>create components with owner=nil

Can I create Memo without Onwer?

To Vinnair
I write code in OnClose event at the parent form which deletes all created components at run-time.

To Epsylon:
What exactly Realease do? I do not want to lose the parent form, even I do not want to free all it's components, only I need to free some components (which created at run-time)

Motaz
0
 

Expert Comment

by:omeralfaroug
ID: 2663415
hi
 i don't understand " A componentS" and
"Labes" tell me the meaning and i will answered u.
omeralfaroug
0
 
LVL 7

Author Comment

by:Motaz
ID: 2663446
To Omer:
I mean control components such as Labels and Memos

Azzoz
0
 
LVL 2

Expert Comment

by:florisb
ID: 2663768
question is probably answered, but:

write some procedures that you can use to place controls on certain possitions, you could use the tag to be able to find those controls again, or to use one onclick event and check the Sender's tag there. To make this a bit more comfortable, you could add adssociate property's to controls, to be able to fill a list that belongs with a button or something.

Had problems with free's run-time generated controls, too. Tussin: owner nil! Offcourse.

saw this too:
  if assigned(MyRegel.VarControl1) then
      begin
      MyRegel.VarControl1.free;
      MyRegel.VarControl1 := nil;
      end;


procedure placeSomeControl(AParent: TWinControl; x: integer);
var
  CheckboxHaakjeOpen: TUMSAdvancedCheckbox;
  begin
  ///
  checkboxHaakjeOpen := TUMSAdvancedCheckbox.Create(Aparent);
  checkboxHaakjeOpen.parent := Aparent;
  checkboxHaakjeOpen.Left := left1;
  checkboxHaakjeOpen.top := firstspace + ((x - 1) * linespace) + 1;
  checkboxHaakjeOpen.width := checkwidth;
  checkboxHaakjeOpen.Caption := '(';
  checkboxHaakjeOpen.regelnummer := x;
  checkboxHaakjeOpen.enabled := false;
  checkboxHaakjeOpen.checked := true;
  end;

Floris.
0
 
LVL 6

Expert Comment

by:DrDelphi
ID: 2664898
Another thing that I am suprised that no-one else mentioned is that you would want to free these controls in the OnCloseQuery event of the form rather than the OnClose. This way you can test to see if all components=nil prior to passing true to the CanClose parameter.
0
 
LVL 7

Author Comment

by:Motaz
ID: 2667928
Is this code can solve my problem:

for i:= 0 to Components.Count - 1 do
  if TControl(Components[i]).Tag = 255 then
begin
  Components[i].Free;
  Components[i]:= nil;
end;

Is that a right code?

0
 
LVL 2

Expert Comment

by:florisb
ID: 2668672
I do think so (that's what I posted)... ...but I'm no 'Delphi docter'...:-)

Floris
0
 
LVL 2

Expert Comment

by:Tussin
ID: 2672257
To Motaz,
   In case that I want dynamic array of component, I normally create component with Owner=nil and free them whenever I want. It works well.
   This is a sample. (don't forget to set event back to nil, otherwise sometimes it will become Access Violation)

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

const MAXMEMO=8;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure MemoClick(Sender: TObject);
  private
    { Private declarations }
    MemoList:array[0..MAXMEMO-1] of TMemo;
    MemoCount:Integer;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  MemoCount:=0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if MemoCount=MAXMEMO then
    exit;
  MemoList[MemoCount]:=TMemo.Create(nil);
  with MemoList[MemoCount] do
  begin
    Parent:=Self;
    Left:=MemoCount*40;
    Top:=MemoCount*40;
    OnClick:=MemoClick;
  end;
  Inc(MemoCount);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if MemoCount=0 then
    exit;
  with MemoList[MemoCount-1] do
  begin
    OnClick:=nil;
    Free;
  end;
  Dec(MemoCount);
end;

procedure TForm1.MemoClick(Sender: TObject);
begin
  ShowMessage('Click Click');
end;

end.
0
 
LVL 7

Author Comment

by:Motaz
ID: 2677432
Tussin, what kind of components can I create without having an owner or parent, my componets which cause the problem is Visual components such Lebels, and Memos, so that can I create it without owner or parent?
0
 
LVL 2

Accepted Solution

by:
Tussin earned 25 total points
ID: 2678748
I cut this message from delphi help. (topic "TComponent.Create")

For components created manually, that is, not created in the form designer, call Create and pass in an owner componentas the AOwner parameter. The owner will dispose of the component when the owner is destroyed. If the component is not owned, then call Free so that it is destroyed.

That means, all object which inherit from TComponent can be created properly with owner=nil, and you have to call method "Free" by yourself.

you can test on my previous sample.
0
 
LVL 7

Author Comment

by:Motaz
ID: 2679016
Tussin, what about MDI child forms, I think it must has an owner, isn't it?
0
 
LVL 2

Expert Comment

by:Tussin
ID: 2679196
Normally, all forms is created with owner=Application and will be free before terminate a program.

This is an example of MDIChild form creation.
procedure TMainForm.CreateMDIChild(const Name: string);
var
  Child: TMDIChild;
begin
  { create a new MDI child window }
  Child := TMDIChild.Create(Application);
  Child.Caption := Name;
end;
That means this form will be free automatically when application is terminated.

you can safe memory by using Event OnFormClose.

TForm provides a variable "Action" in OnFormClose event, if you set it to "cafree", it will free itself after close form

procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caFree;
end;

Anyway you can create MDIChild windows with Owner=nil.
0

Featured Post

ScreenConnect 6.0 Free Trial

Check out the updates in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI that improves session organization and overall user experience. See the enhancements for yourself!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Hello everybody This Article will show you how to validate number with TEdit control, What's the TEdit control? TEdit is a standard Windows edit control on a form, it allows to user to write, read and copy/paste single line of text. Usua…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question