|Visual FoxPro 9.0 SP2|
Included for backward compatibility. Use theinstead.
This command is undocumented in the original VFP9 help file,
but the following documentation was found in the FoxPro for Windows 2.6 help, and may still be valid:
Activates objects created with @ ... GET and @ ... EDIT commands.
READ [CYCLE] [ACTIVATE expL1] [DEACTIVATE expL2] [MODAL] [WITH window title list] [SHOW expL3] [VALID expL4 | expN1] [WHEN expL5] [OBJECT expN2] [TIMEOUT expN3] [SAVE] [NOMOUSE] [LOCK | NOLOCK] [COLOR color pair list | COLOR SCHEME expN4]
READ activates objects. Objects are GET fields, check boxes, lists, popups, push buttons, radio buttons, spinners and text editing regions defined with @ ... GETs. READ activates all objects created after the last READ or CLEAR GETS was issued.
Exiting the READ
A user can exit a READ in several ways. Moving forward past the last object or backward past the first object exits READ (if the CYCLE clause isn't included with READ). Pressing Escape, Ctrl+W or choosing a control that was defined to terminate the READ also exits the READ.
A READ can span multiple windows. You can place objects in different windows and activate all of them with a single READ. When you move the cursor from object to object, the objects are traversed in the order they are created, regardless of the window they are placed in.
When you move the cursor to an object, the window that contains the object is activated and becomes the current output window when the current object is in the window. When you press Tab, Enter or Down Arrow when the cursor is positioned on the last object in a window, the cursor is positioned on the first object in the next window. When you press Shift+Tab or Up Arrow when the cursor is positioned on the first object in a window, the cursor is positioned on the last object in the previous window. SHOW GETS contains an example of multi-window reads.
Nested READs are created by defining objects and issuing READ in a routine called while a READ is active. READ commands can be nested to a depth of five levels. RDLEVEL() returns the level of the current READ. The RDLEVEL() topic in this online help facility contains an example with nested READ commands.
Event Execution Order
The following list shows the order in which READ events and clauses are executed when the READ is first issued:
READ level WHEN clause is executed
First GET window is activated
READ level ACTIVATE clause is executed
READ level SHOW clause is executed
GET level WHEN clause is executed for first GET
The following list shows the order in which READ clauses are called when a new window is activated:
VALID clause for the field being exited is executed
Window of field being exited is deactivated
Window of new GET field is activated
READ level DEACTIVATE clause is executed
READ level ACTIVATE clause is executed
WHEN clause for the new field is executed
If the CYCLE clause is included, the READ isn't terminated when you move forward past the last object or backward past the first object. If the cursor is positioned on the last object and you press Tab, Enter or the Down Arrow, the cursor is repositioned on the first object. If you are positioned on the first object and press Shift+Tab or the Up Arrow, you will be repositioned on the last object. If CYCLE is included, pressing a terminating button, Escape, Ctrl+W, or issuing CLEAR READ or a TIMEOUT clause is required to terminate the READ.
The ACTIVATE clause is executed when READ is issued and whenever the current READ window changes. ACTIVATE can be viewed as a window level WHEN clause.
The logical expression expL1 is typically a user-defined function. WOUTPUT() can be used in the user-defined function to determine which window is activated. The user-defined function can disable @ ... GET objects in other windows, hide windows, display a message and so on.
The DEACTIVATE clause is executed whenever you attempt to bring any other window forward (that is, whenever WONTOP() changes). DEACTIVATE can be viewed as a window level VALID clause.
The logical expression expL2 is typically a user-defined function. The user-defined function can be used to validate the contents of fields in a window before allowing you to bring forward another window. The READ isn't terminated if the user-defined function returns false (.F.). The READ is terminated if the user-defined function returns true (.T.).
Including the MODAL key word in READ prevents all windows from being activated with the exception of windows that are involved in the READ. If windows that are not involved in the READ are defined when a MODAL READ is issued, they cannot be activated or accessed.
WITH window title list
By default, all interactive windows (Browse windows, desk accessories and windows opened with MODIFY FILE, MODIFY REPORT, and so on) can participate in a READ. Include the WITH clause to restrict the windows that participate in the READ. The windows included in the WITH clause can include FoxPro system windows (Browse windows, desk accessories and text and memo editing windows).
Including the WITH clause automatically creates a MODAL READ.
Include the Browse window title (by default, the table alias) in the window list to make a Browse window accessible.
Include the table alias in the window list to make a memo window accessible.
If a window title contains a character that isn't alphabetic, numeric or an underscore, include the part of the title up to the first character that isn't alphabetic, numeric or an underscore in the window list. For example, if the window title is Client List, include Client in the window list (the space between Client and List isn't alphabetic, numeric or an underscore).
If a window title contains a character that isn't alphabetic, numeric or an underscore, you can place the title in quotation marks in the window list. For example, if the window title is Client List, you can include "Client List" in the window list.
The SHOW clause is executed whenever SHOW GETS is issued. The value returned by a SHOW routine is ignored. A SHOW routine can be used to refresh @ ... SAYs or to enable or disable objects.
VALID expL4 | expN1
The VALID clause is evaluated when you attempt to exit the current READ or when a READ issued without a previous @ ... GET clause times out. The VALID clause can specify a logical or numeric expression or a user-defined function (UDF) that returns a logical or numeric value.
The READ is terminated if expL4 evaluates to true (.T.). If VALID expL4 evaluates to a logical false (.F.), the current object remains active if possible.
If the object cannot remain active (perhaps the VALID routine deactivated the object), you are moved to the first object.
If the VALID clause returns a number, you are moved to the corresponding object. The READ is terminated if an object corresponding to the number doesn't exist. A VALID clause returning a value that isn't of logical or numeric type has the same effect as one returning true (.T.).
The WHEN clause determines if the READ is executed. expL5 must evaluate to true (.T.) when the READ is issued for the READ to be executed. The READ is ignored and program execution continues with the command immediately following the READ if expL5 evaluates to false (.F.).
Include the OBJECT clause to specify which object is initially selected when READ is issued. expN2 determines which object is initially selected. Object numbers are determined by the order in which the objects are created.
Each individual push, radio and invisible button is considered one object. In the following program example, a field and three radio buttons are created. The middle radio button is initially selected by including the OBJECT 3 clause with the READ. The NAME field is object number 1, the first radio button is object number 2, the second radio button is object number 3 and the last radio button is object number 4.
STORE 1 TO radio
STORE SPACE(10) TO name
@ 2,2 SAY 'Enter a name: ' GET name
@ 4,2 GET radio PICTURE '@*R Apples;Oranges;Lemons'
READ CYCLE OBJECT 3
A TIMEOUT clause determines how long the READ is in effect. expN3 specifies the number of seconds that can elapse without user input before the READ is terminated. If the READ is terminated by a TIMEOUT clause, READKEY() returns 20 if changes have not been made to any object. If changes have been made, READKEY() returns 276.
When READ is terminated by a TIMEOUT clause, any changes made to the field being edited when the READ ends are discarded. However, changes made to other fields are saved.
All objects definitions are automatically cleared when the READ ends unless the SAVE key word is included. You can reissue READ without recreating the objects if you include SAVE with the previous READ.
Include the NOMOUSE key word to prevent objects from being selected with the mouse. You must use the keyboard to move from object to object. You can still use the mouse within fields to cut, copy, paste and position the cursor.
LOCK | NOLOCK
The LOCK and NOLOCK key words let you specify if a record containing fields specified in objects is automatically locked during a READ when the table is opened for shared use on a network.
If LOCK is included, record locks are attempted for every record used by the objects. If the locks are successfully placed, you can edit the records. SET REPROCESS determines how many times or for how long locking attempts are made. READ defaults to READ LOCK if LOCK or NOLOCK isn't included.
If NOLOCK is included, the records used by objects are not locked. Instead, all objects that use fields in the records are made read-only and the control cannot be selected and is displayed in the disabled colors.
If you issue READ NOLOCK and modify a memo field, the record is automatically locked.
COLOR color pair list
COLOR SCHEME expN4
The color of the current @ ... GET editing region can be specified by including the number of an existing color scheme in the COLOR SCHEME clause or a set of color pairs in the COLOR clause.
When an object is selected, it assumes the colors of the second color pair in the color pair list. All other colors in the color pair list are ignored. If you omit the first color pair you must include a comma for the color pair.
If you include a COLOR SCHEME clause, color pair 2 of the specified color scheme determines the color of the current @ ... GET editing region. By default, the color of the current @ ... GET editing region is determined by color pair 2 of color scheme 1, color pair 2 of the window the @ ... GET editing region is placed in or color pair 2 of the color clause specified in @ ... GET. The color of other objects (check boxes, popups, push buttons, etc.) isn't affected by this color clause.
A color scheme is a set of 10 predefined color pairs. The color pairs in a color scheme can be changed with SET COLOR OF SCHEME. In FoxPro for MS-DOS the color pairs in a color scheme can also be changed in the Color Picker.
A color pair is a set of two letters separated by a forward slash. The first color letter specifies the foreground color and the second letter specifies the background color.
For example, this color pair specifies a red foreground on a white background:
For a list of colors and their corresponding color letters, see the SET COLOR commands and the Color Table by Color Pair topic in this online help facility.
A color pair can also be specified with a set of 6 RGB (Red Green Blue) color values separated by commas. The first 3 color values specify the foreground color and the second 3 color values specify the background color. The color values can range from 0 through 255.
The R/W color pair in the example above can also be specified with this RGB color pair:
FoxPro lets you easily create event-driven interfaces (like the FoxPro interface) for your applications. This section suggests a method for creating an event-driven interface in FoxPro.
In previous versions of FoxPro, some sophisticated users utilized an event loop to handle menu choices and window selections when creating an event-driven interface. The event loop would constantly poll the system status and then take action based on which window was on top or which menu option the user chose.
DO WHILE is used to create the event loop (often a large loop). Event loops should be avoided for the following reasons:
Event loops are constantly being executed, making them intensive CPU users.
Event loops are complex and difficult to program.
Event loops are unfriendly in multi-program environments like DESQview, Windows and the Macintosh MultiFinder.
A Single READ with Multiple Windows
Event loop programming is rarely required in FoxPro. A single READ supporting multiple windows can be used to eliminate most event loops. A single READ with multiple windows provides versatility and flexibility without complex programming.
We suggest that you encompass all the windows that you intend to interact with. FoxPro can coordinate windows containing objects (@ ... GETs, check boxes, radio buttons, popups, and so on) with other windows not usually associated with a READ. By default, all interactive windows (Browse windows, desk accessories, memo editing windows and windows opened with MODIFY FILE, MODIFY REPORT) can participate in a READ.
Coordinating Windows with a Single READ
To programmatically coordinate windows containing @ ... GET objects with a single READ:
Create the windows that will contain the @ ... GET objects.
Activate one of the windows and issue the @ ... GETs that create the objects for the window.
Activate another window and issue the @ ... GETs that create the objects for that window.
Continue in this fashion for the remaining windows.
Screen set program code generated by GENSCRN provides a good example of this sequence.
The windows created and activated are now coordinated with a single READ. Each of the GET objects appears in its respective window, and the user can move between the @ ... GET objects in each of the windows. When the user moves from object to object with the keyboard, the objects are traversed in the order the @ ... GETs have been issued, regardless of which window they are in. A window is activated and becomes the current output window when the current object is in the window.
When the user presses Tab, Enter or Down Arrow when the cursor is positioned on the last object in a window, the cursor is positioned on the first @ ... GET object in the next window. When the user presses Shift+Tab or Up Arrow on the first object in a window, the cursor is positioned on the last @ ... GET object in the previous window. The user can also move between different @ ... GET objects in different windows by clicking on the objects.
Access to other windows during a single READ can be controlled with the READ MODAL clause. Including MODAL in READ prevents interaction with windows that are not encompassed in the READ's coordinated set of windows. When MODAL is included with READ, the user cannot close, zoom, minimize, or move windows not involved in the READ. Clicking on a window not involved in the READ sounds a beep if BELL is SET ON.
By default, all interactive windows (Browse windows, desk accessories and windows opened with MODIFY FILE, MODIFY REPORT, and so on) can participate in a READ.
You can explicitly indicate the windows that participate in the READ by specifying their names in the WITH clause. The READ command is automatically made MODAL if you include the WITH clause to specify other windows involved in the READ. The windows included in the WITH clause can include FoxPro system windows (Browse windows, desk accessories and text and memo editing windows).
ACTIVATE and DEACTIVATE
When a window involved in the READ is brought forward, the action taken can be controlled by the ACTIVATE and DEACTIVATE clauses. The user can bring a window forward by clicking on the window, by cycling to the window with Ctrl+F1 or by choosing a control or menu option that activates the window.
When a window containing objects is foremost and you attempt to bring another window forward, the DEACTIVATE clause is executed after the new window is brought forward.
The value returned by the DEACTIVATE clause determines whether the READ is terminated If the DEACTIVATE clause returns true (.T.), the READ is terminated. If the clause returns false (.F.), the READ isn't terminated.
When the DEACTIVATE clause is executed, WONTOP() returns the name of the new window brought forward and WLAST() returns the name of the window that was formerly frontmost. The window functions (WONTOP(), WOUTPUT() ...) return false (.F.) when you include the name of a window that doesn't exist.
If your DEACTIVATE clause lets the new window remain forward and the new window contains objects, the ACTIVATE clause is executed.
When a window is brought forward, you can return the window to its former position by issuing the following command in the DEACTIVATE clause:
ACTIVATE WINDOW (WLAST())
The function WREAD() facilitates manipulation of windows participating in a READ. WREAD() lets you determine if a specific window is participating in the current READ.
Coordinating Multiple READs / Foundation READs
The single READ with multiple windows section above recommends an approach to handling multiple windows with a single READ command. The single READ approach works for most applications.
However, a foundation READ may be necessary in some applications. A foundation READ is a READ without objects. A foundation READ is used to coordinate multiple READs into a single interactive session.
A foundation READ typically incorporates code in its VALID clause routine that activates and controls the child READs. Child READs are sometimes called nested READs.
A foundation READ normally has a VALID clause. The VALID clause is executed when an event occurs that would otherwise terminate the READ. Here are the events that terminate a foundation READ:
Any mouse click or keystroke that isn't a menu selection or doesn't execute an ON KEY LABEL. During a foundation READ, the FoxPro system menu is accessible.
Selecting an item from a menu or executing an ON KEY LABEL command doesn't terminate a foundation READ. If a menu is activated but a selection isn't made from the menu, the foundation READ isn't terminated.
A child READ is terminated. However, the foundation READ isn't terminated if a grandchild READ is terminated.
The value returned by the READ VALID clause determines whether or not the foundation READ is terminated. If the READ VALID clause returns true (.T.), the foundation READ is terminated; if it returns false (.F.), the foundation READ command remains active.
READKEY() facilitates the management of child READ commands. By specifying a numeric argument in READKEY(), you can determine how the last READ was terminated. For example, the value can indicate that the last READ was terminated by closing a window, by a CLEAR READ, by a READ VALID or DEACTIVATE clause returning a logical true (.T.).
Here are the values returned by READKEY(expN) with the corresponding reason the READ was terminated:
1 None of the following
2 CLEAR READ issued
3 Terminating control chosen
4 READ window closed
5 DEACTIVATE clause returned .T.
6 READ timed out
Included with FoxPro are three sample applications, INV.APP, EX1.APP and EX2.APP. These sample applications illustrate the features available with READs and how these features can be used to create an event-driven interface.
The applications are built from three projects, INV.PJX, EX1.PJX and EX2.PJX. The projects contain all the files (programs, screen sets, menus, tables, and so on) used by the applications. To examine the files included in a project, open the project with MODIFY PROJECT, or through the Open dialog.
INV: A Single READ with Multiple Windows
The sample application INV.APP demonstrates the use of a single READ with multiple windows. A user-defined window containing @ ... GET objects, two Browse windows and the CONTROL2 screen set control panel are coordinated with a single READ command.
EX1: A Foundation Read with Multiple Applications
EX1.APP, a more complex application than INV.APP, demonstrates coordination of four READs, each of which use the control panel built from the CONTROL3.SCX screen set. A foundation READ coordinates the four READs. EX1.APP has been designed so you can utilize any FoxPro desk accessories or windows (Help, Filer, Calculator, Calendar/Diary, editing windows, and so on) in conjunction with the application windows.
Applications are launched from the Application menu. You can switch from one application to another by clicking in the respective application window. Execution of the entire system can be terminated by choosing the Quit option in the File menu.
Before you attempt to write your own multi-READ event driven code, we recommend you carefully study EX1.APP and be certain you can answer the following questions about its operation. The answers are provided at the end of this section.
1. What would happen if the menu handling routine always immediately launched the requested application, regardless of the current READ level (returned by RDLEVEL())?
2. Why is it necessary to specify the IN EX1.MPR clause in the menu command on the Application menu?
3. Where is the code that handles the situation when an application window is closed manually, either through the window's Control menu (FoxPro for Windows) or by clicking on its close box (FoxPro for MS-DOS), or by choosing Close from the File menu?
4. What is the largest number of READs that are active at any one time while EX1.APP is executing?
5. What insures that the control panel vanishes when the last remaining application window is closed?
6. If you bring, say, the Calculator on top of an application window, is the application READ still active? The foundation READ?
7. When you are executing EX1.APP and neither an application window nor the control panel is visible, and you're using, say, the Filer, is any READ active?
8. When you're running in one application window and you click in another application window, how is control transferred from the first application to the new one? What event triggers the transfer?
If you can answer all these questions, you're ready to proceed to the next example.
EX2: A Foundation Read with Multiple Applications
This application is similar to EX1.APP, but replaces the single invoice editing screen with the INV.APP application that, besides editing the invoice file, includes the CONTROL2 control panel and two Browse windows coordinated as part of the READ.
Study EX2.APP carefully and you'll see that the changes required to handle this more complex situation are rather simple. If you can answer the eight questions about EX1.APP, you should have no difficulty with EX2.APP. And by now, you should have a general idea how to proceed in your own applications.
EX1 Quiz Answers
1. You would add one READ level each time you selected an application from the menu and, therefore, would get "Too many READs in effect" in short order. FoxPro supports a maximum of five READ levels.
2. Because the procedure MENUHIT is contained within EX1.MPR. EX1.MPR isn't a part of EX1.PRG; the IN EX1.MPR clause must be included to tell EX1.PRG where to look for the MENUHIT procedure.
3. It's found in the STOPREAD procedure which is evaluated each time an application window is deactivated. The window name is passed to STOPREAD. If the window isn't visible, (because it was closed either manually or by clicking on its close box) the control panel is displayed. STOPREAD returns .T. if the window is involved in the READ, otherwise .F. is returned (a FoxPro system window was closed).
4. There are at most three READs active: the foundation READ, one of the application READs, and a READ MODAL associated with either BROWSER.SPR or FINDER.SPR.
5. The procedure named EFFACE, which is called in the cleanup code for each application screen, ensures that when the last application window is closed the control panel is released.
EFFACE is called when either the Quit button is pressed or a READ window has been manually closed.
EFFACE looks through all the windows that are open, from back to front. If it finds any of the user application windows (which require the control panel) it simply exits. Otherwise, it concludes you're finished with the control panel and releases it.
6. The application READ is terminated because its DEACTIVATE clause returned .T., but the foundation READ remains active.
7. The first application's DEACTIVATE clause returns .T., thereby terminating that application's READ. Termination of the application's READ triggers the foundation READ's VALID clause routine.
8. This routine, called MYHANDLER, uses WONTOP() to return the name of the application window where the mouse was clicked, and the screen program (.SPR) for that window is executed.
For examples using READs, see the sections on @ ... GET, CLEAR READ and SHOW GETS.
Comment or report problem with topic