Reputation: 283
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
Reputation: 9
Init: MyForm := nil;
User FreeAndNil(MyForm)
if (Assigned(MyForm)) then
DON'T DO THE PROCEDURE
else
DO THE PROCEDURE
Upvotes: 1
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