Felipe
Felipe

Reputation: 283

Checking form's existence doesn't work

I have a Form for which I coded my own constructor:

constructor Create(AOwner: TComponent; AParent: TWinControl; ASender: TMyClass;
   ATab: String); reintroduce; overload;

To create such a form I use the following:

try
  MyForm := TMyClassForm.Create(nil, Self.Parent, Self as TMyClass, 'FirstTab');
  MyForm.ShowModal;
finally
  MyForm.Free;
end;

Somewhere else, before starting a procedure, I need to check whether this form is opened or not, so I check its existence with:

if (Assigned(MyForm)) and (MyForm.Active) and (MyForm.Showing) then
  // Don't do the procedure
else
  // Do the procedure

Now, if I open the form and close it, and I check this conditional statement, everytime I get true, but the Form is not opened and not showing anymore, because I freed it after creating.

Any idea of what could be the problem?

Upvotes: 0

Views: 146

Answers (2)

ZibNimer
ZibNimer

Reputation: 9

  1. Init: MyForm := nil;

  2. User FreeAndNil(MyForm)

  3. if (Assigned(MyForm)) then
    DON'T DO THE PROCEDURE
    else
    DO THE PROCEDURE

Upvotes: 1

David Heffernan
David Heffernan

Reputation: 613461

You called Free on the MyForm global method, but you did not modify the reference. So, MyForm still refers to the now destroyed form. And so Assigned(MyForm) evaluates as True, and then the other two tests operate on the stale object reference. Anything could happen when you operate on a stale object reference. In the situations that you have tried, it seems that the operations both return True. But another time you might get an access violation.

You'll want to set the MyForm variable to nil after call Free. At the risk of re-starting the great religious Delphi war of our times, you might contemplate using FreeAndNil(MyForm) in place of MyForm.Free.

You might find my answer here to be instructive: Why should I not use "if Assigned()" before using or freeing things?

Upvotes: 5

Related Questions