Board index » delphi » Checking if a Form is already created

Checking if a Form is already created

I would like to create forms on the very moment I need them. (Hoping to
speed up the starting up of my program)
So when I click MyButton to open MyForm the program should create it.
But only if it was not already created.
So I put it in a 'try ... except' statement.

try
  MyForm.Show
except
  on Exception do
  begin
     CreateTheForm;
     MyForm.Show;
  end
end

But it still gives the errormessage : An EAccessViolation at ...
If I press on F9 again it indeed continues to the code after 'except',
and of course I don't want that message to appear.

I could solve the problem by setting a variable to True after the Form is
created,
but is it not possible to do it the 'try ... except' way?

Does someone have special tips for speeding up a program's startup?

TIA

michiel rapati

 

Re:Checking if a Form is already created


"Michiel Rapati-Kekkonen" <mich...@rapati.com> wrote in news:tsrgackkkagn83
@corp.supernews.com:

I think I understand what you want to do. What I have do is to have a
(private) variable that holds the form. The global one that the Delphi IDE
automatically "creates" when you start an new Form might be ok.

The code goes on the line of this...

-=-=-=-=-=-
//for versions of Delphi < 5.
//if formVar = nil then

if not assigned(formVar) then
  formVar := TMyForm.Create(nil);
// use self instead of nil if you do not want to explict free it.

formVar.Show;
-=-=-=-=-=-

Hope this helps you out.

Nick

Quote
> I would like to create forms on the very moment I need them. (Hoping to
> speed up the starting up of my program)
> So when I click MyButton to open MyForm the program should create it.
> But only if it was not already created.
> So I put it in a 'try ... except' statement.

> try
>   MyForm.Show
> except
>   on Exception do
>   begin
>      CreateTheForm;
>      MyForm.Show;
>   end
> end

> But it still gives the errormessage : An EAccessViolation at ...
> If I press on F9 again it indeed continues to the code after 'except',
> and of course I don't want that message to appear.

> I could solve the problem by setting a variable to True after the Form is
> created,
> but is it not possible to do it the 'try ... except' way?

> Does someone have special tips for speeding up a program's startup?

> TIA

> michiel rapati

Re:Checking if a Form is already created


Thanks for your suggestion.
I do not immediately understand it, but I will study it and experiment.
At the moment I use Boolean variables wich turn to True when a form is
created. So next time it won't be created again.
Works well, too.
Your variable-approach looks intriguing.

Still I would like to understand why the 'try ... except' approach can't
handle it.

thanks,

michiel

"Nicholas Ring" <nr...@NOSPAM.smf.com.au> schreef in bericht
news:Xns913E65561CC29NickForAlison@203.50.2.80...

Quote
> "Michiel Rapati-Kekkonen" <mich...@rapati.com> wrote in
news:tsrgackkkagn83
> @corp.supernews.com:

> I think I understand what you want to do. What I have do is to have a
> (private) variable that holds the form. The global one that the Delphi IDE
> automatically "creates" when you start an new Form might be ok.

> The code goes on the line of this...

> -=-=-=-=-=-
> //for versions of Delphi < 5.
> //if formVar = nil then

> if not assigned(formVar) then
>   formVar := TMyForm.Create(nil);
> // use self instead of nil if you do not want to explict free it.

> formVar.Show;
> -=-=-=-=-=-

> Hope this helps you out.

> Nick

> > I would like to create forms on the very moment I need them. (Hoping to
> > speed up the starting up of my program)
> > So when I click MyButton to open MyForm the program should create it.
> > But only if it was not already created.
> > So I put it in a 'try ... except' statement.

> > try
> >   MyForm.Show
> > except
> >   on Exception do
> >   begin
> >      CreateTheForm;
> >      MyForm.Show;
> >   end
> > end

> > But it still gives the errormessage : An EAccessViolation at ...
> > If I press on F9 again it indeed continues to the code after 'except',
> > and of course I don't want that message to appear.

> > I could solve the problem by setting a variable to True after the Form
is
> > created,
> > but is it not possible to do it the 'try ... except' way?

> > Does someone have special tips for speeding up a program's startup?

> > TIA

> > michiel rapati

Re:Checking if a Form is already created


Michiel Rapati-Kekkonen <mich...@rapati.com> wrote

Quote
> Your variable-approach looks intriguing.

And IMO superior. I am avoiding exceptions if there
is an easy alternative way without using one. The
reason is that when I run under the de{*word*81} with
the Delphi exception flag set, these things then
pop up all over the place, very annoying when they
are there just to take care to handle some program
or data condition.

Peter Reber

Quote
> michiel

> "Nicholas Ring" <nr...@NOSPAM.smf.com.au> schreef in bericht
> news:Xns913E65561CC29NickForAlison@203.50.2.80...
> > "Michiel Rapati-Kekkonen" <mich...@rapati.com> wrote in
> news:tsrgackkkagn83
> > @corp.supernews.com:

> > I think I understand what you want to do. What I have do is to have
a
> > (private) variable that holds the form. The global one that the
Delphi IDE
> > automatically "creates" when you start an new Form might be ok.

> > The code goes on the line of this...

> > -=-=-=-=-=-
> > file://for versions of Delphi < 5.
> > file://if formVar = nil then

