Why doesn't my form close?
If you run the code below, you’ll get an error message. The grid height is being set to 19, which is too small for a vertical scrollbar. Dismiss the message and try to close the form. If you hit Ctrl-F4 or click on the close box, the close box gets dim, but the form doesn’t close. If you CLEAR ALL in the command window, the form is released.
If you change the 19 to 39 so it is a valid height, the form can close.
Why?
To figure out the answer, I used the VS debugger to trace through the VFP internal code that closes the form. When an object is asked to be released, VFP tries to see if the object can close. If there are any member objects on the form, each one must have a reference count of one. If there is any member object that has an outstanding reference, then the form says that it cannot close. As you can imagine, this process is recursive.
For example, change it to 39 for the non-error case, run the form and get an outstanding reference to the form by typing NewVar=oForm.spin1. This creates a new variable called NewVar which references the spinner. Now the form cannot close as in the error case. Set NewVar to 0, and the form disappears.
Internally, for a routine that handles for example, a spinner keypress event, VFP will increment the refcount on the spinner, call the code to handle the event, then decrement the refcount. This protects VFP from user code that releases the object in the event.
There was some code that was incrementing the refcount, encountering the error, and the error caused that code’s matching refcount decrement to be bypassed. This code was processing CanLoseFocus, which was storing the spinner value to the grid height, which caused the error.
The fix is simple: don’t bypass the decrement if an error occurs.
Thanks to Fabio Lunardon for this bug report.
PUBLIC oform
oForm = NEWOBJECT("form1")
oForm.Show
KEYBOARD '19{TAB}' PLAIN
DEFINE CLASS form1 AS form
ADD OBJECT grid1 AS grid
ADD OBJECT spin1 AS spinner WITH ;
format = 'K',;
Left = 108, ;
Top = 96, ;
ControlSource = "thisform.grid1.height"
ENDDEFINE
Comments
Anonymous
August 29, 2006
Here is another case; what do you think: is related?
************* cut here
Comment the define and rerun the program
#Define USE_BINDEVENT
Activate Screen
Clear
Local oForm
oForm = NewObject('MyForm')
If Vartype(oForm) == 'O'
? "A form was created: this is not the expected behaviour"
oForm.Show(1)
Else
? "No form was created: this is the expected behaviour"
EndIf
Define Class MyForm As Form
Autocenter = .T.
#Ifdef USE_BINDEVENT
Procedure Load
BindEvent(This, 'Init', This, 'InitCompleted', 1)
EndProc
Procedure InitCompleted
? 'InitCompleted fired'
EndProc
#EndIf
Procedure Init
Return .F.
EndProc
EndDefine
** cut here *************Anonymous
October 20, 2006
Here’s a blog post that I wrote a long time ago, but forgot to publish. Marco Cenzato commented on WhyAnonymous
March 14, 2007
Du musst ein Fachmann sein - wirklich guter Aufstellungsort, den du hast!Anonymous
April 10, 2007
Luogo molto buon:) Buona fortuna!Anonymous
April 10, 2007
pagine piuttosto informative, piacevoli =)Anonymous
April 13, 2007
9 su 10! Ottenerlo! Siete buoni!Anonymous
April 14, 2007
Stupore! ho una sensibilit molto buona circa il vostro luogo!!!!Anonymous
April 15, 2007
E grande io ha trovato il vostro luogo! Le info importanti ottenute! ))Anonymous
April 11, 2008
Good idea! P.S. A U realy girl?