Board index » delphi » What's wrong with this?

What's wrong with this?

What's wrong with this?

    if Assigned( CurrentMyForm ) then Exit;
    for i := (Application.ComponentCount -1) downto 0 do
      if Application.Components[i] is TMyForm then begin
        CurrentMyForm := TMyForm( Application.Components[i] );
        Exit;
      end;

It spits an Access Violation when the app tries to access the CurrentMyForm
variable. If you look at the variable a lot of the components are nil for some
reason. What I am trying to do is determine if any TMyForm are open (there
could be more than 1 open). If I change:

    for i := (Application.ComponentCount -1) downto 0 do

to:

    for i := 0 to (Application.ComponentCount -1) do

...then it DOES works, but only when there are more than one TMyForm open. If
you close all but one TMyForm, the above code seems to work but spits out the
same violation.

Any suggestions?

Ben Vigil
<ben.s...@abelware.com> remove spam

 

Re:What's wrong with this?


On Mon, 26 Oct 1998 03:35:27 -0500, "Ben Vigil" <b...@abelware.com>
wrote:

Quote
>What's wrong with this?

>    if Assigned( CurrentMyForm ) then Exit;
>    for i := (Application.ComponentCount -1) downto 0 do
>      if Application.Components[i] is TMyForm then begin
>        CurrentMyForm := TMyForm( Application.Components[i] );
>        Exit;
>      end;

>It spits an Access Violation when the app tries to access the CurrentMyForm
>variable. If you look at the variable a lot of the components are nil for some
>reason. What I am trying to do is determine if any TMyForm are open (there
>could be more than 1 open). If I change:

>    for i := (Application.ComponentCount -1) downto 0 do

>to:

>    for i := 0 to (Application.ComponentCount -1) do

>...then it DOES works, but only when there are more than one TMyForm open. If
>you close all but one TMyForm, the above code seems to work but spits out the
>same violation.

>Any suggestions?

Can't you use Screen.Forms and Screen.FormCount to do the
(essentially) same thing ?

Also, you should test for nil before making the 'is' comparison, the
'is' operator tends to say 'true' when an object is nil, (in Delphi 3,
at least; Delphi 1 was ok in this respect).

hth

David

Quote
>Ben Vigil
><ben.s...@abelware.com> remove spam

------------------
David A. Schweizer

iec ProGAMMA, The Netherlands
d.a.schweizer[OK, i don't want any more spam]gamma.rug.nl
guess where the '@' goes ?

Re:What's wrong with this?


In article <363432e...@news.inetnow.net>, "Ben Vigil" <b...@abelware.com>
writes:

Quote
>What's wrong with this?

>    if Assigned( CurrentMyForm ) then Exit;
>    for i := (Application.ComponentCount -1) downto 0 do
>      if Application.Components[i] is TMyForm then begin
>        CurrentMyForm := TMyForm( Application.Components[i] );
>        Exit;
>      end;

>It spits an Access Violation when the app tries to access the CurrentMyForm
>variable. If you look at the variable a lot of the components are nil for
>some
>reason. What I am trying to do is determine if any TMyForm are open (there
>could be more than 1 open). If I change:

>    for i := (Application.ComponentCount -1) downto 0 do

>to:

>    for i := 0 to (Application.ComponentCount -1) do

>...then it DOES works, but only when there are more than one TMyForm open. If
>you close all but one TMyForm, the above code seems to work but spits out the
>same violation.

>Any suggestions?

Have you :-

1 Not set CurrentMyForm to nil after declaring it and before using it.

2 Free'd a TMyForm without setting the pointer to nil and CurrentMyForm to nil
and re-calling the procedure (you might have Free'd the CurrentMyForm).

3 Created TMyForm with an Owner who is not Application.

You could do it another way by having a fairly trivial component (a TPanel)
which you create and whose Owner is the Application. Make this trivial
component the Owner of all your TMyForm, then :-

Instances_of_TMyForm := OwnerPanel.ComponentCount;

BTW when you say "if any TMyForm are open", do you mean "any instances of
TMyForm are  created" or "any instances of TMyForm are shown" or "any instance
of TMyForm is active". You need different approaches for each of these.

Alan Lloyd
alangll...@aol.com

Re:What's wrong with this?


The forms in question are begin created by:

    Application.CreateForm(TMyForm, MyForm);

Then in the form, the relevant code is:

    procedure TMyForm.FormActivate(Sender: TObject);
    begin
      CurrentMyForm := Self;
    end;

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

I usually do an "if Assigned(CurrentMyForm) then ..." which works fine all
over the place but the loop in question {*word*88}s. If the user clicks the form,
the assignment in FormActivate() occurs and all is well. I just need to find
the topmost instance if TMyForm without the user. This *should* be simple.

For example, if 5 TMyForm's and a TYourForm are open and the user closes 3 of
the TMyForm's, it is possible that one of the TYourForm will get the focus. At
this point CurrentMyForm = nil. Fine, but I want to determine whether or not
any TMyForm are still out there and assign the topmost one to CurrentMyForm.

It seems to work in the loop (Delphi finds the instance TMyForm) but I noticed
when peeking at the CurrentMyForm variable after the assignment, that many
(not all) of the controls are nil. The problem only occurs with the topmost
form in the ZOrder.

IOW, if I use a "for i := x to y" type loop, it DOES WORK, but only when more
than one TMyForm are open (since the last one it finds is the topmost).

If I use a "for i := y downto x" type loop, it never works (since the first
one it finds is the topmost).

Any more suggestions???

Ben Vigil
<ben.s...@abelware.com> remove spam

Quote
AlanGLLoyd wrote in message <19981026101350.01918.00000...@ngol04.aol.com>...

>In article <363432e...@news.inetnow.net>, "Ben Vigil" <b...@abelware.com>
>writes:

>Have you :-

>1 Not set CurrentMyForm to nil after declaring it and before using it.

>2 Free'd a TMyForm without setting the pointer to nil and CurrentMyForm to
nil
>and re-calling the procedure (you might have Free'd the CurrentMyForm).

>3 Created TMyForm with an Owner who is not Application.

>You could do it another way by having a fairly trivial component (a TPanel)
>which you create and whose Owner is the Application. Make this trivial
>component the Owner of all your TMyForm, then :-

>Instances_of_TMyForm := OwnerPanel.ComponentCount;

>BTW when you say "if any TMyForm are open", do you mean "any instances of
>TMyForm are  created" or "any instances of TMyForm are shown" or "any
instance
>of TMyForm is active". You need different approaches for each of these.

>Alan Lloyd
>alangll...@aol.com

Other Threads