"Session #" (inserted at later date)

Event Driven Programming
in Visual FoxPro

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

Overview

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?

Event

Applies to:

What it does / what to put there

INIT

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.

ERROR

Same

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

DESTROY

Above, plus CommandGroup and OptionGroup

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

DRAGOVER,  DRAGDROP

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.

MOUSEMOVE

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.

CLICK, MOUSEDOWN, MOUSEUP

Not to Column, otherwise same as above

Mouse click

 

UIENABLE

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.

RIGHTCLICK

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

Right mouse click on control.

GOTFOCUS, LOSTFOCUS

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

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

VALID, WHEN

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.

ERRORMESSAGE

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"

MESSAGE

same as above

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

KEYPRESS

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

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

MOVED

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

Fires when the object has been moved.

 

RESIZE

same

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.

ACTIVATE, DEACTIVATE

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

RANGEHIGH, RANGELOW

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.

DOWNCLICK

ComboBox, ListBox, Spinner

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

LOAD, UNLOAD

Form, FormSet

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

PAINT

Form, Toolbar

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

BEFOREOPENTABLES, AFTERCLOSETABLES

Data Environment

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

AFTERDOCK, BEFOREDOCK, UNDOCK,

Toolbar

Code which can run while user is manipulating a toolbar.

BeforeRowColChange, AfterRowColChange

Grid

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

DELETED

Grid

When user marks or unmarks a row for deletion.

SCROLLED

Grid

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

DROPDOWN

ComboBox

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

TIMER

Timer

Fires when Timer is enabled and Interval has passed.

QUERYUNLOAD

Form

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

READACTIVATE, READDEACTIVATE, READSHOW, READVALID, READWHEN

Form

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