home *** CD-ROM | disk | FTP | other *** search
/ HomeWare 14 / HOMEWARE14.bin / prog / ks94an.arj / KMENU.HDR < prev    next >
Text File  |  1994-04-24  |  26KB  |  579 lines

  1. /******************************************************************************
  2.                  The Klipper Library, for CA-Clipper 5.x
  3.         Copyright (c), 1994, Wallace Information Systems Engineering
  4.  
  5. FUNCTION:
  6.  
  7. _KMenu(__level,__prefuncarg,__postfuncarg,__scrnarea) --> NIL
  8.  
  9. PARAMETERS:
  10.  
  11. __Level       : Menu Level to display
  12. __PreFuncArg  : Name of Pre-menu Function (string)
  13. __PostFuncArg : Name of Post-menu Function (string)
  14. __ScrnArea    : string containing coords of screen area to save
  15.  
  16. SHORT:
  17.  
  18. A data driven general purpose menuing subsystem.
  19.  
  20. DESCRIPTION:
  21.  
  22. OVERVIEW
  23.  
  24. The menu system is completely self contained, data driven, and can be used
  25. with little or no modification to your programming style.  In short, the Menu
  26. Sub-System completely takes over the responsibility of screen management and
  27. menu navigation and passes control to functions that are specified in the
  28. menu definition file.  When menu options are selected by the user, the
  29. function coresponding to that menu item is called. The programmer need only
  30. ensure that these functions are indeed present in the executable, however, it
  31. is not necessary.  Any function specified in the menu definition file that is
  32. not present in the run-time environment is simply ignored.  This allows the
  33. programmer to completely prototype an entire system's menu structure at once,
  34. and then develop the supporting functions later.
  35.  
  36. Menu Definition Files
  37.  
  38. To initially create the menu definition file, simply call the _kmenu()
  39. function either with or without arguments.  The _kmenu() function itself
  40. checks to see if the menu definition file exists, in the location specified
  41. (if specified) or in the current directory (if not specified).  If the file
  42. does not exist, an empty menu definition file is created accordingly.
  43.  
  44. This will result in an UNDEFINED MENU LEVEL error message which can be
  45. ignored.  The menu definition file is now available for modification.  Use
  46. dBASE, the Clipper DBU utility, or KEDIT to fill in the table with the
  47. desired menu information.
  48.  
  49. The default name of the menu definition file is MENUDEF.DAT, however, this
  50. may be changed by any application that uses the menu system by specifiying
  51. the name to use in a variable called _KMENUNAME.  The menu defintion file
  52. uses an index, the Table Information File (".TIF") to order itself.  The
  53. default name for this file is MENUDEF.TIF, and may also be changed by the
  54. application by including the name in a variable called _KMENUIDX.
  55. Location of the Menu Definition Files
  56.  
  57. The location of the menu definition file and it's index need not be the
  58. current directory (the directory in which the program is being run).  The
  59. default location of the menu definition file, and index file, is the current
  60. working directory (application directory), unless otherwise specified by
  61. including a PATH in the _KMENUNAME and _KMENUIDX variables.
  62.  
  63. Example 1: To use the default menu definition file and index names in the
  64. current working directory, do nothing.  The defaults will apply:
  65.  
  66. FUNCTION MAIN()
  67.  
  68. _kmenu(0)
  69.  
  70. RETURN(NIL)
  71.  
  72. In this example, the menu definition file will be named MENUDEF,DAT, the
  73. index file will be MENUDEF.TIF, and both will be in the current working
  74. directory.
  75.  
  76. Example 2: To use a different name and location for each of the files:
  77.  
  78. FUNCTION MAIN()
  79.  
  80. MEMVAR _KMENUNAME
  81. MEMVAR _KMENUIDX
  82.  
  83. PUBLIC _KMENUNAME := '\SYSTEM\BUDGET.MNU'
  84. PUBLIC _KMENUIDX  := '\SYSTEM\BUDGET.IDX'
  85.  
  86. _kmenu(0)
  87.  
  88. RETURN(NIL)
  89.  
  90. In this example, the application and all of it's data files may be kept and
  91. run in one directory, while the menu definition file and index can be renamed
  92. to BUDGET.MNU and BUDGET.IDX, respectively, and located in a directory called
  93. "\SYSTEM".  For advanced applications being run in a Novell Network
  94. environment, the users of the application can have login scripts which
  95. establish a READ ONLY attribute to the \SYSTEM directory.
  96. MAP M:=FS1/VOL1:\SYSTEM\
  97.  
  98. The application programmer can then refer to the menu definition file
  99. location as:
  100.  
  101. PUBLIC _KMENUNAME := "M:BUDGET.MNU"
  102. PUBLIC _KMENUIDX  := "M:BUDGET.IDX"
  103.  
  104. This offers two advantages.  First, it ensures that no user can inadvertently
  105. or intentionally alter the menu definition files, and secondly, it allows the
  106. programmer to employ the network operating system itself as a security
  107. measure: allowing only users who have properly mapped drive specifications to
  108. access the program.
  109.  
  110. Menu Definition and Execution Procedure
  111.  
  112. Menus are created in LEVELS.  Each menu is comprised of a group of items that
  113. have a common LEVEL.  Typically, LEVEL 0 or LEVEL 1 is the MAIN MENU and
  114. calls all other menu levels and supporting functions.  One menu level may
  115. call another menu level resulting in a multiple layered menu scheme.  To call
  116. another menu level, _kmenu() simply makes a recursive call to itself:
  117.  
  118. _KMenu(6)
  119.  
  120. This would load menu level 6 over the current menu.  Menu level 6 may have
  121. several items that call functions, or may have items that make other calls to
  122. other menu levels.  Menu Level 1 may have an option which calls Menu Level 6
  123. which may in turn have a menu item that calls Menu Level 12 and so on.  No
  124. extra programming is required to accomplish this as each menu saves the state
  125. of the menu system before calling another menu level, and restores that state
  126. when the called menu is exited.
  127.  
  128. TECHNICAL DETAILS
  129.  
  130. Calling Convention and Parameter Options
  131.  
  132. The behavior of the Menu Sub-System can be modified in part by the
  133. developer's application.  There are a number of variables that the system
  134. looks for that can contain information that alters the way the program
  135. performs.
  136.  
  137. Parameters:
  138.  
  139. The function call to _kmenu() can include four parameters, one of which is
  140. mandatory, the other three optional.  The actual function syntax is:
  141.  
  142. _kmenu( nLevel, cPreFunc, cPostFunc, cScrArea )
  143.  
  144. nLevel: (REQUIRED)  This parameter defines which menu is to be presented.
  145.  
  146. cPreFunc:  This function is very similar to the PRE_FUNC for menu items.  The
  147. difference is that this function is called just BEFORE each MENU, instead of
  148. before each menu item.  If this parameter is specified, it is evaluated to
  149. determine if it is a valid function call (i.e., is defined in the source code
  150. and is in scope), and if it is, it is called.  The return value from this
  151. function is always ignored.  After the function is executed, the menu is
  152. displayed and the user is able to make menu selections.
  153.  
  154. cPostFunc:  This function works identically to the cPreFunc function, but it
  155. is evaluated and (if applicable) called AFTER the user has made a menu
  156. selection, and BEFORE the menu calls the MENU_FUNC function.
  157.  
  158. Variables:
  159.  
  160. The operational characteristics of the menu can also be modified by use of
  161. certain variables which, if present and in scope at runtime, control certain
  162. features.
  163.  
  164. _kMenuName: By default, the name of the menu definition file is MENUDEF.DAT.
  165. The application that uses the Menu Sub-System can change this to any other
  166. file name by specifying it in a PUBLIC or PRIVATE character variable:
  167.  
  168. _KmenuName := 'DATAMENU.DBF'
  169.  
  170. The Menu Sub-System will then look for a file called "DATAMENU.DBF' from
  171. which to build menus.  If the variable is not declared or not in scope when
  172. the _kmenu() function is called, or if it is, but is not a character type,
  173. the default menu file name of MENUDEF.DAT is used.
  174.  
  175. _kMenuIdx:  The Menu Sub-System menu Table Information File (TIF) contains
  176. information that logically orders the menu definition file.  The default name
  177. for this file is MENUDEF.TIF.  It can be changed in the same manner as menu
  178. definition file, but specifying the file name in a PUBLIC or PRIVATE
  179. character variable:
  180.  
  181. _KMenuIdx := 'DATAMENU.TIF'
  182.  
  183. _kMenuLockKey:  The default key for the keyboard lock is ALT-F10.  This key
  184. can be reassigned to any valid key combination by specifying it's INKEY()
  185. value in a PUBLIC or PRIVATE numeric variable:
  186.  
  187. _KMenuLockKey := K_CTRL_F5
  188.  
  189. In this example, be sure to include:
  190.  
  191. #include "INKEY.CH"
  192.  
  193. _kGlobalFunc: A function can be defined that is called once before each menu
  194. is built and displayed.  This function is called BEFORE the menu is drawn,
  195. and BEFORE a menu selection is made.  It differs from the PRE_FUNC function
  196. (discussed later) in that the PRE_FUNC function is called after the menu
  197. selection has been made and before the MENU_FUNC function is executed, while
  198. the GLOBAL FUNCTION is called only once at the beginning of each menu.  To
  199. define this global function, you need only define a PUBLIC or PRIVATE
  200. character variable that will be in scope when the menu system is initialized,
  201. that contains the name of the function to call:
  202.  
  203. _kGlobalFunc := 'function_name()'
  204.  
  205. FILE STRUCTURE
  206.  
  207. This is the structure of the data file that drives the menu system:
  208.  
  209.     LEVEL,      C,  3
  210.     ORDER,      C,  2
  211.     MENU_TEXT,  C, 75
  212.     MENU_FUNC,  C, 75
  213.     PRE_FUNC,   C, 75
  214.     POST_FUNC,  C, 75
  215.     MENU_HELP,  C, 40
  216.     FUNC_DESC,  M
  217.     INT_MENU,   L
  218.     SECURITY,   N,  1
  219.  
  220.  
  221. The first three fields, LEVEL, ORDER, and MENU_TEXT work together and need to
  222. be discussed first.
  223.  
  224. LEVEL: A complete menu is a group of items.  All items that pertain to a
  225. particular menu are grouped together by their Menu Level.  Menu levels need
  226. not be contiguous, you can have levels 1, 3, 5, 9, or 1, 2, 3, 4.  Any
  227. missing Levels are simply ignored.  The Menu Level does nothing but group
  228. menu items together.  This will be emphasized and made clear later when
  229. discussing, Menu_Func.
  230.  
  231. ORDER: Inside each Level, the menu options are ordered by their menu option
  232. order.  The menu option order that is placed in this field is concatenated
  233. with the text in the menu text field, and all together they comprise the
  234. complete menu.  NOTE:  ALL menus must have ONE item, ORDER=0, which denotes
  235. that the text contained in MENU_TEXT is to be used as the menu header, and is
  236. not itself a menu item.
  237.  
  238. MENU_TEXT: The Menu Text is the text that is displayed as a menu option in
  239. each menu item.
  240.  
  241. Summary of LEVEL-ORDER-MENU_TEXT
  242.  
  243. Each menu is comprised of a group of menu items that have the same menu
  244. level.  Inside each menu level, the items are ordered according to their menu
  245. order.  The menu order (logical order, not the ORDER field) is added as a
  246. string to the menu text to comprise a menu item and the whole group becomes a
  247. complete menu.
  248.  
  249. For example, the following MENUDEF.DAT entries:
  250.  
  251.     ORDER = 1,  LEVEL = 0, MENU_TEXT = "MAIN MENU"
  252.     ORDER = 1,  LEVEL = 1, MENU_TEXT = "Menu Option One"
  253.     ORDER = 1,  LEVEL = 2, MENU_TEXT = "Menu Option Two"
  254.     ORDER = 1,  LEVEL = 3, MENU_TEXT = "Menu Option Three"
  255.  
  256. will produce the following menu:
  257.  
  258.     ┌───────────────────────────┐
  259.     │        MAIN MENU          │░
  260.     ├───────────────────────────┤░
  261.     │  1 - Menu Option One      │░
  262.     │  2 - Menu Option Two      │░
  263.     │  3 - Menu Option Three    │░
  264.     ├───────────────────────────┤░
  265.     │ Enter      Esc = Previous │░
  266.     └───────────────────────────┘░
  267.       ░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  268.  
  269.  
  270. The length of the longest MENU_TEXT field (as opposed to the length of the
  271. menu header) determines the width of the menu.  In this case, "Menu Option
  272. Three" is the longest and the entire menu was dimensioned to accommodate it.
  273. The complete menu is drawn, including the constant and predefined keys of
  274. Enter to select a menu item and ESC to exit the menu. Also drawn is the
  275. shadow alongside the menu, giving an appearance of depth.  The shadow in this
  276. example is just a graphic character, however, in your application, it will be
  277. whatever text or graphics lay below the menu in the shadowed area.  The
  278. shadow is always drawn in low- white on black giving the impression of a true
  279. shadow.
  280.  
  281. The menu sub-system takes care of screen management while it is running.  It
  282. saves the screen inside which the menu will reside BEFORE it is drawn.  When
  283. the menu is exited by pressing ESC, the original screen that laid under the
  284. menu is redisplayed.
  285.  
  286. The next three fields, MENU_FUNC, PRE_FUNC, and POST_FUNC work together to
  287. call the functions that are defined for each menu item.  They are discussed
  288. next.
  289.  
  290. MENU_FUNC:  This field contains the name of the function that is to be called
  291. when this menu item is picked.  It should be specified with the parenthesis
  292. and any necessary arguments:
  293.  
  294. Option_One()
  295. Option_Two(cUser_Name)
  296. Option_Three('James Powell')
  297.  
  298. The menu system can be completely developed before any of the supporting
  299. functions are written.  At runtime, if the requested function is undefined or
  300. unspecified, nothing happens when you execute that menu item.  In the above
  301. function call examples, if Option_Two() is undefined at runtime, then nothing
  302. will happen when that menu item is executed.  If Option_Three() is defined,
  303. then Option_Three() is executed, receives 'James Powell' as a parameter and
  304. proceeds.  When the function is complete and returns, control returns to the
  305. menu system which redraws the menu and waits for another selection.
  306.  
  307. PRE_FUNC: This is a function call exactly like the MENU_FUNC function call.
  308. If specified, it is checked and called in a similar manner to MENU_FUNC.  If
  309. not specified, then like MENU_FUNC, nothing is called.
  310.  
  311.  
  312. The purpose of this function is to allow you to call another function
  313. immediately before calling the function in MENU_FUNC. This allows you to do
  314. things like check statuses, security levels, or do anything else that you
  315. want before actually performing the MENU_FUNC function.  For Example, if
  316. PRE_FUNC = 'PreCallFunc()', and MENU_TEXT = 'MenuOptionFunc()', then when you
  317. execute this menu item, a call is made to PreCallFunc(), which executes and
  318. returns and THEN MenuOptionFunc() is called.
  319.  
  320. The PRE_FUNC function's return value is significant.  Not only does the
  321. PRE_FUNC function allow you to take care of preliminary details before
  322. calling the MENU_FUNC function, it's return value can control whether or not
  323. the MENU_FUNC function is even executed.  The PRE_FUNC function can return
  324. any value at all, but the only value that is significant is a logical value.
  325. If the PRE_FUNC function returns FALSE, the MENU_FUNC function is NOT
  326. executed  if TRUE the MENU_FUNC function IS executed.  Any other type return
  327. value is ignored.
  328.  
  329. POST_FUNC:  The POST_FUNC field is similar to the PRE_FUNC and MENU_FUNC in
  330. that it also contains a function call that is to be executed immediately
  331. AFTER the MENU_FUNC function call.  If it is not specified, or if specified
  332. but the requested function is undefined in the source code, then no call is
  333. made.  The return value from the POST_FUNC, if any, is ignored.
  334.  
  335. The remaining fields, MENU_HELP, FUNC_DESC, INT_MENU, and SECURITY provide
  336. various functionality which is discussed next.
  337.  
  338. MENU_HELP: Data entered in this field is used as a "hook" into the On-Line
  339. Help Sub-System.  The Menu Sub-System and the On-Line Help Sub-System are
  340. designed to cooperate with each other.  A brief note is in order though.  The
  341. On-Line Help Sub- System uses the contents of a variable in your source code
  342. called "Help_Label" to derive the help text from the help database.  You use
  343. the On-Line Help by leaving a "trail of Help_Labels" in your source code.
  344. The Help_Label variable from whichever procedure is active when the user
  345. presses F1 is used as the help key.
  346.  
  347. But when the Menu Sub-System is active, and the user's screen is displaying a
  348. menu, none of your source code is active! This is because the menu system
  349. takes care of all screen activity related to the front end menu system and
  350. only branches into your source code when a menu item is executed that calls
  351. one of your MENU_FUNC functions.  For that reason, you have no opportunity to
  352. specify the HELP_LABEL that should be used while the menu is active.
  353.  
  354. You can use the MENU_HELP field to add text to be used for the Help_Label
  355. variable.  The Menu Sub-System takes this field's contents and declares a
  356. LOCAL HELP_LABEL that contains your MENU_HELP text.  Thus, you can continue
  357. to use the On-Line Help sub-system to provide context sensitive help even for
  358. the menus.
  359.  
  360. FUNC_DESC:  This field is a memo field and does not affect the Menu
  361. Sub-System in any way.  It is an area for you to record free-form text notes
  362. about the menu item, and a description of the function that it calls.  It is
  363. used largely for documentation purposes.
  364.  
  365. INT_MENU: Creating multiple-level menus is as simple as making your MENU_FUNC
  366. function make a recursive call to the Menu Sub-System itself.  For example,
  367. if you started your program with "_kmenu(1)", thus kicking off the menu
  368. system, you can easily make a menu item which has a MENU_FUNC function that
  369. calls "_kmenu(2)".  By doing this, menu level 2 is loaded on top of menu
  370. level 1, and you then have a multiple-level stacked menu!
  371.  
  372. The Menu Sub-System recognizes when a menu item is defined to make a
  373. recursive call to itself, and adds a caveat "?" to the right side of the menu
  374. item to indicate to the user that this menu item leads to another menu.
  375.  
  376. As you define your menus, you will eventually have to branch out into your
  377. own source code in order to accomplish anything useful.  Often, your
  378. MENU_FUNC call may branch to another menu that you have specifically encoded
  379. into your source code.  This might be any sort of menu with any appearance.
  380. But, if you branch from a menu in the Menu Sub-System to a menu in your
  381. source code, the Menu Sub-System has no way of knowing what is coming next in
  382. your source, so it cannot automatically add the menu indicator caveat to the
  383. menu item.  You must tell it that another menu of your own design follows.
  384. You may want to add the right-hand side caveat to indicate that another menu
  385. follows. This Logical field adds that caveat if TRUE.
  386.  
  387. SECURITY: The Menu Sub-System, when running, looks for a numeric variable
  388. called SYS_SEC in scope in the environment.  If you define a numeric variable
  389. called SYS_SEC in your program BEFORE making your first call to the Menu
  390. Sub-System, the Menu Sub-System will use this variable as a security level
  391. that determines whether menu items appear on a particular menu or not.
  392.  
  393. For instance, if your variable SYS_SEC=5, and SECURITY=9, then the user does
  394. not have sufficient access to even have this item on their menu, and it will
  395. not appear there.  Any menu items skipped for lack of security will not
  396. affect the numbering of the menu items.  One user may have menu options 1
  397. through 5, and another user who does not have access to menu option 3 will
  398. have menu options 1 - 4, with the unavailable menu option not being
  399. displayed.
  400.  
  401. Example:  If user RONW has a SYS_SEC of 9, and user BENC has a SYS_SEC of 5
  402. and they both run the following menu:
  403.  
  404.     ORDER  LEVEL  TEXT                   SECURITY
  405.     ----------------------------------------------
  406.     1      0    EDIT DATA MENU           0
  407.     1      1    EDIT FINANCIAL DATA      0
  408.     1      2    DELETE FINANCIAL DATA    6
  409.     1      3    REPORT FINANCIAL DATA    0
  410.     1      4    IMPORT FINANCIAL DATA    0
  411.  
  412. here are the two menus that they will see:
  413.  
  414.              USER: RONW                          USER: BENC
  415.     ┌───────────────────────────┐     ┌───────────────────────────┐
  416.     │      EDIT DATA MENU       │░    │      EDIT DATA MENU       │░
  417.     ├───────────────────────────┤░    ├───────────────────────────┤░
  418.     │ 1 - EDIT FINANCIAL DATA   │░    │ 1 - EDIT FINANCIAL DATA   │░
  419.     │ 2 - DELETE FINANCIAL DATA │░    │ 2 - REPORT FINANCIAL DATA │░
  420.     │ 3 - REPORT FINANCIAL DATA │░    │ 3 - IMPORT FINANCIAL DATA │░
  421.     │ 4 - IMPORT FINANCIAL DATA │░    ├───────────────────────────┤░
  422.     ├───────────────────────────┤░    │ Enter      Esc = Previous │░
  423.     │ Enter      Esc = Previous │░    └───────────────────────────┘░
  424.     └───────────────────────────┘░     ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  425.      ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  426.  
  427. User BENC does not have the "Delete" option on his menu because the SECURITY
  428. field demands a security level greater than or equal to 6 and his SYS_SEC is
  429. 5.  Notice that BENC's menu renumbered itself to account for the missing menu
  430. item.  Again, it is the logical order, not the ORDER field that determines
  431. the number of the menu option.
  432.  
  433. Keyboard Lock:
  434.  
  435. The Menu Sub-System contains a keyboard locking mechanism that allows the
  436. user to lock up the program under password protection while leaving the
  437. system running, but unattended.  At any point, the user may press ALT-F10,
  438. enter a password, and press ENTER.  The screen will be cleared, a message
  439. indicating that the system is locked, and a prompt for an unlocking password
  440. is presented.  The only way to unlock the program is to enter the same
  441. password again, at which point the application resumes where it left off.
  442.  
  443.  
  444. The ALT-F10 is a default key and can be changed by your program.  See the
  445. following section on Conventions, Parameters and Options for details.
  446.  
  447. Since the Menu Sub-System makes all calls to other functions, this keyboard
  448. password can be set anywhere, even when the execution has branched from the
  449. menu to your source code.
  450.  
  451. Navigation Key List
  452.  
  453. While a menu is being displayed, the very last line of the screen contains
  454. navigation and selection key help.
  455.  
  456. This key help can be changed to suit your preferences by declaring a PUBLIC
  457. or PRIVATE character variable named NAV_KEY that will be in scope when you
  458. initiate the menu system:
  459.  
  460. PUBLIC Nav_Key := 'Make your selection and press ENTER'
  461.  
  462. Summary of Available Menu Function Calls
  463.  
  464. Since much program flow-control is taken over by the Menu Sub-System,
  465. flexibility has been built in to give the developer several opportunities to
  466. "intervene" during the period when the Menu Sub-System has control.  The
  467. following is a summary of "points" where your application can step in for a
  468. moment to take care of things:
  469.  
  470. 1) At the beginning of every menu display. Using: _KGlobalFunc Function Call.
  471.  
  472. 2) Before the selected menu option is called. Using: PRE_FUNC Function Call.
  473.  
  474. 3) After the selected menu option is called. Using: POST_FUNC Function Call.
  475.  
  476. Each is called in the following order:
  477.  
  478. 1  - _KGlobalFunc function is called if defined.
  479.  
  480. 2  - Menu is drawn and user is prompted to select.
  481.  
  482. 3  - User selects and executes a Menu Option
  483.  
  484. 4a - If PRE_FUNC function is defined and returns TRUE:
  485.      4a 1: The MENU_FUNC function is called if defined.
  486.      4a 2: GOTO Step 5
  487.  
  488. 4b - If PRE_FUNC is defined and returns FALSE:
  489.      4b 1: The MENU_FUNC is NOT called, even if defined.
  490.      4b 2: GOTO Step 5
  491.  
  492. 4c - If PRE_FUNC is NOT defined:
  493.      4c 1: The MENU_FUNC function is called if defined.
  494.      4c 2: GOTO Step 5
  495.  
  496. 5  - The POST_FUNC function is called if defined.
  497.  
  498. 6  - The menu is redrawn and the process restarts at Step 1.
  499.  
  500. NOTE:
  501.  
  502. The _prefuncarg and _postfuncarg are independent of the pre_func and
  503. post_func FIELD functions that are called upon execution of menu
  504. items. _prefuncarg, and _postfuncarg are performed once upon each call to
  505. the _kmenu() function whereas pre_func and post_func are defined and
  506. called for each menu option as they are selected.
  507.  
  508. In like manner as _prefuncarg, _kglobalfunc, if declared and in scope,
  509. is evaluated and executed if present and is performed BEFORE _prefuncarg.
  510.  That makes for two pre-menu functions and one post menu function that can
  511. be called independantly of the declared field functions (pre_func
  512. and post_func).
  513.  
  514. The pre_func field function will be performed just before the menu
  515. option function. The Post_func will be performed just after the menu
  516. option function.  In the case that the menu option function is a
  517. recursive call to _kmenu, the effect is that pre_func occurs immediatly
  518. prior to displaying the menu, and post_func occurs immediatly after the
  519. menu is displayed. This allows you to take care of necessities in
  520. between menus.
  521.  
  522. Optional: A KeyBoard Password may be set at any menu by pressing ALT-F10
  523. and entering the password UNLESS that key has been redefined by
  524. your application.  In this case, the key can be changed by
  525. setting "_KMENULOCKKEY" to contain the key that is used to set the
  526. keyboard lock.
  527.  
  528. Example:
  529.  
  530. _KMENULOCKKEY = K_ALT_F5 // would set Alt-F5 to Lock Keyboard
  531.  
  532. Note: Only F2...F10, Ctrl-F2...F10, and ALT-F2...F10 can be used to
  533. redefine the Keyboard lock key if the default key of ALT-F10 is not used.
  534.  
  535. Reserved File Names: menudef.dat, menudef.idx, _update.dbf, _temp.dbf
  536.  
  537. Also, Menu Levels 999 and 9999 are reserved for internal use.
  538.  
  539.  
  540. COLORS.  The menu uses a set of default colors.  If the default colors are
  541. not desireable, they may be changed by defining a few PRIVATE memory
  542. variables that will be in scope when the menu is called:
  543.  
  544. _FSDeskColor   // desktop color
  545. _FSHeadColor   // Top screen header color
  546. _FSBottColor   // bottom line color
  547. _FSNameColor   // menu name color
  548. _FSMenuColor   // menu body color
  549. _FSBordColor   // menu border color
  550. _FSItemColor   // menu item color
  551.  
  552. For a fairly decent monochrome scheme, try:
  553.  
  554. PRIVATE _FSDeskColor := 'w/n'
  555. PRIVATE _FSHeadColor := 'w+/n'
  556. PRIVATE _FSBottColor := 'n/w'
  557. PRIVATE _FSNameColor := 'n/w'
  558. PRIVATE _FSMenuColor := 'n/w'
  559. PRIVATE _FSBordColor := 'n/w'
  560. PRIVATE _FSItemColor := 'n/w,w/n'
  561.  
  562. The default colors are (These are the colors used by the KLIPDOCS.EXE
  563. program):
  564.  
  565. _FSHeadColor = 'b/w'
  566. _FSBottColor = 'n/w'
  567. _FSDeskColor = 'rb/b,w+/b'
  568. _FSMenuColor = 'n/w,w+/n'
  569. _FSBordColor = 'n/w,w+/n'
  570. _FSItemColor = 'n/w,w+/b'
  571. _FSNameColor = 'b/w'
  572.  
  573.  
  574. EXAMPLE:
  575.  
  576.  
  577.  
  578. ******************************************************************************/
  579.