These two events are just about the only carryovers from FoxPro 2.x's READ that are still useful. When fires when a control is offered focus. If When returns .T., the control can have the focus and its GotFocus event fires. (When also fires at a few other times—see below.) A good rule of thumb is for textual controls (text box, edit box, spinner), Valid fires whenever the control loses focus and determines whether it's allowed to lose focus. If so, the control's LostFocus fires. For non-textual controls, Valid fires when the user does something that could change the control's Value.
PROCEDURE oObject.When | oObject.Valid
[ LPARAMETERS nIndex ]When is pretty simple. It fires when you head for the object. There are only a few surprises. First, the When for a list box fires every time you move the highlight in the list. This behavior is the same as that of lists in 2.x and is very handy. It lets you do something, like update other controls, as the user moves through the list.
Second, the When for some controls fires more than once when you use the control. When you use a button (command or option), check box, or combo, if focus will still be on that control afterwards, the When fires following the Valid. If you click on the control, you get the following sequence: When, GotFocus, Valid, When.
Finally, ActiveControl doesn't point to the control whose When you're executing. The control doesn't become ActiveControl until When returns .T. and GotFocus fires.
Returning a non-zero value is even trickier. Lists and option buttons totally ignore numeric returns, as do controls in a grid. Other controls do move the focus forward or backward the specified amount. However, we strongly recommend you stay away from this approach—it's just plain too confusing. It's kind of a shame this technique isn't easier to use, because it's one way to work around the fact that you can't call SetFocus from the Valid method of a textual control—in other words, from those controls where Valid really means a validity check.
Figuring out when the Valid for an object fires was confusing in FoxPro 2.x and it's still somewhat confusing. For controls that accept text (the same ones that pay attention to Return .F.), it's easy—it always fires when you leave, whether you click, tab, press Enter, or do something else.
Other controls fire their Valids only when they feel used. Clicking on a button or check box fires its Valid. So does pressing Spacebar or Enter. For a combo (with Style set to either combo or dropdown), Valid fires when you choose something from the list with the mouse or with Spacebar or Enter. A list's Valid fires only when you double-click an item or press Enter.
As an extra added attraction, several of the containers have When and Valid events of their own. The events for button groups fire right after the same event for the button itself. A grid's When fires when you first enter the grid. The grid's Valid fires when you leave the grid.
Finally, all the comments about which keystrokes fire Valids apply only when KEYCOMP is set to Windows. With KEYCOMP set to DOS, some different keystrokes fire objects' Valids.
Last but not least (didn't we just say "finally"?), if SET NOTIFY is ON (not something we generally recommend), when a Valid returns .F., a wait window saying "Invalid Input" appears. If there's code in the control's ErrorMessage, that runs first, but then the "Invalid Input" window appears. To avoid this, either SET NOTIFY OFF or RETURN 0 rather than .F. from the Valid.
* See if user input is acceptable in a text box for grade entry
PROCEDURE txtGrade.Valid
IF BETWEEN(This.Value,"A","F")
RETURN .T.
ELSE
WAIT WINDOW "Invalid grade. Try again" NOWAIT
RETURN .F.
ENDIFControl Arrays, ErrorMessage, GotFocus, LostFocus, Set KeyComp, Set Notify

