Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
When it comes to debugging, these may the two most important properties around. They give you a hook into whatever’s going on at the moment. Both provide object references. ActiveForm points you to the form that contains the focus in a formset, or even just the form with focus without regard to formsets. ActiveControl points you to the control that has focus on a form.
frmCurrentForm = frsFormSet.ActiveForm
frmCurrentForm = _SCREEN.ActiveForm
oCurrentControl = frmForm.ActiveControl
Although these properties are themselves read-only (that’s why the syntax goes only one way), you’ll usually use them on the left-hand side of the “=” as part of a reference to a property of a form or a control on it. You can both test and change properties this way.
For debugging, the combination you’ll use the most is _SCREEN.ActiveForm, which lets you touch the form that has focus. (You can also use _VFP.ActiveForm, but we suspect that, when you’re working inside VFP, the _SCREEN format is cheaper.) You can put expressions like _SCREEN.ActiveForm.Height (or even _SCREEN.ActiveForm.pgfAbout.pagMemory.txtFreeMemory.Value) in the Watch window or in DebugOut commands and watch them change as you manipulate the form. You can also use similar expressions in the Command Window and assign new values to the properties to see how the changes affect the form. We use this technique extensively to cut down the design-test-design-test cycle. Just try things out on a live form. If you like it, incorporate it; otherwise, go on and try something else.
Utterly annoying, however, is that when you switch focus to the Debugger, ActiveControl no longer works. Even if the Debugger is sitting in its own frame. Since even our humongous monitors make it hard for us to position both VFP and the Debugger so that each is fully visible, this is truly a pain. Now that we have a really good debugger, among the things this complicates is drilling down into the control with focus. We have to go to the form level, find the right control (but how do we know which one it is when ActiveControl no longer tells us!), and start from there. |
Because toolbars never get focus, ActiveForm and ActiveControl are useful in methods of the controls on toolbars. You can figure out where the user was before he or she clicked on the toolbar and take appropriate action. This simplifies sharing a toolbar among multiple forms.
When the focus is in a grid, ActiveControl always points to the grid rather than to the individual control within the grid, which actually has focus. Thanks to our friend Drew Speedie, we have a way to climb down the containment hierarchy and find out which control is really in control here, but it ain't pretty: local loControl, lcActiveControl, lcJunk loControl = _SCREEN.ActiveForm.ActiveControl IF UPPER(ALLTRIM(loControl.BaseClass)) = "GRID" FOR i = 1 TO loControl.ColumnCount IF loControl.Columns[i].ColumnOrder = loControl.ActiveColumn * Name of the real ActiveControl: lcActiveControl = loControl.Columns[i].CurrentControl * Object reference to ActiveColumn: loControl = loControl.Columns[i] * Text string representing ActiveControl reference: lcJunk = "loControl." + lcActiveControl * Object reference to the real ActiveControl: loControl = &lcJunk EXIT ENDIF ENDFOR ENDIF |
* With a form running, you can change its
* title from the Command Window like this:
_SCREEN.ActiveForm.Caption = "Look what I can do!"
* To see the name of the control with focus:
? _SCREEN.ActiveForm.ActiveControl.Name
* To call a method of the active form from
* a button on a toolbar, put something like this
* in the button's Click:
_SCREEN.ActiveForm.Save()