"Session #" (inserted at later date)

Event Driven Programming
in Visual FoxPro

Ted Roche
Computer Resource
278 Kearsarge Avenue
Contoocook, NH
CIS: 76400,2503


Visual FoxPro's new event model, combined with the robustness of the object model and the addition of many new events, allows truly modeless programming with far finer control of the behavior of your system. We'll examine the new events available to programmers and their implications for application development.


What are Events?

"An action, recognized by an object, for which you can write code to respond. Events can be generated by a user action, such as clicking the mouse or pressing a key, by program code, or by the system, as with timers."

- FoxPro Help File

Event firing sequences

Probably some of the most difficult functionality to understand. Typically, a container cannot perform its action until its contents exist, therefore, objects are created from the inside out: textbox–›column–›grid–›page–›pageframe, and destroyed in the opposite fashion, from the outside in, imploding.

How to program for events?

The Foundation read is no more, except for legacy code we attempt to migrate to Visual FoxPro. Forms are it. The concept behind Visual FoxPro is that the initial application environment can be set up, a menu can be hoisted to the top of the screen, and READ EVENTS will hold the entire application together until the user chooses to quit. Time will tell if this model proves robust enough for commercial applications.

So what are the new events?


Applies to:

What it does / what to put there


All but Column, Header, Page, Separator

Fires when the object is created, optionally accepts parameters. If it returns .F., object is not created. Contained objects fire before containers, in the order added.



Fires when an error occurs in the method of an object - passes error #, method name and line number. Fires before ON ERROR.


Above, plus CommandGroup and OptionGroup

Code runs just before an object is released. Containers fire before contents.


Above, plus Cursor, Custom, DataEnvironment, FormSet, Relation, Timer

Fires during and upon completion respectively of a drag & drop operation. Code must include parameters statement to accept the dragged object reference and mouse coordinates.


Column, but not to above, plus OLEControl, OLEBoundControl

Tracks mouse movements over an object. Also passes status of Ctrl-Alt-Shift keys, as well as left, middle and right mouse button statuses.


Not to Column, otherwise same as above

Mouse click



CheckBox, ComboBox, CommandButton, CommandGroup, Container, Control, EditBox, Grid, Image, Label, Line, ListBox, OLEBoundControl, OLEControl, OptionGroup, PageFrame, Shape, Spinner, TextBox

Fires when control becomes visible because of activation of container, such as PageFrame.


Above, plus Form, Header, OptionButton, OptionGroup, but NOT OLEBoundControl, OLEControl

Right mouse click on control.


CheckBox, ComboBox, CommandButton, Container, Control, EditBox, Form,  ListBox, OLEBoundControl, OLEControl, OptionButton, Spinner, TextBox

Occurs when the control is tabbed to, or clicked on.


CheckBox, ComboBox, CommandButton, CommandGroup, EditBox, Grid,  ListBox,  OptionButton, OptionGroup, Spinner, TextBox

Good old WHEN and VALID, fire before accepting a change (after receiving focus) and after a change is made.


CheckBox, ComboBox, CommandButton, CommandGroup, EditBox, ListBox,  OptionButton, OptionGroup, Spinner, TextBox

When VALID returns a .F., allows display of an error message. "Included for backward compatibility"


same as above

Displays status bar text. Another " backward compatibility." Property StatusBarText provides similar capabilities.


CheckBox, ComboBox, CommandButton, EditBox, Form, ListBox, OptionButton, Spinner, TextBox

Allows processing of input keystroke-by-keystroke, rather than waiting for input to be completed.


Column, Container, Control, Form, Grid, OLEBoundControl, OLEControl, PageFrame, Toolbar

Fires when the object has been moved.




Fires when the object has been resized.

InteractiveChange, ProgrammaticChange

CheckBox, ComboBox, , CommandGroup, EditBox, ListBox, OptionGroup, Spinner, TextBox

What UPDATED() always should have been, but at a finer level. Fires each time a change is made via mouse or keyboard, even before focus has shifted from the control. INTERACTIVE detects user changes, PROGRAMMATIC changes performed in code.


Form, FormSet, Page, Toolbar

Similar to the 2.x Screen's show clause. Occurs when container gets the focus or Show() method runs. Toolbar.Hide() also runs DEACTIVATE


ComboBox, Listbox, Spinner, TextBox

Dual functions. For ComboBox and ListBox, returns the initially selected element when the control gets the focus. For Spinners & TextBoxes acts as a RANGE test, returning a numeric when focus to the control is lost.


ComboBox, ListBox, Spinner

Not to be confused with MOUSEDOWN, fires when the down- or up-ward-pointing arrow is pressed.


Form, FormSet

Load occurs after Init, but before Activate and GotFocus. UnLoad is the last event to fire.


Form, Toolbar

When the item re-paints. CAUTION: don't RESIZE or refresh() objects within PAINT or a "cascading" series may occur!


Data Environment

Wrappers around the automatic behavior of the Data Environment. Occurs before OpenTables() method and after CloseTables() methods.



Code which can run while user is manipulating a toolbar.

BeforeRowColChange, AfterRowColChange


Before the Valid of the row or column of the cell being left, and after the When of the cell being moved to.



When user marks or unmarks a row for deletion.



User movement, parameter will return whether by cursor keys or scroll bars and which one.



Fires after DOWNCLICK, to allow interactive changes to the contents of the drop down list.



Fires when Timer is enabled and Interval has passed.



Allows testing the ReleaseType property to determine if a form is being released using the close box or programmatically.



Similar to 2.x READ model, only works in 'Compatibility' modes


What to do now?

Experiment. 90% of the time the standard WHEN and VALID will provide all the functionality needed in data entry fields. Specialized input fields, such as Spinners, have finer control. Click is a more intuitive place to put button firing code than VALID, but either (though not necessarily both!) work. Add new Events to your arsenal as the need arises. Anticipate some great third party tools which know how to really take advantage of all the new features.

The included application demonstrates several of the nicer features, including resizing, sensing mouse movements and detecting mouse and keyboard presses.


About the Speaker

Ted Roche is principal with Computer Resource of Contoocook, NH. His latest book project, "The Hacker's Guide to Visual FoxPro for Windows", is written with co-author Tamar Granor, with whom he also writes the Q&A column for FoxPro Advisor magazine. Ted was a contributing author to the best-selling "Using FoxPro 2.5", and was a technical editor for four FoxPro 2.5 books. He is a Microsoft Certified Professional in Windows and was named a Most Valuable Professional by Microsoft in 1994 for his support of FoxPro on CompuServe.

Ted is a popular speaker at professional and user group conferences in North America and Europe. He is co-editor of the Boston Computer Network News, a Foxpro newsletter freely distributed on the Internet. He may be reached at 76400.2503@compuserve.com