> > if not assigned(formVar) then
> >   formVar := TMyForm.Create(nil);
> > // use self instead of nil if you do not want to explict free it.

> > formVar.Show;
> > -=-=-=-=-=-

> > Hope this helps you out.

> > Nick

> > > I would like to create forms on the very moment I need them.
(Hoping to
> > > speed up the starting up of my program)
> > > So when I click MyButton to open MyForm the program should create
it.
> > > But only if it was not already created.
> > > So I put it in a 'try ... except' statement.

> > > try
> > >   MyForm.Show
> > > except
> > >   on Exception do
> > >   begin
> > >      CreateTheForm;
> > >      MyForm.Show;
> > >   end
> > > end

> > > But it still gives the errormessage : An EAccessViolation at ...
> > > If I press on F9 again it indeed continues to the code after
'except',
> > > and of course I don't want that message to appear.

> > > I could solve the problem by setting a variable to True after the
Form
> is
> > > created,
> > > but is it not possible to do it the 'try ... except' way?

> > > Does someone have special tips for speeding up a program's
startup?

> > > TIA

> > > michiel rapati

Re:Checking if a Form is already created


Michiel Rapati-Kekkonen <mich...@rapati.com> wrote

Quote
> Still I would like to understand why the 'try ... except' approach
can't
> handle it.

> > > try
> > >   MyForm.Show
> > > except
> > >   on Exception do
> > >   begin
> > >      CreateTheForm;
> > >      MyForm.Show;
> > >   end
> > > end

In your code of CreateTheForm do you assign
the value rtuned by form.create() to the
global variable that points to the form?
If you don't then you would get your problem.

--
Peter Reber

Re:Checking if a Form is already created


Here's solution to the same problem, it similar to one of the other posting
(Nicholas Ring's) but adds some extra bits to help keep memory usage down.
Make sure that you turn off the autocreate form option in the project
options.

unit Unit3;

interface

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

type
  TForm3 = class(TForm)
    procedure FormDestroy(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form3: TForm3;

implementation

{$R *.DFM}

Procedure ShowMyForm;
Begin
  If Form3 = nil Then
  Begin
    Form3 := TForm3.Create( nil ); //Or self
  End;
  Form3.Show;
End;

procedure TForm3.FormDestroy(Sender: TObject);
begin
  Form3 := nil;
end;

procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //Use This line for an MDI Application.
  Action := caFree;
end;

Initialization
  //This code executes when the program is loading.
  Form3 := nil;
Finalization
  //Don't need to do anthing in this example.
end.

I'll just take a little time to explain why I do it slightly differently to
Nicholas. I'll talk you though the code in execute form (not from top to
bottom, but it'll be how the program runs the code)

<snip>
Initialization
  //This code executes when the program is loading.
  Form3 := nil;
</snip>

This runs first.  I do not trust anything to do with memory allocation. If
I'm going to use it I want to make sure that it's set properly. We know that
the form is not created when the program executes, and we know that the
Form3 pointer is definatly set to nil.  Delphi should do this, but if you
make that assumtion it's bound to fail.

<snip>
Procedure ShowMyForm;
Begin
  If Form3 = nil Then
  Begin
    Form3 := TForm3.Create( nil ); //Or self
  End;
  Form3.Show;
End;
</snip>

At some point in the program this procedure will be executed. It's check our
 Form3 pointer to see if it points to anying, nil  is a pointer to nothing
and means that the form does not exist.  I added the Begin .. End block next
to make reading simpler - but you don't really need it in this case.  The
code inside the Begin .. End is only executed if the for does not exist,
lets create the form here.

This is exactly what Nicholas's code does.  If you look at his code you'll
also see that he's doing the following "if not assigned(formVar) then" I
decided to leave this out, as we already know that our form3 pointer is nil.
Assigned is just another way of asking the question "if form3 = nil".

So, we've now finished the Begin .. End block.  It's safe to assume that the
form is created at this point. Show lets call the Show command.

If we call this procedure again Form3 will not equal NIL but will point to
the memory address of the form, so it won't create the form, it'll just show
it.

The next code will execute when we try to shut down the form.

<snip>
procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //Use This line for an MDI Application.
  Action := caFree;
end;
</snip>

As my comment says This is only needed for an MDI Application, where you may
have several form3's opened. In order to keep track of several identical
forms, you are best of using a TList to store a list of pointer to your
forms. (That's a whole other are so don't worry about it for now).  Setting
the Action variable to caFree, tells windows to free (or destroy) the form.

<snip>
procedure TForm3.FormDestroy(Sender: TObject);
begin
  Form3 := nil;
end;
</snip>

Which leads us quite nicely to the last piece of the puzzle.  This code does
exactly the same as we did in the first place.  Deplhi is not destroying the
form, so the memory location stored in the Form3 variable will no longer be
valid.  By setting it to nil, the program will create a new form if it's
needed.

There is a whole other way of doing this which is better for MDI
Application, where you'll have several copies of the same form opened. It
involves asking the application if a specific window has been created, using
the windows Messaging technique.  If you want details on this the please
e-mail my personal e-mail address  N...@cdawson.tele2.co.uk

Regards

Colin Dawson.

Other Threads