Migrating Your MS FoxPro 2.x-based Applications
David Anderson
Alden Anderson Inc.
Introduction
Microsoft® Visual FoxPro™ database forms are converted in a “Read” compatibility mode. It is important to grasp how this mode functions in order to understand what changes should be made to converted forms to enable them to operate in a fully event-driven model. This session covers all aspects of the “Read Compatibility” mode and how to make changes to forms so that they can take full advantage of the Visual FoxPro event model.
Visual FoxPro's "Read Compatibility" Mode
Overview
Several features have been included in Visual FoxPro to provide full support for screens created using Microsoft FoxPro® 2.x. These features include properties and events on the FormSet, Form and controls, special variable scoping in the FormSet Load and Form Load events, the use of Pageframes and Pages for read levels, and the availability of @ ... GET, @ ... EDIT, @ ... SAY, @ ... TO, and READ commands.
The "Read" FormSet
When a FoxPro 2.x screen is converted to Visual FoxPro form, a FormSet will always be created to contain the form. If the screen is converted from a screen set, one FormSet will be created to contain all of the forms in the screen set.
FormSet WindowType Property
The FormSet WindowType property is what identifies its contained Form(s) as operating in “read” mode. Valid values for the FormSet WindowType property are 0 (Modeless), 1 (Modal), 2 (Read), and 3 (Read Modal). For “read” mode Forms, the property must be set to 2 or 3.
If the FormSet WindowType property is set to 2, the FormSet behaves as if it were activated by the READ command. If the FormSet WindowType property is set to 3, the FormSet behaves as if it were activated by the READ MODAL command. Program execution stops at the Show method or the DO FORM command. When the FormSet is deactivated, execution continues.
The WindowType setting of a FormSet overrides the individual WindowType settings of the Form objects it contains. For example, if the WindowType property for a FormSet is set to 2, all the Form objects contained in it are read (modeless), regardless of their individual WindowType property settings.
Parameter Passing to FormSets with WindowType = 2 or 3
Visual FoxPro will pass parameters to FormSets with WindowType = 2 or 3 to the FormSet Load event. When the FormSet WindowType = 0 or 1 the parameters are passed to the FormSet Init event.
Other FormSet Properties and Events
Once the WindowType of a FormSet is set to 2 or 3, several properties and events become available for use by the program. These properties and events are included for backward compatibility and do nothing when the FormSet WindowType is not 2 or 3.
FormSet Properties
Visual FoxPro FormSet Property | FoxPro 2.x Equivalent | Functionality |
ReadCycle | READ CYCLE | Specifies whether the focus moves to the first object in a FormSet when the focus moves beyond the last object in a FormSet. |
ReadLock | READ LOCK | Specifies whether all records that are referenced on any of the Forms in the FormSet are locked. |
ReadMouse | READ NOMOUSE | Specifies whether you can move between controls using the mouse on the Forms contained in a given FormSet. |
ReadSave | READ SAVE | Specifies whether the READ command can be used to re-activate an object. |
ReadTimeout | READ TIMEOUT | Specifies how long the FormSet remains active with no user input. |
FormSet Events
Visual FoxPro FormSet Event | FoxPro 2.x Equivalent | Functionality |
Load | #SECTION 1 Setup Code | Occurs just before the FormSet is created. |
ReadActivate | READ ACTIVATE | Occurs when a new Form in the FormSet is made active. |
ReadDeactivate | READ DEACTIVATE | Occurs when a new Form in the FormSet is deactivated. |
ReadShow | READ SHOW | Occurs when a SHOW GETS command is issued on the active FormSet and when a FormSet is activated. |
ReadValid | READ VALID | Occurs just before a FormSet is deactivated. |
ReadWhen | READ WHEN | Occurs when a FormSet is activated. |
FormSet Variable Scoping
Variables created in the FormSet Load of a FormSet with WindowType = 2 or 3 are scoped to the FormSet and visible to the entire FormSet, its Forms and controls. Variables created in other FormSet events (or methods) will only be visible as specified (i.e., PRIVATE, PUBLIC, or LOCAL).
The "Read" Form
Form Properties and Events
Window settings used in FoxPro 2.x are mapped to Visual FoxPro Form properties.
Form Properties
Visual FoxPro Form Property | FoxPro 2.x Equivalent | Functionality |
Name | Screen Name | Specifies the name of the form. |
Top | Vertical Position | Determines the distance between the top edge of the Form and the main Visual FoxPro window. |
Left | Horizontal Position | Specifies the distance between the left edge of the Form and the main Visual FoxPro window. |
Height | Height | Specifies the vertical dimension of the Form. |
Width | Width | Specifies the width of the Form. |
Caption | Title | Specifies the text displayed in the Form’s title bar. |
FontName | Font (FontFace) | Specifies the name of the font used to display text. |
FontBold | Font Style Bold | Specifies that text is bold. |
FontItalic | Font Style Italic | Specifies that the text it italic. |
FontSize | Font Size | Specifies the size of the font. |
Movable | Window Attribute Moveable (Float) | Specifies whether the Form can be moved at run time by the user. |
Closable | Window Attribute Close | Specifies whether the Form can be closed by double-clicking the Control-menu box or choosing Close from the Control menu. |
HalfHeightCaption | Window Attribute Half Ht Title Bar | Specifies whether the caption of a Form is half the normal height. |
MinButton | Window Attribute Minimize | Specifies whether a Form has a Minimize button. |
BorderStyle | Border | Specifies the border style of the Form. |
AutoCenter | Center | Specifies whether the Form is automatically centered in the main Visual FoxPro window the first time it is displayed. |
Icon | Window Icon | Specifies the icon displayed for a Form at run time when the Form is minimized. |
Form Events
Visual FoxPro Form Event | FoxPro 2.x Equivalent | Functionality |
Load | #SECTION 2 Setup Code | Occurs just before the Form is created. |
Unload | Cleanup Code | Occurs when the Form is released. |
Form Variable Scoping
Variables created in the Form Load event are scoped to the Form and visible to the FormSet, its Forms and controls when a FormSet with WindowType = 2 or 3 exists. Variables created in other Form events (or methods) will only be visible as specified (i.e. PRIVATE, PUBLIC or LOCAL).
"Read" Mode and Controls
"Read" Mode Usage of PageFrames and Pages
Whenever the FormSet WindowType = 2 or 3, there must be a PageFrame containing at least one Page control on each Form in the FormSet. Each Page in the PageFrame represents one read level. Therefore, if there is one read level on the form, there should be one Page in the PageFrame, if there are two read levels, there should be two Pages in the PageFrame, and so on. The controls contained within each Page are the controls that will participate in the read level specified by the Page. Page1 is read level 1, Page2 is read level 2, and so on.
When a program issues any @ ... GETs, Visual FoxPro will create a PageFrame, if one does not already exist, and a new Page to handle the new read level. The @ ... GETs will be controls contained within the newly created Page. When the READ statement is issued, the Page and its contained controls will become active. Once the READ terminates, the Page created for the read level will be destroyed, along with the controls created by the @ ... GETs. If the PageFrame was created for the Page (i.e. the Page was Page1), it will also be destroyed.
Control Properties and Events
@ ... SAYs, @ ... GETs, @ ... EDITs, @ ... TOs and their FoxPro 2.x settings are mapped to Visual FoxPro controls. @ ... snippet code from FoxPro 2.x is mapped to the corresponding control event code in Visual FoxPro.
Control Properties (Core Set)
Visual FoxPro Control Property | FoxPro 2.x Equivalent | Functionality |
Top | Vertical Position | Specifies the top-most edge of the control. |
Left | Horizontal Position | Specifies the distance between the left edge of a the control and the left edge of its container object. |
Height | Height | Specifies the vertical dimension of the control. |
Width | Width | Specifies the width of the control. |
Format, InputMask | Picture | Format: Mimics the behavior of the FUNCTION clause for the @ ... GET and @ ... EDIT commands.InputMask: Specifies the data-entry rule for each character entered in the control. |
FontName | FontFace | Specifies the name of the font used to display text. |
FontBold, FontItalic | FontStyle | Specify that text is either Bold or Italic. |
FontSize | FontSize | Specifies the font size for text displayed with an object. |
Caption | Label Expression (Expr) | Specifies the text displayed in an object’s caption. |
BackColor | FillColor | Specifies the background color used to display text and graphics in an object. |
ForeColor | PenColor | Specifies the foreground color used to display text and graphics in an object. |
BackStyle | Mode | Specifies whether the background of an object is transparent or opaque. |
Alignment | Text Alignment | Specifies the alignment of text associated with a control. |
Name | Name | Specifies the name of the control. |
ControlSource | Name | Specifies the source of data to which an object is bound. |
Enabled | .not. Disabled | Specifies whether an object can respond to user-generated events. |
TerminateRead | Terminate READ on Selection | Specifies whether or not the READ command is terminated when a control receives the focus. |
Value | Initial Value | Specifies the current state (value) of a control. |
SpinnerHighValue | Maximum (Tag2) | Specifies the highest value that can be entered into a Spinner control by clicking on the up arrow. |
SpinnerLowValue | Minimum (Tag) | Specifies the lowest value that can be entered into a Spinner control by clicking on the down arrow. |
BorderWidth | Pen Size | Specifies the width of a control’s border. |
DrawStyle | Pen Pattern | Specifies the line style to use when drawing with graphics methods. |
FillStyle | Fill Pattern | Specifies the pattern used to fill Shapes and figures created with the Circle and Box graphics methods. |
Stretch | Scale Picture | Specifies how an image is sized to fit inside an Image control. |
Style | Picture Check Box | Specifies the style of a control. |
Note Option buttons are converted to Option Groups, Command buttons are converted to Command Groups.
Control Events
Visual FoxPro Control Event | FoxPro 2.x Equivalent | Functionality |
When | When | Occurs before a control receives the focus. |
Valid | Valid | Occurs before a control loses the focus. |
Message | Message | Displays a message in the status bar at the bottom of the screen. |
Error | Error | Occurs when there is a run-time error in a method. |
RangeHigh | RangeHi | TextBox, Spinner low range, ListBox, ComboBox 1st Element |
RangeLow | RangeLo | TextBox, Spinner high range, ListBox, ComboBox # of Elements |
Event Firing Sequence
When the FormSet WindowType = 2 or 3, the order of events is as follows:
FormSet Load
Form Load
Controls Init (Inside to Outside)
Form Init
FormSet Init
FormSet ReadWhen
FormSet ReadActivate
FormSet ReadShow
FormSet Show
Form Show
FormSet Activate
Form Activate(when event of first control)
Control Valid event
. . .
Form Deactivate
FormSet Deactivate
FormSet ReadDeactivate
FormSet ReadValid
Controls Destroy (Outside to Inside)
FormSet Destroy
Form Destroy
Form Unload
FormSet Unload
Moving from "Read Compatibility" Mode into the Event Model
Overview
The GOOD NEWS is that Visual FoxPro’s converter does so much work! Most form and control properties have already been set!
There are, however, some changes that should be made to FormSets, Forms and code to allow applications to run fully in the event model.
Remove/Change the FormSet and Form
If there is only one Form in the FormSet, the FormSet should probably be removed (leaving the form, of course). But before doing this, all code in the FormSet events must be moved to the appropriate places in the Form events, otherwise the code will be removed along with the FormSet.
If there is more than one Form in the FormSet, the FormSet cannot be removed.
Change the FormSet WindowType Property and Move Event Code
If the FormSet will not be removed, several changes should be made to it. First, the WindowType property should be changed from 2 (read) or 3 (read modal) to 0 (modeless) or 1 (modal). This change will require the code in the FormSet ReadWhen, ReadActivate, ReadShow, ReadDeactivate, and ReadValid code to be moved to other events because they will not fire when the FormSet WindowType property is 0 or 1. The code in ReadWhen, ReadActivate, and ReadShow should be moved to the FormSet Show and Activate events, with care being given to make sure that sequence that the code will execute is correct. Note that the event firing sequence in FoxPro 2.x is When, Active and then Show, while the event firing sequence in Visual FoxPro is Show and then Activate.
If the FormSet will be removed, The FormSet Read... events should be moved to the Form Show and Activate events, with the same care given to the sequence that the code will execute (as described above). Additionally, the FormSet Load code should be moved to the Form Load event.
Parameters are passed to the FormSet Load event when the FormSet WindowType = 2 or 3 and to the FormSet Init when the FormSet WindowType = 0 or 1. All parameter handling code will need to be moved to the Init event of the FormSet if the FormSet is not removed or to the Init of the Form if the FormSet is removed.
Create FormSet or Form Properties for Variables created in FormSet Load
When the FormSet WindowType property is not 2 or 3 or the FormSet is removed, no special scoping of variables created in the FormSet Load or Form Load occurs. Properties should be added to the FormSet for each variable needing to be scoped to the FormSet. If the FormSet is removed, these properties should be added to the Form instead. Properties also should be added to the Form for variables needing to be scoped to the Form.
Remove the PageFrame and Page
For each Form in the FormSet, the PageFrame and Page should be removed. Before deleting them, however, make sure that all controls contained within the Page are copied to the clipboard (select all controls contained within the Page and press Ctrl-C or select Copy from the Edit menu. Note that you will need to make the Page the current object in the property sheet before you will be able to select the controls contained within it. Once all the controls have been copied to the clipboard, re-select the PageFrame and press the delete key. This should delete the PageFrame and Page from the Form (if the PageFrame remains, press the delete key one more time to make sure it is removed). Make the Form the current object in the property sheet and press Ctrl-V or select Paste from the Edit menu. This will place the controls that were copied to the clipboard back on the Form. The controls may need to be moved.
Change Code
CLEAR READ
Any occurrences of CLEAR READ will need to be changed to RELEASE ThisFormSet or RELEASE ThisForm (depending on whether the FormSet remains).
SHOW GETS
Any occurrences of SHOW GETS will need to be changed to ThisFormSet Refresh or ThisForm Refresh (depending on whether the FormSet remains).
Change Foundation READ to READ EVENTS
We are no longer in “Read” mode. Change to READ EVENTS.
CLEAR READ
Any occurrences of CLEAR READ should be changed to CLEAR EVENTS.
Get Rid of the .SPR?
Procedures and Functions in the .spr can be turned into methods for the various objects that they pertain to. If all of them are changed to methods, the .spr file can be disposed of. Make sure all program statements that call the form with the statement DO x.spr are changed to DO FORM x (passing parameters, if necessary).
What Else?
At this point, your Form should run in the event model. Other things to consider include analyzing your program to see where the use of classes may be beneficial and how to take full advantage of the Data Environment and Sessions.