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.
Command buttons are generally use to make something happen. Perhaps the most common command buttons are the ones labeled “OK” and “Cancel” that appear in dozens of dialogs throughout Windows.
In Visual FoxPro, command buttons can be used both singly and in groups. CommandGroups have a Value property that indicates which button in the group was last chosen. The Value can be either character or numeric. When character, it contains the Caption of the button last chosen. When numeric, it’s the position of that button in the group.
Command buttons can contain text or a bitmap or both. In addition, command buttons can be invisible. Of course, in that case, the bitmap and the caption don’t do you much good. Invisible buttons are one way to put a “hot spot” on a form. A command group can contain any combination of textual, graphical and invisible buttons.
Property |
Value |
Purpose |
AutoSize |
Logical |
Should this button be resized automatically to fit the caption? |
Cancel |
Logical |
Should this button be chosen when the Esc key is pressed? |
Caption |
Character |
The message that appears on the button. |
Default |
Logical |
Should this be the default button, chosen by pressing Enter? |
Picture, DownPicture, DisabledPicture |
Character |
The names (including path) of graphic files to appear on the button. Picture appears when the button is enabled and not pressed. DownPicture appears when the button is pressed. DisabledPicture appears when the button is disabled. |
SpecialEffect |
Numeric |
Determines the appearance of the button—3-D (0), Plain (1), or "hot tracking" (2), in which the button is flat until the mouse passes over it or it gets focus. |
Style |
Numeric |
Determines whether the button is visible (0) or invisible (1). |
VisualEffect |
Numeric |
Determines appearance of the button, set at runtime only—leave existing effect (0), raised (1), or sunken (2). Added in VFP 7. |
Event |
Purpose |
Click |
Fires when the button is "pressed," using either the mouse or the keyboard. |
MouseEnter |
Fires when the mouse moves into the area occupied by the button. |
MouseLeave |
Fires when the mouse moves out of the area occupied by the button. |
Property |
Value |
Purpose |
AutoSize |
Logical |
Should the group be resized to completely contain all of its buttons? |
BackStyle |
Numeric |
Should the group let objects behind it show through or not? Objects behind the buttons themselves do not show through regardless, unless the button's Style is set to invisible. |
BorderColor |
Numeric |
Color used for the border around the group. |
BorderStyle |
Numeric |
Determines whether or not there is a border around the group. |
ButtonCount |
Numeric |
The number of buttons in the group. |
Buttons |
Collection |
References to the buttons in the group. |
Objects |
Collection |
References to the buttons in the group. |
TabIndex |
Numeric |
The tab order of the button within the group. |
Value |
Numeric or Character |
Which button in the group was chosen last? |
Event |
Purpose |
Click |
Fires when a button in the group is "pressed," and doesn't have any Click code of its own. |
InteractiveChange |
Fires when any button in the group is chosen, because the group's Value changes. |
MouseEnter |
Fires when the mouse moves into the area occupied by the button. |
MouseLeave |
Fires when the mouse moves out of the area occupied by the button. |
The relationship between a command group and the buttons in it is different than most of the container/contained object relationships in FoxPro. Normally, if an object doesn’t have code in a particular event anywhere in its class hierarchy, no code runs when that event fires. For command buttons in a command group (and option buttons in an option group), ‘tain’t so. If a button has no Click code, for example, the group’s Click code executes. If the button doesn’t have anything in MouseDown, the group’s MouseDown fires. Pretty cool. In fact, this is what Control Arrays
were supposed to be all about.
However, for properties, the behavior propagates downward, but not the property values. That is, setting Enabled to .F. for a control group disables all the buttons in the group, but they’re not dimmed and their individual Enabled properties remain .T. We’ve got mixed feelings on this one. We can see why it’s nice to maintain the individual values—when you re-enable the group, it’s good that buttons that were disabled before are still disabled. But the lack of a visual cue means we can’t take advantage of this behavior. (In VFP 6 and later, you can use an Assign method for the group’s Enabled to change the Enabled property of the individual buttons in the group. This does raise the issue of remembering what was enabled before the change to the group.)
Since command buttons have a separate existence, there’s no problem subclassing them visually. However, there’s no way visually to tell a subclass of CommandGroup to use your CommandButton subclass. For this reason among others, we rarely use CommandGroups, sticking to individual buttons instead.
Like OptionButtons and OptionGroups, the interaction between the AutoSize properties of CommandButtons and CommandGroups is strange. You can have autosized buttons inside a non-autosized group with the result that the group’s border clips the button itself.
* Perhaps the most common button of all.
* Of course, we'd do this in the Class Designer.
DEFINE CLASS CloseButton AS CommandButton
Caption = "\<Close"
ToolTipText = "Close this form"
PROCEDURE Click
IF EMPTY(ThisForm.PARENT) && A stand-alone form
ThisForm.Release()
ELSE
ThisFormSet.Release() && A formset
ENDIF
ENDPROC
ENDDEFINE
AutoSize, BackStyle, BorderColor, BorderStyle, ButtonCount, Buttons, Cancel Property, Caption, Click, Default, DisabledPicture, DownPicture, InteractiveChange, MouseEnter, MouseLeave, Objects, OptionButton, OptionGroup, Picture, ProgrammaticChange, SpecialEffect, Style, TabIndex, Value, VisualEffect