Solved

Freeing components

Posted on 2000-03-27
17
258 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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 

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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Delphi Dbf export problem to a Visual Foxpro application 6 207
Delphi: how to send PJL commands to printer 3 109
Delphi: Connect to running MS Outlook 4 123
update joined tables 2 55
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Nobody understands Phishing better than an anti-spam company. That’s why we are providing Phishing Awareness Training to our customers. According to a report by Verizon, only 3% of targeted users report malicious emails to management. With compan…

829 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