User Interfaces


A Versatile Menu Program for Turbo C

Roger T. Stevens


Dr. Roger T. Stevens is a member of the technical staff of the MITRE Corporation, Bedford, MA. He holds a B. A. degree in English from Union College, an M A in Mathematics from Boston University, an M. Eng. in Systems Engineering from Virginia Tech, and a PhD. in Electrical Engineering from California Western University. Dr. Stevens' books Graphics Programming in C, Fractal Programming in C, and Fractal Programming in Turbo Pascal are published by M & T Publishing, Inc., 501 Galveston Dr., Redwood City, CA 94063.

Introduction

Although there are menu programs available commercially and as shareware, most of them provide only the capability to display and select from a list of menu items, and do not permit interaction with the display. However, interaction with the display is often essential for efficient operation of a program. Look at the sample display of Figure 1. The two bottom lines are provided by the menu function. They give the user the choice of the actions: DISPLAY DATA, CHANGE DATA, ADD DATA, or QUIT. All you can do with most menu functions is to select one these actions. However, for the first two of these actions, we want to interact with the display, by selecting a name from the list for the action to be performed upon. The menu function described below will automatically switch mode after an action is selected. For the first two actions, the new mode can permit scanning the list of names with the up and down cursor arrows, highlighting each in turn with a contrasting color combination. The user then hits ESC to activate the selected function. The cursor is only permitted to go to the first letter of each name in the list.

Now look at the display of Figure 2. This is a new user generated display which provides detailed data on the person selected from the first display. Again the menu function is activated; this time it just displays two lines of instructions at the bottom of the screen. This is the display that you see if you chose the action CHANGE DATA, from the first display. Those places on the screen where you are allowed to change the data are actually shown on this display in a different color from the rest of the display and the cursor is restricted to only these positions. After you have modified the data in any way you desire, hitting ESC returns to the main program. The user can then arrange to read any data changes from the screen into his data files. Note that as long as you are within the menu function, you have the capability to move the cursor to any permissible location and change or rechange the data there. If at the first screen, you selected the DISPLAY DATA action, the bottom explanatory lines simply say Hit any key to continue... and no modification of display data is permitted.

For the ADD DATA action, no selection from the list of names is permitted; instead the display immediately switches to that of Figure 2, but with the data areas blank, ready to receive data on a new person.

All of the menu and display interaction is controlled by a versatile menu function which provides a number of different modes of operation through passed parameters. This menu function is described in the text that follows, and the code is in Listing 1. The listing also includes a number of useful functions needed for program operation.

What You Can Do with the Menu Program

The menu program begins by displaying two adjacent lines of instructions or menu items on the screen. You can select the location of the first of these lines by setting a parameter called first_line_loc, which is passed to the menu function. The first line normally consists of general instructions; the second line, which is the next line after the first line, can be a list of menu items from which the user makes a selection, or can be another set of general instructions, depending upon the mode of operation of the menu program.

You can specify the color combination for the menu items and the color combination which is used to highlight the currently selected menu item. The rest of the screen display remains as you generated it before calling the menu function. A menu item is selected by use of the cursor arrows; when selection is complete, this phase of the menu program is terminated by hitting the Enter key. For any number of menu items, beginning with the leftmost, you can specify an alternate (screen) mode of operation, which is entered after the Enter key is hit. You can specify each permissible cursor position for this alternate mode, and the cursor will only be allowed to go to these selected positions. (For example, if the down arrow is hit, the menu function will look at the current column and the next line and move the cursor there if it is a permissible position. If that position is not permissible, the function will look for the nearest permissible position on that line; if there is none, it will look at the next line, and so forth until a permissible location is found.) You can also specify two lines of text which will appear on the menu lines when the alternate mode is entered. You can specify whether this alternate mode of operation will be a select or an enter text type of operation. If selection is chosen, the text from the cursor to the next occurrence of two adjacent spaces is highlighted. Usually for this type of operation, the only allowable cursor positions are at the beginning of each selectable item on the display, so the entire selected item is highlighted.

If you specified the enter text type of operation, the user may enter alphanumeric data in any permissible cursor location. You may specify the color combination which this entered data will have. When data entry is complete, the same escape character specified above is used to terminate the screen mode of operation.

Determining Permissible Cursor Positions

The heart of the menu program is the capability to specify which positions on the screen the cursor is permitted to occupy. When in the selection mode, there should only be one permissile cursor position for each item to be selected. That is usually the first character of the item description. When changing or entering data on the screen, a file structure is usually determined, which specifies the names of the data items for each file entry and the length of each of these items. A display location and length is established for the display of each item, and the cursor is only allowed to go to the allocated space for each item. These areas of the screen can then be read to obtain the modified data. By prohibiting the cursor from going to other areas, it becomes impossible for the user to overwrite item definitions or to enter data that is too long to fit into the file.

The permissible cursor positions are controlled in the menu program by use of a bit map, which contains one bit for each character position on the screen. The bit map consists of a character array of 25 by l0 characters. The 25 is for the 25 screen lines; the 10 is for ten bytes of eight bits each to provide for the 80 character positions on a line.

If a particular bit is one, the cursor is permitted to go to that location; if it is a zero, the cursor is prohibited from going there. The bit map for a particular menu may be generated dynamically or it may be generated manually by determining what bits need to be set and where they are located in the array. Since this latter process can be rather cumbersome, a utility function, set_cursor, has been provided to do the job automatically. You temporarily insert set_cursor into your program, just after the display has been generated. You can now move the cursor around the display and insert an x or X at every position where the cursor is to be allowed. You should also replace any x or Xs that occur naturally in the display in locations prohibited to the cursor with some other character. Make sure not to hit the Enter key until you have inserted all of the required xs in the display.

