DOCUMENT:Q109430 28-FEB-2002 [foxpro] TITLE :FILE:Fw0969.exe Coordinates Menus & Screens w/ Foundation READs PRODUCT :Microsoft FoxPro PROD/VER::2.5,2.5a,2.5b OPER/SYS: KEYWORDS:kbcode kbfile kbDSupport ====================================================================== ------------------------------------------------------------------------------- The information in this article applies to: - Microsoft FoxPro for Windows, versions 2.5, 2.5a, 2.5b - Microsoft FoxPro for MS-DOS, versions 2.5, 2.5a, 2.5b ------------------------------------------------------------------------------- SUMMARY ======= Fw0969.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 INFORMATION ================ The following files are available for download from the Microsoft Download Center: Fw0969.exe (http://download.microsoft.com/download/fox26win/Doc/1/W9X/EN-US/fw0969.exe) For additional information about how to download Microsoft Support files, click the article number below to view the article in the Microsoft Knowledge Base: Q119591 How to Obtain Microsoft Support Files from Online Services Microsoft used the most current virus detection software available on the date of posting to scan this file for viruses. Once posted, the file is housed on secure servers that prevent any unauthorized changes to the file. 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 Included The 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: - Options with keyboard shortcuts for accessing screen controls. - Options that are not available in the screen because they are used infrequently. - Options that trigger irreversible actions (such as PACK). This Application Note covers managing a menu system and accessing screen controls via a menu. 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 READ ============================= The 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 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 SYSMENU ================================== With 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 ON -------------- Your 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 OFF --------------- Your menu bar is not accessible during program execution. SET SYSMENU AUTOMATIC --------------------- Your 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 DEFAULT ---------------------- The 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 MENUS ========================== PUSH 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 PROGRAMS ================================ To call a menu program, use the following syntax: DO .mpr Similarly, to call a screen program, use the following syntax: DO .spr You 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: - It keeps an application active even though no screen sets are active so that application users can choose options from your custom menu. - It can be used in conjunction with an event handler to create an event-driven application. An event-driven application allows the user to control which application events take place, instead of the application limiting and controlling the actions of the user. Depending on the complexity of your application, you might choose to use the basic model or the advanced model of the foundation READ. If your application has no more than one screen set active at a time, the basic model should be adequate. Otherwise, you'll probably want to use the advanced model. BASIC MODEL -- FOUNDATION READ WITHOUT AN EVENT HANDLER ======================================================= The 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 ALL The 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 HANDLER =================================================== The 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 Handler ------------------------------------------------ To 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: - Preliminary Code -- Sets up your environment and initializes global variables. - Launch Menu -- Runs the main menu program for the application. The user can launch screen sets by choosing menu options. - Foundation READ -- Issues the foundation READ with a handler function in the VALID clause. - Cleanup Code -- Restores the environment. - Procedures and Functions -- Includes user-defined functions to be called in your application. The following statement issues the foundation READ: 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 1. Issue the command CLEAR READ ALL in the procedure associated with the Quit option on your custom menu. 2. Have the function MYHANDLER( ) return true (.T.). Why an Event Handler Is Necessary --------------------------------- A 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 READ =========================================== FoxPro 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.app ------------------- Ex1.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: - Ex1.prg -- The main program. The first code to be executed, including the foundation READ, is in this program. - Ex1.mpr -- The menu program. - Excust.spr -- The customer update screen set. - Exparts.spr -- The parts update screen set. - Exinv.spr -- The invoice screen set. - Exsman.spr -- The salesman update screen set. Procedures and User-Defined Functions - MYHANDLER -- The event handler. MYHANDLER is located in Ex1.prg. - EFFACE -- Routine to decide whether to release the control panel. EFFACE is located in Ex1.prg. - STOPREAD -- Returns .T. to terminate the screen set READ or .F. to keep the screen set READ active. STOPREAD is called from the window DEACTIVATE clause in each of the screen sets, and is located in Ex1.prg. - MHIT -- Handles choices from the Application menu. MHIT is located in Ex1.mpr. Important FoxPro Commands and Functions Used in Handling Events 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.app ----------------------- EX1.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: 1. The menu program is launched, replacing the system menu with the custom menu: DO Ex1.mpr 2. The foundation READ is issued: READ VALID myhandler( ) Since MYHANDLER( ) initially returns .F., the READ continues. Issuing RDLEVEL( ) at this point would return 1. The menu bar is available to the user, and the Application menu on the custom menu bar contains the following options: - Customers -- Launches the EXCUST screen set. The window in this screen set for customer updates is CUST. - Salesmen -- Launches the EXSMAN screen set. The window in this screen set for salesmen updates is SMAN. - Parts -- Launches the EXPARTS screen set. The window in this screen set for part updates is PARTS. - Invoices -- Launches the EXINV screen set. The window in this screen set for customer updates is INV. User Action 1: Initial Menu Choice 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: 1. The following command is executed: DO mhit in Ex1.mpr WITH "Exsman.spr" MHIT with Two READs Active Code Comments --------------------------------------------------------------------- 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 2. When the EXCUST READ is cleared, the cleanup code for the screen set executes. The cleanup code in the CUST screen consists of the following lines: IF quitting RELEASE WINDOW cust DO efface ENDIF Since .T. is stored to the variable QUITTING only if the user chooses Quit on the control panel or manually closes the CUST window, no action is taken in the cleanup code. 3. RDLEVEL( ) drops back to 1. Program execution returns to the foundation READ, which causes the VALID clause, MYHANDLER( ), of the foundation READ to be evaluated. MYHANDLER Function in Ex1.prg Code Comments --------------------------------------------------------------------- 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: 1. SMAN ceases to be the active window, so the window DEACTIVATE clause on the READ is executed. The DEACTIVATE clause can be viewed as a window-level VALID clause; if the DEACTIVATE clause returns .T., the READ terminates. If the DEACTIVATE clause returns .F., the READ continues to be active. 2. The DEACTIVATE clause in the SMAN window invokes the STOPREAD function, located in Ex1.prg, with the parameter "sman". stopread("sman") STOPREAD Invoked When Changing Active READs Code Comments --------------------------------------------------------------------- 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. 3. When the nested READ terminates, RDLEVEL( ) drops back to 1. Program execution returns to the foundation READ, which causes the VALID clause, MYHANDLER( ), of the foundation READ to be evaluated again. 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.spr CASE WONTOP("sman") DO exsman.spr CASE 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: 1. CUST ceases to be the active window, so the window DEACTIVATE clause on the READ is executed. 2. The DEACTIVATE clause in the CUST window invokes the STOPREAD function with the parameter "cust". stopread("cust") STOPREAD Invoked When Changing Active Windows in the Same READ Code Comments --------------------------------------------------------------------- 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: 1. The following commands from the push button VALID clause in CONTROL3 are run: quitting = .T. CLEAR READ 2. Since the EXCUST READ is cleared, the cleanup code for the screen set is run. The cleanup code consists of the following: IF quitting RELEASE WINDOW cust DO efface ENDIF Because .T. has been stored to QUITTING, CUST is released so that it is no longer visible to the user and command execution goes to the procedure EFFACE, located in Ex1.prg. EFFACE to Determine Whether to Release the Control Panel Code Comments --------------------------------------------------------------------- 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. 3. Again, because the VALID clause associated with the Quit button in the control panel cleared the READ, the nested READ terminates and RDLEVEL( ) drops back to 1. Program execution returns to the foundation READ, which causes FoxPro to evaluate the VALID clause, MYHANDLER( ), of the foundation READ. 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.spr CASE WONTOP("parts") DO exparts.spr CASE WONTOP("inv") DO exinv.spr CASE 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: 1. The following lines of code are executed: dropdead = .T. CLEAR READ ALL 2. Because the READ is cleared, program execution returns to the foundation READ, which causes FoxPro to evaluate the VALID clause, MYHANDLER( ), of the foundation READ. MYHANDLER( ) Function in Ex1.prg Code Comments --------------------------------------------------------------------- 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. 3. The foundation READ terminates and code in Ex1.prg following the foundation READ runs, restoring environment settings and cleaning up after the application. Summary of Event Handler Events ------------------------------- The event handler manages a variety of possible user actions: - If the user chooses a new screen set from the Application menu, code in MHIT determines whether to immediately launch the screen set or to CLEAR the current READ and have MYHANDLER( ) launch the appropriate screen set. - If the user clicks on a different window, code in the previously active window's DEACTIVATE clause invokes STOPREAD( ) to determine whether the current READ should be terminated so that another can be activated or whether the current READ should remain active. - If the user closes a window by pressing ESC, by choosing Close from the File menu, or by clicking on the close box, the DEACTIVATE clause and the STOPREAD( ) function allow the READ to be cleared as if the user had chosen Quit in the control panel. - When the user closes a window, code in the EFFACE procedure, called in the screen set's cleanup code, determines whether the control panel should also be closed. - If the user closes a window, code in the MYHANDLER( ) function determines what screen set should be the active READ, if any. - If the user chooses Quit from the File menu, MYHANDLER( ) returns .T. to terminate the foundation READ. Coding an event handler takes some effort, but an event handler like the one in Ex1.app enables you to create an intuitive and easy-to-use interface. Additional query words: MBuilder FoxDos FoxWin 2.50 2.50a 2.50b appnote ====================================================================== Keywords : kbcode kbfile kbDSupport Technology : kbAudDeveloper kbFoxproSearch kbZNotKeyword3 kbFoxPro250DOS kbFoxPro250aDOS kbFoxPro250bDOS kbFoxPro250 kbFoxPro250a kbFoxPro250b Version : :2.5,2.5a,2.5b Issue type : kbinfo ============================================================================= THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY. Copyright Microsoft Corporation 2002.