Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Better method: Auto-create forms or on demand? 1

Status
Not open for further replies.

doctorjellybean

Programmer
May 5, 2003
145
When one adds forms to the main one, Delphi auto-creates it at runtime. Now I've seen quite a few examples where the form is removed from the Available Forms list and created when needed
Form2 := TForm2.Create(nil);
Is there a difference between the two, and what if yes?

Thank you.
 
to answer your question:

when autocreated, your form eats/memory resources, even if it is not visible/used at that moment.

for an app with 2 forms, this will not make a big difference (depending what's on the form offcourse)
but things could go ugly when your app has a LOT of forms.

I tend to create my objects the moment I need them.
(that's the method you showed)

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
whosrdaddy (Vendor)

a)
Formx.Create(Application) -> Form resources will be freed when application is terminated

b)
Formx.Create(Self) -> Form resources are freed when the owner object is destroyed (if Self is a descendand of TComponent)

c)
Formx.Create(nil) -> you are responsible for freeing the form

a is used by delphi when a form is autocreated
b is handy for a main form that has several child windows that need to close when the main form is closed
c is handy for showing a dialog window

I have a normal main menu, and each menu item uses its own form. If I select item 2, form 2 shows, item 3 shows form 3, and so on. When showing e.g. form 3, then form 2 should be closed.

Do I use option (c) Formx.Create(nil) for each form?
 
yes, that would be the best option.

to prevent the hassle checking which for is in memory at the moment, just create a variable. make sure all forms have an onclose event with the code Action := caFree;

CurrentForm : TForm;

initialize it to nil
CurrentForm := nil;

when clicking on the menu item create your form and associate it with the var

Code:
...

procedure Menu1Click(Sender : TObject);
var Form : TForm1; 

begin
// check if we have a form open, if so, close it
// the onclose event will free the form
 if Assigned(CurrentForm) then
  CurrentForm.Close; 
// create your new form
 Form1 := TForm1.Create(nil);
 CurrentForm := Form1;
end;

clearer now?

/Daddy

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 

Perhaps you shouldn't be doing this, but if you have data stored on/in a form that's not always visible, then creating it at run time isn't an easy option.

To give an example one of my first apps started out with all pre-created forms, later when attempting to convert it to 'create at run time', I found that major re-write would be required to change the way the data was structured.
I could only convert about 2/3 of the forms.




Steve: N.M.N.F.
Playing the blues isn't about feeling better. It's about making other people feel worse.
 
whosrdaddy (Vendor)

clearer now?

Yes, I think so. Thank you.

This is the code on my main form.
type
TForm1 = class(TForm)
MainMenu1: TMainMenu;
Menu1: TMenuItem;
Menu2: TMenuItem;
Menu3: TMenuItem;
Menu4: TMenuItem;
Panel1: TPanel;
procedure Menu1Click(Sender: TObject);
procedure Menu2Click(Sender: TObject);
procedure Menu3Click(Sender: TObject);
procedure Menu4Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
CurrentForm : TForm;

implementation

uses Unit2, Unit3, Unit4;

{$R *.dfm}

procedure TForm1.Menu1Click(Sender: TObject);
var Form : TForm1;
begin
if Assigned(CurrentForm) then
CurrentForm.Close;
Form1 := TForm1.Create(nil);
CurrentForm := Form1;
end;

procedure TForm1.Menu2Click(Sender: TObject);
var Form : TForm1;
begin
if Assigned(CurrentForm) then
CurrentForm.Close;
Form2 := TForm2.Create(nil);
CurrentForm := Form2;
Form2.Show;
end;

procedure TForm1.Menu3Click(Sender: TObject);
var Form : TForm1;
begin
if Assigned(CurrentForm) then
CurrentForm.Close;
Form3 := TForm3.Create(nil);
CurrentForm := Form3;
Form3.Show;
end;

procedure TForm1.Menu4Click(Sender: TObject);
var Form : TForm1;
begin
if Assigned(CurrentForm) then
CurrentForm.Close;
Form4 := TForm4.Create(nil);
CurrentForm := Form4;
Form4.Show;
end;

I'm sure I'm doing something wrong, as it gives me a message when compiling:
[DCC Warning] Unit1.pas(38): H2164 Variable 'Form' is declared but never used in 'TForm1.Menu1Click'
[DCC Warning] Unit1.pas(47): H2164 Variable 'Form' is declared but never used in 'TForm1.Menu2Click'
[DCC Warning] Unit1.pas(57): H2164 Variable 'Form' is declared but never used in 'TForm1.Menu3Click'
[DCC Warning] Unit1.pas(67): H2164 Variable 'Form' is declared but never used in 'TForm1.Menu4Click'

However, it does appear to work. I think.

I assume I don't need the create routine in the menu1 click procedure, as menu1 is the main form?
 
2 observations:

you don't need the form var in each unit as the form's unit already contains a global variable.

I assume I don't need the create routine in the menu1 click procedure, as menu1 is the main form?

yeah, your main form should act as a placeholder for the other forms. so Form1 is autocreated by delphi and the others are controlled by you...

/Daddy

P.S: please use the code tags when posting code

-----------------------------------------------------
What You See Is What You Get
Never underestimate tha powah of tha google!
 
Thanks for help and advice!

Oops, I'm so used to using quote tags. Will remember to use code tags [smile]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top