BASICally Better Menus (PC World October 1986 by Lawrence J. Magid) DOS is every user's first adversary. Over time a grudging fondness develops for this most essential for PC programs. But even hardened users will probably admit that there must be a better way to get at programs and access DOS functions. One solution is to buy a front-end menu program. Installing a front end conceals the uncommunicative DOS, replacing it with an informative system that makes formatting a disk, running a program, or navigating through a thicket of subdirectories a matter of picking a number off the screen. Although the market features a number of these programs, creating your own is surprisingly easy and gives you complete control over the look and the scope of the menu. With BASIC, you have flexible alternatives. The first enlists BASIC 3.0's SHELL command; the second, any version of BASIC combined with two batch files and a RAM disk. BASIC's functions give a menu system the ability to check for input errors, choose text colors, and branch to submenus that let you perform mundane but vital tasks such as formatting disk, copying files, adn backing up hard disks. BASIC can also effectively insulate the user from DOS, preventing inexperienced users from accidentally erasing files or those with suspect motives from gaining entry to restricted data or progarms. However, such a system cannot prevent a determined (and sophisticated) user from breaking and entering -- and wreaking havoc. One way to build a menu system with BASIC is to display menu options with the PRINT command, accept keyboard input via the reserved variable INKEY$, and execute the appropriate commercial program or DOS command from within the menu program with BASIC's SHELL command. The BASIC interpreter and the menu program remain in memory while the chosen menu option executes. Although SHELL can deal with batch files and programs that have .COM and .EXE file extensions, it cannot run another interpreted BASIC program or load a memory-resident utility such as SideKick or ProKey. With IBM's BASIC.COM, the short menu program SHELL.BAS takes up about 21K of memory. With the BASIC, BASICA, or GWBASIC supplied on disk with most PC compatibles, the memory overhead can jump to 80K. At the beginning of SHELL.BAS, the screen is cleared and set in 80-column text mode. On a monitor driven by an IBM Monochrome Display Adapter, the program prints "BASIC Shell Menu" underlined and skips two lines. If the monitor is hooked up to a graphics board, you will have to replace COLOR 1,0 on line 10 with COLOR 0,7 to display the title in inverse video. Lines 30 through 90 print the menu selections and the prompt "Enter choice: __" to the screen. Line 100 sets the variable CHOICE to 0 and begins a WHILE ...WEND loop that displays the date and time while resetting the value of CHOICE based on keyboard input. (The program considers alphabetic characters, punctuation, and other symbols to be 0.) As long as CHOICE is less than 1 or greater than 6 (the number of menu options), the loop continues. A valid menu selection ends the loop, and line 150 (PRINT CHOICE) displays it on screen. The ON ...GOSUB statement, based on the numeric value of CHOICE, branches execution to a section of the program. If CHOICE=1, the program jumps to line 1000; if CHOICE=2, the subroutine at line 2000 does the honors. The ON ...GOSUB construct also eliminates the need for a cascade of IF statements, but it does require that menu choices be numeric. The SHELL commands starting at lines 1000, 2000, and 3000 load the programs tied respectively to menu choices 1, 2, and 3. (The sequence of SHELL commands on each line is the same as if you'd entered the individual commands, such as CD\123, at the command line.) Each swatch of code representing a selection ends with RETURN, which sends execution back to line 170 and hence to line 10, which displays the menu. To check a disk (menu option 4) the program takes advantage of BASIC's ability to query the user for additional information. On line 4010, INPUT$(1) tells the program to proceed after accepting a single keystroke. This tactic eliminates the need for the user to press after typing the disk drive letter, which is then assigned to the DRIVE$ variable. The variable CHK$ on line 4020 is assigned to DOS's CHKDSK command, a space, the drive letter passed to DRIVE$, and a colon. SHELL CHK$ passes the entire command (for example, CHKDSK B:) to DOS. RETURN then sends control back to line 170 and pops up the menu again. The fifth menu item is processed in much the same manner, although SHELL.BAS asks for information about the files to be copied. Menu option 6 exits to DOS; typing EXIT at the DOS prompt returns the menu. The menu system described here is just a starting point -- those familiar with BASIC can dress up the menu and add options. But SHELL's modest talents do limit the menu's capabilities. As noted earlier, certain kinds of programs cannot be executed using SHELL. Furthermore, before a SHELL command executes, BASIC accesses COMMAND.COM in the root directory of the disk from which the system was started, which slows down operations. With DOS 3.0 and later versions, copying COMMAND.COM to a RAM disk (E: in this example) and issuing the DOS command: SET COMSPEC=E:\COMMAND.COM minimizes that delay. The second BASIC menu system eschews the SHELL command and instead relies largely on two batch files. MENU.BAS displays the menu, accepts user input, and creates NEXT.BAT on the fly in a RAM disk. NEXT.BAT is a small batch file that temporarily holds the latest menu selection and passes it to MENU.BAT, a master batch file that calls the appropriate routine. For acceptable performance, BASIC, MENU.BAS, and both batch files are kept in a RAM disk (drive E:). A 32K RAM disk is adequate on an IBM PC; compatible systems (which lack BASIC in ROM) must dedicate more memory to the task. With this batch/BASIC menu system, fewer restrictions apply and operations are noticeably faster than with the previous method. You can use any version of BASIC and invoke any program or command from the menu -- including memory-resident and interpreted BASIC programs. The master batch file, MENU.BAT, can be written with a text editor or any word processing program that creates ASCII files. MENU.BAT doesn't change unless you add or subtract entries from the menu. MENU.BAT begins with ECHO OFF, which suppresses the display of the batch file's commands. The next two liens clear the screen and designate C: as the default driver. GOTO CHOICE%1 branches execution to various labels linked to a value -- in other words, a menu selection -- that replaces the DOS variable %1. If you have only passing acquaintance with labels, branching, and replaceable parameters, keep in mind that a batch file is composed of statements that can be issued directly from the DOS command line. If a command is followed by parameters (such as a disk drive and file name) you can represent those parameters in the batch file with the "repoaceable parameters" %1, %2, %3, and so on. As the batch file executes, DOS replaces every occurrence of %1 with the first parameter, every %2 with the second parameter, and so on. For example, if you invoke MENU.BAT at the command line by typing MENU 7 4 , the 7 and the 4 replace %1 and %2, respectively, wherever they appear in MENU.BAT. If you only enter MENU, both %1 and %2 are null and no value is passed for either replaceable parameter. In this case, GOTO CHOICE%1 is simply read as GOTO CHOICE and execution jumps to the line following the label :CHOICE. That line -- E:BASIC E:MENU -- runs MENU.BAS, the menu program stored in the RAM disk. You'll notice that lines 9-149 in MENU.BAS and SHELL.BAS are almost identical. These lines set the display modes; display menu choices, the date, and the time; and assign menu choices to the CHOICE variable. Line 150 of MENU.BAS clears the variables PARAM$2 and PARAM$3 -- which are used only if menu option 4 or 5 is chosen -- of any previous assignments. Line 160 diverts program flow to the selected subroutines starting at lines 1000, 2000, 3000, 4000, 5000, and 6000. If you pick 1, 2, or 3 from the menu, MENU.BAS RETURNs operations to line 170. Line 170 OPENs (creates) the NEXT.BAT file in the RAM disk. Line 180 defines the contents of NEXT.BAT, namely MENU, followed by a space and the number picked from the menu. For example, if you choose menu option 2 to run WordStar, NEXT.BAT will contain the command MENU 2. Line 190 CLOSEs (saves) NEXT.BAT, and line 200 ends the BASIC program and returns control to the seventh line in MENU.BAT. The sole command on this line, E:NEXT, calls the newly created NEXT.BAT into play. Since WordStar was selected, NEXT.BAT issues the command MENU 2. MENU.BAT runs, and GOTO CHOICE%1 is now interpreted as GOTO CHOICE2. Execution branches to the line after the label :CHOICE2, changes to the WordStar subdirectory (\WS), runs WordStar, and, when WordStar is exited, changes back to the root directory. GOTO CHOICE branches execution back to the sixth line (E:BASIC E:MENU), running MENU.BAS and starting the process again. If you select option 4, "Check a disk," line 160 of MENU.BAS branches execution to line 4000. The menu program asks which drive to check, then passes the letter you type to DRIVE$ on line 4010. Line 4020 defines the variable PARAM$2 as the drive letter plus a colon. Execution RETURNs to line 170, recreating NEXT.BAT. Line 180 puts MENU 4, plus the contents of PARMA$2, into NEXT.BAT. If you type in A as the drive, NEXT.BAT's contents would be MENU 4 A:. At line 200, SYSTEM terminates the BASIC program, returning control to DOS. But because MENU.BAT is active, control actually returns to the line in MENU.BAT following E:BASIC E:MENU. MENU.BAT calls NEXT.BAT, which issues the command MENU 4 A:. Line 4 of MENU.BAT is now read as GOTO CHOICE4. On the line immediately below the label :CHOICE4 is CHKDSK %2. The variable parameter %2 is replaced by A:, and MENU.BAT sends out the command CHKDSK A:. PAUSE gives you a chance to read the results; pressing any key executes GOTO CHIOCE, and MENU.BAS is run once more. The processes marshalled by selectint item 5 from the menu are much the same, except that a third variable, PARAM$3, joins the crew. When you select item 6, MENU.BAS defines NEXT.BAT's contents as MENU 6. :CHOICE6 is found, the message "Type E:MENU to return to the menu" appears, echo is turned on, and the batch file ends. And when any batch file ends, DOS reasserts control. Of course, to display the menu again, you simply type E:MENU. To display this menu system every time a PC is turned on or restarted, add the following lines to the system's AUTOEXEC.BAT file: COPY \DOS\BASIC.COM E: COPY \MENU\MENU.* E: E:MENU The first two lines copy BASIC.COM, MENU.BAS, and MENU.BAT to the RAM disk drive (E:). E:MENU runs MENU.BAT. Throughout all this jumping to and from among MENU.BAS, MENU.BAT, and NEXT.BAT, keep in mind that although MENU.BAS displays the menu and modifies the contents of NEXT.BAT, MENU.BAT is the real workhorse. Also, when MENU.BAT calls another batch file, it loses control and cannot regain it unless called by another batch file. So don't use this menu system to run other batch files unless then end with the command E:MENU. It's easy to make menu selections with the PC's function keys instead of number keys. Just use BASIC's KEY statement at the beginning of the program to redefine the function keys for the appropriate menu options. For example, the statement KEY 1,"1" assigns the character 1 to F1. Refer to the KEY and KEY(n) statements in the BASIC manual for further programming ideas. There are other ways to enhance the menu. You merely have to tap your desires, creativity, and understanding of BASIC. With this approach to menu making, you have full access to all BASIC commands, including those that display the PC's extended ASCII character set. If you need characters from foreign alphabets, special symbols, or graphics characters, they're available. BASICA, of course, can provide even fancier bells and whistles, notably true graphics and sound, but you will have to set aside at least an additional 10K of memory. 1 'SHELL.BAS: Runs a menu system with the aid of PRINT, INKEY$, and 2 'SHELL commands. From PC World October 1986 by Lawrence J. Magid. 9 'Set up screen 10 KEY OFF:CLS:SCREEN 0,1,0,0:WIDTH 80:COLOR 1,0 19 'Print title line and menu choices 20 PRINT "BASIC Shell Menu":COLOR 7,0:PRINT:PRINT 30 PRINT "Lotus 1-2-3..........................1" 40 PRINT "WordStar.............................2" 50 PRINT "WordPerfect..........................3" 60 PRINT "Check a disk.........................4" 70 PRINT "Copy a file..........................5" 80 PRINT "Exit to DOS..........................6" 90 PRINT:LOCATE 14,24,0:PRINT "Enter choice: __"; 99 'Print date and time while waiting for input 100 CHOICE=0:WHILE CHOICE <1 OR CHOICE>6 110 CHOICE=VAL(INKEY$) 120 LOCATE 1,65:PRINT DATE$ 130 LOCATE 2,65:PRINT TIME$ 140 WEND 149 'Print and GOSUB to choice; then redisplay menu 150 LOCATE 14,37,1:PRINT CHOICE 160 ON CHOICE GOSUB 1000,2000,3000,4000,5000,6000 170 GOTO 10 999 'Choice 1: Lotus 1-2-3 1000 SHELL "CD\LOTUS":SHELL "123":SHELL "CD\" 1010 RETURN 1999 'Choice 2: WordStar 2000 SHELL "CD\WS":SHELL "WS":SHELL "CD\" 2010 RETURN 2999 'Choice 3: WordPerfect 3000 SHELL "CD\WP":SHELL "WP":SHELL "CD\" 3010 RETURN 3999 'Choice 4: Check a disk 4000 CLS:PRINT "Enter letter name of drive to check: "; 4010 DRIVE$=INPUT$(1):PRINT DRIVE$ 4020 CHK$="CHKDSK "+DRIVE$+":":SHELL CHK$ 4030 LOCATE 25,1:SHELL "PAUSE" 4040 RETURN 4999 'Choice 5: Copy a file 5000 CLS:INPUT "Enter source file name: ",SOURCE$ 5010 INPUT "Enter target drive and/or file name: ",TARGET$ 5020 COPY$="COPY "+SOURCE$+" "+TARGET$:SHELL COPY$ 5030 RETURN 5999 'Choice 6: Exit to DOS 6000 CLS:PRINT "Type EXIT to return to the menu.":PRINT 6010 SHELL 6020 RETURN - - - - - MENU.BAT: ECHO OFF CLS C: GOTO CHOICE%1 :CHOICE Display menu, write and call next.bat E:BASIC E:MENU E:NEXT :CHOICE 1 Lotus 1-2-3 CD\LOTUS 123 CD\ GOTO CHOICE :CHOICE2 WordStar CD\WS WS CD\ GOTO CHOICE :CHOICE3 WordPerfect CD\WP WP CD\ GOTO CHOICE :CHOICE4 Check a disk CHKDSK %2 PAUSE GOTO CHOICE :CHOICE5 Copy a file COPY %2 %3 GOTO CHOICE :CHOICE6 Exit to DOS ECHO Type E:MENU to return to the menu. EHCO ON - - - - - 1 'MENU.BAS: Displays the menu and modifies the contents of the 2 'temporary file, NEXT.BAT. From PC World October 1986 by 3 'Lawrence J. Magid. 9 'Set up screen 10 KEY OFF:CLS:SCREEN 0,1,0,0:WIDTH 80:COLOR 1,0 19 'Print title line and menu choices 20 PRINT "BASIC/Batch File Menu":COLOR 7,0:PRINT:PRINT 30 PRINT "Lotus 1-2-3..........................1" 40 PRINT "WordStar.............................2" 50 PRINT "WordPerfect..........................3" 60 PRINT "Check a disk.........................4" 70 PRINT "Copy a file..........................5" 80 PRINT "Exit to DOS..........................6" 90 PRINT:LOCATE 14,24,0:PRINT "Enter choice: __"; 99 'Print date and time while waiting for input 100 CHOICE=0:WHILE CHOICE <1 OR CHOICE>6 110 CHOICE=VAL(INKEY$) 120 LOCATE 1,65:PRINT DATE$ 130 LOCATE 2,65:PRINT TIME$ 140 WEND 149 'Print and GOSUB to choice; then redisplay menu 150 LOCATE 14,37,1:PRINT CHOICE:PARAM2$="":PARAM3$="" 160 ON CHOICE GOSUB 1000,2000,3000,4000,5000,6000 170 OPEN "E:NEXT.BAT" FOR OUTPUT AS #1 180 PRINT #1,"MENU";STR$(CHOICE);" ";PARAM2$;" ";PARAM3$ 190 CLOSE 200 SYSTEM 999 'Choice 1: Lotus 1-2-3 1000 RETURN 1999 'Choice 2: WordStar 2000 RETURN 2999 'Choice 3: WordPerfect 3000 RETURN 3999 'Choice 4: Check a disk 4000 CLS:PRINT "Enter letter name of drive to check: "; 4010 DRIVE$=INPUT$(1):PRINT DRIVE$ 4020 PARAM2$=DRIVE+":" 4030 RETURN 4999 'Choice 5: Copy a file 5000 CLS:INPUT "Enter source file name: ",SOURCE$ 5010 INPUT "Enter target drive and/or file name: ",TARGET$ 5020 PARAM2$=SOURCE$:PARAM3$=TARGET$ 5030 RETURN 5999 'Choice 6: Exit to DOS 6000 CLS 6010 RETURN