FILE:Fw0969.exe Coordinates Menus & Screens w/ Foundation READsLast reviewed: February 12, 1998Article ID: Q109430 |
2.50 2.50a 2.50b | 2.50 2.50a 2.50b
WINDOWS | MS-DOSkbprg kbappnote kbfasttip kbcode The information in this article applies to:
SUMMARYFw0969.exe is a file that contains the Application Note entitled "Coordinating Screens and Menus with Foundation READs" describing how to manage a menu system and access screen controls through a menu.
MORE INFORMATIONThe following file is available for download from the Microsoft Software Library: ~ Fw0969.exe For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:
ARTICLE-ID: Q119591 TITLE : How to Obtain Microsoft Support Files from Online Services THE TEXT OF FW0969
Microsoft(R) Technical Support Application Note (Text File) FW0969: COORDINATING MENUS AND SCREENS WITH FOUNDATION READS Revision Date: 12/93 No Disk IncludedThe following information applies to Microsoft FoxPro versions 2.5, 2.5a, and 2.5b for Windows and FoxPro versions 2.5, 2.5a, and 2.5b for MS-DOS.
| INFORMATION PROVIDED IN THIS DOCUMENT AND ANY SOFTWARE THAT MAY | | ACCOMPANY THIS DOCUMENT (collectively referred to as an Application | | Note) IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER | | EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED | | WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR | | PURPOSE. The user assumes the entire risk as to the accuracy and | | the use of this Application Note. This Application Note may be | | copied and distributed subject to the following conditions: 1) All | | text must be copied without modification and all pages must be | | included; 2) If software is included, all files on the disk(s) | | must be copied without modification (the MS-DOS(R) utility | | diskcopy is appropriate for this purpose); 3) All components of | | this Application Note must be distributed together; and 4) This | | Application Note may not be distributed for profit. | | | | Copyright (C) 1993 Microsoft Corporation. All Rights Reserved. | | Microsoft, FoxPro, and MS-DOS are registered trademarks and Windows | | is a trademark of Microsoft Corporation. | |---------------------------------------------------------------------| INTRODUCTION ============Many screens have associated menu systems that are called from the screen program. These menu systems usually contain:
MANAGING A MENU SYSTEM ======================Menus created in the Menu Builder automatically interact with the FoxPro menu system. If you create a menu and add it to the FoxPro menu system, you don't have to explicitly activate the menu with ACTIVATE MENU. The following sections give you more information about managing menus that you create.
ACCESSING MENUS DURING A READThe READ command activates controls in FoxPro screens. Whether or not your menus are accessible when a READ is active depends on the type of READ you issue. A modal READ is a READ that includes the MODAL keyword or a WITH <window title list> clause. When you issue a modal READ, your menu is disabled. After you issue a READ, access to your menu depends on the setting of SYSMENU, as discussed in the following section.
CONTROLLING MENUS WITH SET SYSMENUWith the SET SYSMENU command, you can disable your menu, selectively add and remove items from the menu, restore the default FoxPro menus, and control access to your menu during program execution. Here are some of the ways you can use SET SYSMENU:
SET SYSMENU ONYour menu bar is accessible during program execution when FoxPro waits for keyboard input, such as during BROWSE, a non-modal READ, or MODIFY MEMO. The menu bar is not displayed in FoxPro for MS-DOS, but you can display it and make it accessible by pressing the ALT or F10 key or by double-clicking the mouse button.
SET SYSMENU OFFYour menu bar is not accessible during program execution.
SET SYSMENU AUTOMATICYour menu bar is displayed at all times during program execution and is accessible during program execution when FoxPro waits for keyboard input.
SET SYSMENU TO DEFAULTThe default FoxPro menu system is restored to its default configuration. For more information about the SET SYSMENU command, see the FoxPro "Language Reference."
SAVING AND RESTORING MENUSPUSH MENU and POP MENU help you save and restore menus. Using these commands, you can push a menu onto a stack in memory and restore it later by popping it off the stack. Pushing a menu onto a stack saves its current state but does not remove it from the screen. While the menu is saved in memory, you can change the menu on the screen, or you can replace it with another menu. After changing or replacing the original menu, you can restore the original menu by using POP MENU. Menus are pushed onto and popped off the stack in a "last in, first out" order. The number of menus saved in memory is limited only by the amount of memory available. For more information about PUSH MENU and POP MENU, see the FoxPro "Language Reference." The ORGANIZER application demonstrates how menus are replaced and restored. When you choose a menu option in the ORGANIZER, a screen program runs. This program pushes the current menu into memory and then runs a menu program that creates a new menu to replace the original one. When the screen program ends, the original ORGANIZER menu is restored (popped) from memory. The following example shows the Convert.spr screen program commands that PUSH the ORGANIZER menu onto a stack in memory, replace the ORGANIZER menu with its own menu, and then restore the original ORGANIZER menu when the screen program ends.
PUSH MENU _MSYSMENU && Defined in the setup code for the screen. . . . DO convmenu.mpr && Defined in the READ WHEN code for the screen. . . . POP MENU _MSYSMENU && Defined in the cleanup code for the screen. CALLING SCREEN AND MENU PROGRAMSTo call a menu program, use the following syntax:
DO <menu name>.mprSimilarly, to call a screen program, use the following syntax:
DO <filename>.sprYou must include the .mpr or .spr extension, because different types of program or code files -- such as menus, screens, and queries -- can have the same names. The filename extensions make them unique.
ACCESSING SCREEN CONTROLS VIA A MENU ====================================If screen controls such as radio buttons are frequently used, you can help users by allowing access to these controls via menu options and keyboard shortcuts. For example, the CONVERT.SCX screen has a set of radio buttons, menu options, and keyboard shortcuts that you can use to select a measurement unit -- such as area, length, or mass. To define a menu option, you can often use the code that defines the behavior of the corresponding screen control. Simply copy the code used for the screen control into the code snippet for the menu option.
USING A FOUNDATION READ WITH MENUS AND SCREEN SETS ==================================================A foundation READ is a READ command with a VALID clause that you issue before issuing any @ ... GET commands. The foundation READ, also called a "GETless" READ, suspends program flow so that your application can wait for the user to make choices and initiate actions. The foundation READ keeps your application active until the VALID clause expression evaluates to true (.T.) or until a user- defined function returns true. A foundation READ serves two basic purposes:
BASIC MODEL -- FOUNDATION READ WITHOUT AN EVENT HANDLERThe basic model of the foundation READ keeps a menu active in an application created with the FoxPro Distribution Kit. If your application has only one screen active at a time, use the basic model. If you want a menu program to be the main file in your application, initialize a logical variable to false (.F.) in the menu's setup or cleanup code. For example, the following statement creates the logical variable M.ENDREAD and initializes it to false:
m.endread = .F.Then issue the foundation READ command in the menu's cleanup code. The following statement issues a READ command that remains active until the VALID clause (that is, M.ENDREAD) evaluates to true:
READ VALID m.endread && This is the foundation READ.You also need to provide a mechanism for altering the value of the memory variable when it's time for the application to terminate. In the procedure associated with the Quit option on your custom menu, include the following:
m.endread = .T. CLEAR READ ALLThe VALID clause on the foundation READ will be evaluated after the READ is cleared in the second statement. Since the previous line of code stored true to the logical variable that is evaluated in the VALID, the foundation READ terminates, and program flow continues until your application ends. If you want your user to be able to interact with multiple screen sets at the same time, you should use a foundation READ in conjunction with an event handler function. The next section describes how to do this.
ADVANCED MODEL -- FOUNDATION READ AND EVENT HANDLERThe advanced model of the foundation READ calls an event handler UDF instead of evaluating a variable flag to determine whether to terminate the READ. Code in the handler function can be used to manage subsequent READ levels by determining which screen set the user wants to activate based on choices the user has made. If the appropriate screen set is not active, the handler function clears the active READ and launches the desired screen set. A detailed example of a foundation READ with an event handler is provided in the "Sample Applications Using a Foundation READ" section later in this Application Note.
Creating a Foundation READ with an Event HandlerTo create a foundation READ that calls a handler function in the VALID clause, create a .PRG program and make it the main file of your application. For information about creating programs, see the "File Menu" chapter in the FoxPro "User's Guide." For information about the main program in an application, see the "Selecting a Main File" section in the "Project -- The Main Organizing Tool" chapter in the FoxPro "Developer's Guide." The main program contains these elements:
READ VALID myhandler( ) && This is the foundation READ.MYHANDLER( ) is a function in the main program that launches the appropriate screen set in response to user actions. To terminate the foundation READ
Why an Event Handler Is NecessaryA screen is a window with GET objects and an associated READ. In a generated screen set, all the screens have a single common READ. All the GET objects on the screens in the screen set can be active while this READ is active. If another screen set is run, another READ is issued, and it is nested within the original READ. The user cannot access any of the objects in the original READ until the nested READ has been terminated. Even though the GET objects in the original screen set are not active, the windows are still visible and can be brought to the front. To the user, it appears as though the objects and controls on the original screens are accessible. In addition, if you have very many screen sets in your application, you can easily exceed the FoxPro limit of five nested READ commands, generating an error. Using a handler function allows you to clear all READs except the foundation READ and the READ associated with the screen set that the user wants to access. The user can choose a screen set either by choosing a menu option or by clicking on a visible window in the screen set.
SAMPLE APPLICATIONS USING A FOUNDATION READFoxPro version 2.5 includes two sample applications that demonstrate how to use a foundation READ and manage subsequent READ levels: Ex1.app and Ex2.app. Both of these samples are installed by default in the GOODIES\FNDATION subdirectory. The file Ex2.app is the same as Ex1.app except that it also demonstrates coordinating a screen and a Browse window. This section of this Application Note traces the code that executes when users of Ex1.app interact with the application's interface.
Overview of Ex1.appEx1.app is an application that allows users to view, update, browse, and search through the customer, salesman, parts, and invoice files of a company. The user can open multiple screens by choosing menu options, and can switch between visible screens by clicking on them. Programs in Ex1.app Although there are other programs in the application, the following programs are important in a discussion of the foundation READ and the event handler:
CLEAR READ INLIST( ) LEN( ) RDLEVEL( ) READ CYCLE WCHILD( ) WONTOP( ) WREAD( ) WVISIBLE( )Information about each of these functions can be found in the FoxPro "Language Reference" or in the Help system.
What Happens in Ex1.appEX1.PRG is the main program in the application, so the menu and the foundation READ are invoked in this program. When you run the application:
If the user chooses Customers from the Application menu, for example, the following code is executed:
DO mhit IN Ex1.mpr WITH "Excust.spr"Because MHIT is a procedure in the cleanup and procedures area of the menu program, it is necessary to specify where the procedure is, IN Ex1.mpr. The string "Excust.spr" is passed as a parameter to MHIT.
MHIT with Only the Foundation READ Active Code Comments
PROCEDURE mhit The parameter "EXCUST.SPR" is stored to PARAMETER prog the variable PROG. IF RDLEVEL() > 1 Since the only READ active is the tobedone = prog foundation READ when MHIT is initially CLEAR READ invoked, RDLEVEL( ) is not greater than 1, and this code is not executed. ELSE Instead, Excust.spr is run. DO (prog)ENDIF
Excust.spr is a generated screen set containing two screens: CUST (titled "Customer Update") and CONTROL3 (not titled). CONTROL3 is included in each of the four main screen sets. User Action 2: Second Menu Choice If, without closing CUST (the Customer Update screen), the user then chooses Salesmen from the Application menu, the following actions occur:
PROCEDURE mhit The parameter "Exsman.spr" is stored to PARAMETER prog the variable PROG. IF RDLEVEL() > 1 RDLEVEL( ) returns 2 -- the foundation tobedone = prog READ and the READ for the EXCUST screen CLEAR READ set. "Exsman.spr" is stored to the variable TOBEDONE, and the READ for the EXCUST screen set is cleared. The windows for the EXCUST screen set are still visible even though the READ has been cleared. This is because the screens in Ex1.app are generated with the Clear Windows check box in the Generate Screen dialog not checked. ELSE DO (prog)ENDIF
PRIVATE m.temp, m.x IF dropdead DROPDEAD is initialized to .F., so this RETURN .T. condition isn't met and the command ENDIF isn't executed. IF LEN(tobedone) > 0 In MHIT, "Exsman.spr" was stored to the m.temp = tobedone public variable TOBEDONE so the length tobedone = "" of the variable is greater than 0. DO (m.temp) "Exsman.spr" is stored to a private RETURN .F. variable, the null string is stored to ENDIF the public variable TOBEDONE, and Exsman.spr is executed. .F. is returned so that the foundation READ does not terminate. . The additional code in the MYHANDLER( ) . function will be discussed in . conjunction with the actions that trigger it.When this code executes, SMAN is the active window and EXSMAN is the active READ. CUST is still visible. User Action 3: User Clicks on a Screen in Another READ If the user clicks on the CUST window, the following actions take place:
FUNCTION stopread The parameter "sman" is stored to the PARAMETER m.window variable M.WINDOW. IF NOT WVISIBLE(m.window) SMAN would not be visible if the user SHOW WINDOW control3 TOP had chosen Close from the File menu, quitting = .T. clicked the close box, or pressed ESC. ENDIF This code would make sure that the control panel remained visible and would store .T. to QUITTING so that the READ would be terminated. Since the user only clicked on another window, SMAN remains visible and these commands are not executed. RETURN quitting OR NOT WREAD() QUITTING is still false. WREAD( ) determines if WONTOP( ) is involved in the current READ level. Since the user clicked on CUST and the current READ is still the READ associated with EXSMAN, WREAD( ) evaluates to .F., and NOT WREAD( ) evaluates to .T. .F. OR .T. returns .T., so the EXSMAN READ terminates.
MYHANDLER Function in Ex1.prg
Code Comments PRIVATE m.temp, m.x IF dropdead RETURN .T.ENDIF
IF LEN(tobedone) > 0 Neither of these conditions is met, so m.temp = tobedone none of this code is executed this time. tobedone = "" DO (m.temp) RETURN .F.ENDIF
DO CASE Since the user clicked on CUST, CASE WONTOP("cust") WONTOP("cust") returns .T., EXCUST.SPR DO excust.spr is launched again, and the EXCUST screen CASE WONTOP("parts") set becomes the active READ. RDLEVEL( ) DO exparts.spr would return 2 again at this point.CASE WONTOP("inv") DO exinv.sprCASE WONTOP("sman") DO exsman.sprCASE WONTOP("control3") . . . ENDCASE
RETURN .F. The foundation READ is not terminated.Now CUST is the active window, and EXCUST is the active READ. User Action 4: User Clicks on the Control Panel If the user clicks on the control panel (the window CONTROL3), the following actions occur:
FUNCTION stopread The parameter "cust" is stored to the PARAMETER m.window variable M.WINDOW. IF NOT WVISIBLE(m.window) CUST remains visible and these SHOW WINDOW control3 TOP commands are not executed. quitting = .T.ENDIF RETURN quitting OR NOT WREAD() QUITTING is still false. Since the user clicked on CONTROL3, which is a window in the EXCUST screen set, WREAD( ) evaluates to .T., and NOT WREAD( ) evaluates to .F. .F. OR .F. returns .F., so the EXCUST READ does not terminate.Now CONTROL3 is the active window and EXCUST is the active READ. User Action 5: User Chooses Quit on the Control Panel If the user chooses Quit on the control panel, the following actions occur:
PROCEDURE efface PRIVATE m.x
m.x = WCHILD("",0) This procedure cycles through all the DO WHILE LEN(m.x) > 0 visible windows until it finds one of IF INLIST(m.x, "CUST", the application screen set windows: "PARTS", ; CUST, PARTS, INV, or SMAN. "INV","SMAN") RETURN Since SMAN is still visible, RETURN is ENDIF issued. CONTROL3 remains visible and is m.x = WCHILD("",1) the active window.ENDDO RELEASE WINDOW(WONTOP()) If none of the other screen set windows had been visible, the last line in this procedure would have released CONTROL3, too, so that none of the screen set windows would be visible.
MYHANDLER( ) Function in Ex1.prg
Code Comments PRIVATE m.temp, m.x IF dropdead RETURN .T.ENDIF Neither of these conditions is met, so none of this code is executed this time.IF LEN(tobedone) > 0 m.temp = tobedone tobedone = "" DO (m.temp) RETURN .F.ENDIF DO CASE CASE WONTOP("cust") DO excust.sprCASE WONTOP("parts") DO exparts.sprCASE WONTOP("inv") DO exinv.sprCASE WONTOP("sman") DO exsman.spr CASE WONTOP("control3") WONTOP("control3") returns .T. m.temp = "" This code cycles through the visible m.x = WCHILD("",0) windows, starting with the window at DO WHILE LEN(m.x) > 0 the bottom of the stack of child DO CASE windows, until it finds the window to CASE m.x = "CUST" launch the screen program for. m.temp = "Excust.spr" CASE m.x = "PARTS" m.temp ="Exparts.spr" CASE m.x = "INV" m.temp ="Exinv.spr" CASE m.x ="SMAN" Since SMAN is the child window that is m.temp ="Exsman.spr" found, "Exsman.spr" is stored to ENDCASE M.TEMP. m.x = WCHILD("",1) ENDDO IF LEN(m.temp) > 0 DO (m.temp) Exsman.spr is launched again. RDLEVEL() ENDIF goes back to 2, and SMAN becomes the ENDCASE active window.RETURN .F.
User Action 6: User Chooses to Terminate the Application The user is finished with the application and chooses Quit from the File menu, causing the following actions to occur:
PRIVATE m.temp, m.x
IF dropdead This time, because .T. has been stored RETURN .T. to DROPDEAD, the event handler in the ENDIF VALID clause of the foundation READ returns .T., causing the foundation READ to terminate.
Summary of Event Handler EventsThe event handler manages a variety of possible user actions:
|
Additional reference words: MBuilder FoxDos FoxWin 2.50 2.50a 2.50b appnote
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |