Hello,

Sorry I'm on holiday and only noticed this thread now.

Anyway: NEVER free a form in an event handler of the form, as per the 
Delphi help.  Always use Release instead, which works (IIRC) by posting 
a message to the form, and then only freeing it, thus allowing the event 
handlers to complete before freeing.  (Otherwise, you effectively cut 
the branch that you're sitting on from the tree, so to speak...)

 Quote from the help:
"Warning:    Never explicitly free a component within one of its own 
event handlers or the event handler of a component it owns or contains. 
For example, don
't free a button, or the form that owns the button, in its OnClick event 
handler.

To free a form, call its Release method, which destroys the form and 
releases the memory allocated for it after all its event handlers and 
those of the components it contains are through executing."

As for handling the auto-freeing/managing the creation/freeing of the 
form,  you might consider using the following idiom that at least 
centralizes the creation of the "default" instance of the form and 
removes the responsibility from the rest of your code to continuously 
check for and create if required a form before use.  I suggest this is 
at least preferable to having code all over your app that checks and 
creates the form if required.

1.)  In the unit of the form, replace the global form variable with a 
global accessor/"factory" function.  Move the variable the the private 
(implementation) part of the unit.

2.) Implement the function so that it checks if the (now private to the 
unit global) variable is nil, if so, it creates the form and assigns it 
to the variable.  The function always returns the value of the variable.

3.) In the destructor of the form (override destroy) or perhaps in the 
OnDestroy, check to see if "self" is the same as the global form 
variable created by the accessor and is not nil.  If so, then the 
instance being freed was created by the accessor and is now being freed, 
so, then nil the global variable.    The next time the accessor is used, 
a new instance will now be created.  On the other hand, if this instance 
was created by some other client code and not by the accessor, then the 
references will be different, and we leave the global instance alone, 
thus allowing for multiple form instances if that is desired.

4.) In the FormClose event, ensure Action := caFree to ensure forms get 
freed when closed.

The benefit is, the global is now effectively read only, due to the 
accessor function, so for example buggy code which for example blindly 
creates and overwrites the global causing a memory leak is impossible. 
Furthermore, no other code has to check the form variable and/or create 
the form, it can just be used it and have the form be lazily created on 
the fly just before use.  If the form is closed, it will be freed (due 
to Action = caFree), which in turn will nill the global reference (but 
only if the instance being freed is the "global" one.)  Nevertheless, 
the code will still allow arbitrary client code to declare and create 
their own instances of the form if they want to, and such forms will 
still be freed when they're closed but won't molest the global reference.

Walter

Jamie L. Mitchell wrote:
>
> Just tried it quickly to make sure I still get the error.
>
> In the OnClose event, I put in code to free the dialog as follows:
>
> frmGlobalPointer := NIL;
> Self.Free;
>
>   


[Non-text portions of this message have been removed]

Reply via email to