REPOST of DropDown Menu CODE ...
Posted in 1995
Tired of the typical Ring Menu ? By Jorge Torralba (407)323-4439 Quite often, the typical ring menu function inherent to Informix 4gl just isn't enough to produce the look and flexibility you want from a menu structure. Although they are practical and useful, they do have their limitations. How many times have you wanted to trigger other menu options from a ring menu, without having to write lines of accompanying code for every menu option? Now it is possible to do so by combining the two functions listed below into a single file. Simply create the file menutool.4gl containing the code listed below, compile it into an object file, link the object file to your code, and call the function 'dropmenu' as described in the example. Dropmenu displays a DropDown/PopUp menu at a specified screen coordinate. The menu choices and screen coordinates are based on a string and 2 small integers passed to the function dropmenu. A user may scroll through the menu choices using the up and down arrow keys, or press the first letter of a menu choice to make his or her selection. dropmenu("menu choices", down, across) dropmenu(char, smallint, smallint) "menu choices": A string or a string variable containing the menu choices which are to appear in the dropdown menu. These choices are separated by pipe symbols(|). ie. "Add|Modify|Delete" "down", "across": Screen coordinates for the dropmenu. down is the number of rows down from the top of the screen and across is the number of columns from the left of the screen. example: MAIN DEFINE menu_choice SMALLINT LET menu_choice = dropmenu("Add|Modify|Delete",3,5) DISPLAY menu_choice END MAIN In the above example, a dropmenu will appear containing the values Add, Modify and Delete. Each word within the string is represented by a small integer indicating its relative position within the string. Thus, 'Add' is 1, 'Modify' is 2 and 'Delete' is 3. If the user selects 'Modify' from the menu, 2 would be returned and assigned to the variable menu_choice. Pressing the 'interrupt' key returns a value of 0. Dropmenu has its limitations for now. Menu titles cannot be longer than 25 characters and no more than 20 choices can be specified per dropmenu. Should you pass invalid screen coordinates for your menu, dropmenu is smart enough to make the necessary adjustments. Try using dropmenu, once you see how easy it is to use, you will be popping up menus all over the place. 4GL CODE FUNCTION dropmenu(c_menu_string, s_dwn, s_acr) DEFINE s_pl,s_rws, s_dwn, s_acr, s_counter1, s_counter2, s_position, s_initdisplay, s_starting_title, s_start_from1, s_array_loc, s_previous_array_loc, s_howmany, s_title_len, s_max_title_len SMALLINT, c_any_key CHAR(01), c_find_this CHAR(80), c_menu_string CHAR(512), c_display_title ARRAY[20] OF CHAR(80) IF s_dwn < 3 OR s_acr < 3 THEN ERROR "Invalid DropMenu coordinates ... " SLEEP 2 RETURN "0" END IF IF c_menu_string IS NULL THEN RETURN "0" END IF # # get the menu titles from the string # FOR s_counter1 = 1 TO 20 CALL extractor(c_menu_string, s_counter1, "|") RETURNING c_display_title[s_counter1], s_howmany, s_position IF c_display_title[s_counter1] IS NULL AND s_counter1 = 1 THEN RETURN "0" END IF IF c_display_title[s_counter1] IS NULL THEN EXIT FOR END IF END FOR IF s_howmany = 0 THEN RETURN 0 END IF LET s_counter1 = 1 LET s_max_title_len = 0 LET s_start_from1 = 0 LET s_initdisplay = s_howmany # # establish the length of the longest title to display # FOR s_counter1 = 1 TO s_howmany LET s_title_len = length(c_display_title[s_counter1]) IF s_title_len > s_max_title_len THEN LET s_max_title_len = s_title_len END IF END FOR # # This section readjusts the pulldown window sizes if they are too big # IF (s_acr + s_max_title_len) > 78 THEN LET s_max_title_len = (78 s_acr) END IF IF (s_dwn + s_initdisplay) > 20 THEN LET s_initdisplay = (20 s_dwn) END IF IF s_howmany < s_initdisplay THEN LET s_initdisplay = s_howmany END IF LET c_find_this = NULL LET s_starting_title = 1 LET s_array_loc = 1 LET s_pl = s_initdisplay + 1 LET s_rws = s_initdisplay + 1 OPEN WINDOW drop_menu AT s_dwn, s_acr WITH s_rws ROWS, s_max_title_len COLUMNS ATTRIBUTE (BORDER, PROMPT LINE s_pl) FOR s_counter1 = 1 TO s_howmany DISPLAY c_display_title[s_counter1] AT s_counter1, 1 END FOR LET s_array_loc = 1 WHILE TRUE DISPLAY c_display_title[s_array_loc] AT s_array_loc,1 ATTRIBUTE(REVERSE) PROMPT "" FOR CHAR c_any_key ON KEY(DOWN) LET c_any_key = "1" ON KEY(UP) LET c_any_key = "3" END PROMPT LET c_any_key = UPSHIFT(c_any_key) IF fgl_lastkey() = fgl_keyval("RETURN") THEN CLOSE WINDOW drop_menu EXIT WHILE END IF IF INT_FLAG <> 0 THEN LET INT_FLAG = 0 CLOSE WINDOW drop_menu RETURN "0" END IF # # The '1' is the down key and the '3' is the up key # IF c_any_key = "1" OR c_any_key = "3" THEN IF c_any_key = "3" AND s_array_loc = 1 THEN DISPLAY c_display_title[s_array_loc] AT s_array_loc,1 LET s_array_loc = s_howmany CONTINUE WHILE END IF IF c_any_key = "3" AND s_array_loc >= 2 THEN DISPLAY c_display_title[s_array_loc] AT s_array_loc,1 LET s_array_loc = s_array_loc 1 CONTINUE WHILE END IF IF c_any_key = "1" AND s_array_loc = s_howmany THEN DISPLAY c_display_title[s_array_loc] AT s_array_loc,1 LET s_array_loc = 1 CONTINUE WHILE END IF IF c_any_key = "1" AND s_array_loc >= 1 THEN DISPLAY c_display_t