When you hit Enter the program reads the entire screen and generates a file called MATRIX.C, which contains all of the ASCII data needed for initializing a cursor map array in your program. You can set up the bit map array by inserting the following line in your program:

char nnnnnnnn[25][10] =
where nnnnnnnn is the name of your bit map. If you are using the Turbo C total environment editor, place the cursor after the equals sign and type ^KR. When asked for the file name, type in MATRIX.C. The required data for the bit map will then be inserted into your program. You can then remove set_cursor from your listing and recompile the program. When you run the menu function, you will find that the cursor will only go to those positions which you marked with an x or X when you used set_cursor to construct the bit map.

Key Designations

Normal keys on the IBM PC keyboard generate the standard ASCII representation of the selected letter or number. Most special keys, such as the cursor arrow keys and the F1 through F10 function keys return two characters, first a hex 0 and then some number from 1 to 255. To put all key returns into a common format, the menu program automatically reads a second character from the keyboard when the first character is 0 and adds 256 to this second character to obtain a unique number that will not duplicate one of the normal ASCII codes. This key input is stored in a variable called key_id. Thus, when looking at the program listing, some of the comparisons of key_id with various numbers may appear unfamiliar. They can be identified by taking any chart of keyboard codes and adding 256 to the second character generated by a particular key. The menu program has the flexibility of specifying which key will be used to escape from the screen type of operation. This capability will be described in furthur detail below. You should note, however, that whatever character you select for escape cannot be entered as data on the screen.

Menu Options

The programmer has almost unlimited flexibility in defining how the menu program is to be used. The menu options are selected by parameters passed through the menu function.

The first parameter passed to the menu function is a string called values which defines the characteristics of the menu line. It begins with two digits which define the number of menu function items. Four digits then follow for each menu item. The first two represent the column of the display at which that menu item begins. The next two represent the number of characters in the menu item. These four digit entries must correspond to the actual spacing of the entries in the menu line string described below.

The next parameter, called menu_first_line, is a string showing the first line of instructions when the program is showing the menu type display. Following that is a string called menu_second_line, which is the second line of instructions for the menu type (the actual set of menu function items). Next are two strings called screen_first_line and screen_second_line, which are the first and second lines of instructions when the menu program switches to the second type of operation.

The next parameter, called menu_type, selects the mode of operation. There are four modes of operation for the menu function, which are controlled by this parameter. They are assigned by one of the numbers zero to three. The modes of operation are:

0 = When the menu program is called, it will start with the menu display. When it is in the screen display type of operation, all alphanumerics will be ignored.

1 = When the menu program is called, it will start with the menu display. When it is in the screen display type of operation, all alphanumerics will be displayed where typed.

2 = When the menu program is called, it will start with the screen display. When it is in the screen display type of operation, all alphanumerics will be ignored.

3 = When the menu program is called, it will start with the screen display. When it is in the screen display type of operation, all alphanumerics will be displayed where typed.

The next parameter, screen_color, is the screen color. This has no effect upon the display that has already been generated, but does determine what color combination will be used for alphanumerics typed on the screen and to restore the background for that part of the two instruction lines that is not used. Normally it should be the same color combination used in generating the original display screen. Table 1 shows the color combinations represented by each number. The next parameter, called menu_color, is the color combination used by the two lines of instructions produced by the menu. The next parameter, called highlight_color, is the color combination used to highlight the selected menu item.

The next parameter determines how many menu functions will switch to the screen type of operation when selected. Those functions which switch to the screen type of operation must be grouped at the beginning of the menu line, since the count in this variable begins with the leftmost function.

The next parameter, called escape_char, is the representation of the key which must be hit to escape from the screen type of operation. It is a number which is the ASCII value produced by a regular key or the value plus 256 if the keyboard output is a two character output beginning with 0. Thus any keyboard output may be selected. When this key is hit, it will immediately cause an exit from the screen mode of operation. The next parameter, called first_line_loc, determines the line on which the first of the two menu lines begins. It may be any screen line from 0 to 23. Normally the menu lines should be either at the top or bottom of the screen.

The final parameter is the address of the bit map, which determines which are the permissible positions of the cursor. The bit map has already been described above.

Supporting Functions

The menu function uses several supporting functions. These include clearscreen, which clears the screen by filling it with spaces of a designated color; gotoxy, which positions the cursor at a desired column and row; putcolorchar, which displays a character at the cursor location with a specified color combination and moves the cursor to the next column; color_printf, which acts like the standard C printf function except that it displays its data with a selected color combinations; and change_line_color, which changes the color of a line of characters from the current cursor position up until a double space is encountered. Listings of these functions are shown for completeness. Many of them may already be available in standard libraries, but they are not included with the current version of Turbo C. If you are adapting the menu funciton for a monochrome display, standard monochrome equivalent functions may be used in place of some of these functions.

Conclusions

The menu function provides a great deal of flexibility in manipulating data and making menu selections. About the only restriction is that all menu function item names must fit on one line. Colors, instructions, titles, order of mode, cursor settings, and whether or not alphanumerics are to be displayed are all under the control of the programmer through the manner in which he calls the menu function.