Article ID:qOOP017
Date Revised:November 14, 1998
Keywords:object references, ObjRef, OOP, reference counter, Form, release, destruct
See Also:Click to download the ObjRef.zip beta test 

Question: Why doesn't my form release after I click the close button?

Answer: This is usually always because there is a object property or a memory variable that is holding a reference to one of the contained objects of the form. For example:

oX = CreateObject( "Form" )
oX.AddObject( "Command1", "CommandButton" )
oX.Command1.Visible = .t.
oX.Visible = .t.

oY = oX.Command1

The variable oY now contains a reference to the CommandButton. This increments it's internal reference counter to 2. Now click the Close button ofthe form. The Close button disables, but the form doesn't go away. The form is stuck in a kind of limbo state. When you do oY = .null. in the command window the form will finally disappear, because the CommandButton's reference counter decrements to zero.

An object can not destruct until its reference counter gets to zero. A container (the Form) can not destruct until all of it's contained objects destruct.

This internal reference counter may seem like a huge annoyance, but it's actually a very nice feature provided by Visual FoxPro. Unfortunately there is no way to backtrack what exactly is keeping your objects from destructing if you have missed cleaning up one of your object references.

I wrote a utility (click the above link to download it) that works it's way through _screen, _screen.Forms[], _vfp, _vfp.Objects[] and current memvars looking for object references and displaying them in another form. The program takes a single argument, plAllObjects, it defaults to .T. if not passed. The above code would cause this display:

ObjRef( .t. ) or ObjRef()ObjRef( .f. )
memory variable OX->Form1
memory variable OY->Form1.COMMAND1
memory variable OY->Form1.COMMAND1

If the parameter is .F. only the references to internal objects are reported. The tool may report the object references more than once depending on where it finds the objects. For example it will report it in the _screen.Forms[] collection and along a memory variable that refers to the same form. The tool makes no attempt to see if more than one item refers to the same object.


1