MCHOICE() Does a boxed, achoice() style popup on an array

  <expN> Achoice selection


  Provides a box for selection from array <aOptions> of
  character elements.

  [nTop,nLeft] may be specifed to determine the
  starting top and left of the popup box.

  [nBottom,nRight] may be specified to complete the box

  Default box dimensions are centered on the screen. If the dimensions
  passed are not wide enough to display the mouse hot areas on the
  bottom, the box is widened and centered on the screen.

  [cTitle] is a string to display at the top of the box.

  [lTrigger] determines (yes or no) whether a return is
  to be executed on a first letter match.(default .f.)

  [nStart] optional starting element (default 1)
  [@nRow] optional starting row. Pass by reference to retain value
  between calls.

  [aSelectable] is an array of logicals that determines which items
  are selectable. This array must be the same size as [aOptions], and
  all elements must be either True or False, not NIL. Where an element
  is False, the corresponding element in [aOptions] will be dimmed
  and will emit a BEEP when you attempt to select it.

   aMeals   := {"Pizza","Chicken","Chinese"}
   nSelect  := mchoice(aMeals)

   // or box with title
   aMeals   := {"Pizza","Chicken","Chinese"}
   nSelect  := mchoice(aMeals,,,,"Meals")

   // or box with title, first letter match = return and top/left specified
   aMeals   := {"Pizza","Chicken","Chinese"}
   nSelect  := mchoice(aMeals,10,10,,,"Meals",.t.)

   //to retain element and position between calls
   nSelect := 1
   nRow    := 1
   aMeals   := {"Pizza","Chicken","Chinese"}
   while nSelect > 0
     nSelect  := mchoice(aMeals,,,,,"Meals",.t.,nSelect,@nRow)
     // code

  Bottom of window adjusts (shrinks) to adjust to array
  size if needed.

  Now uses Tbrowse() instead of ACHOICE().





  HELPMOD() Interactively build and modify help screens



  HELPMOD() creates and modifies help screens for
  HELP() which are stored in HELP.DBF.

  HELPMOD() allows online creation and modification of
  the size, location and contents of the help screen for the
  current PROC,VARIABLE combination, and stores the results in

  HELPMOD() is intended to be used online, during
  program execution, by the developer/programmer. It can be
  removed after development.

  By setting a key xxx to this function, the current
  PROC and VARIABLE are passed to it when the key is pressed
  during the program.

  By comparing the PROC and VARIABLE parameters against
  entries in the HELP.DBF, HELPMOD() can then provide the
  appropriate help screen for modification, or, if no matching
  record is found, allow creation of a new help screen record.

  HELP.DBF is created if not present.


   SET KEY -30 TO HELPMOD  && alt-F1

  Will not be much use during ACHOICE or MENU TO





  AMSG() Pop up message box for an array of messages



  Pops up a box to display messages in <aMsgs>. Each
  element of <aMsgs> can be of type Character, Numeric, Date or

  The box is centered in the middle of the screen by

  [cTitle]  is an optional title string displayed at

  [cFooter] is an optional footer string displayed at
  <nBottom>, <nLeft+1>. Default footer is "Press a key.."

  [lCenter]  determines center messages in box or not.
  by default, message lines are left justified. Passing True
  causes messages to be centered.

  [cColor] is the color of the popup box. By default,
  is sls_popcol()

  [nTop,nLeft] are optional TOP/LEFT dimensions for the
  box. Default is centered on the screen, and big enough to hold
  all of the message lines.


  aArray := {"Attention:","all items are on sale for",1.99,;
     "today only",date()}


  If there are more message lines than will fit in the
  box, up/down arrows will scroll the messages.

  See MSG()



C5 UI – Advanced

C5 UI – Advanced


Execute a pop-up menu

ACHOICE(<nTop>, <nLeft>, <nBottom>, <nRight>,
    [<alSelectableItems> | <lSelectableItems>],
    [<nWindowRow>]) --> nPosition


Browse records within a window

BROWSE([<nTop>], [<nLeft>],
    [<nBottom>], [<nRight>]) --> lSuccess


Browse records in a table format

DBEDIT( [<nTop>], [<nLeft>],
    [<nBottom>], <nRight>],
    [<acColumnSayPictures> | <cColumnSayPicture>],
    [<acColumnHeaders> | <cColumnHeader>],
    [<acHeadingSeparators> | <cHeadingSeparator>],
    [<acColumnSeparators> | <cColumnSeparator>],
    [<acFootingSeparators> | <cFootingSeparator>],
    [<acColumnFootings> | <cColumnFooting>]) --> NIL


Display records to the console

DISPLAY <exp list>
    [TO PRINTER] [TO FILE <xcFile>]
    [<scope>] [WHILE <lCondition>]
    [FOR <lCondition>] [OFF]


List records to the console

LIST <exp list>
    [TO PRINTER] [TO FILE <xcFile>]
    [<scope>] [WHILE <lCondition>]
    [FOR <lCondition>] [OFF]


Display labels to the console

LABEL FORM <xcLabel>
    [<scope>] [WHILE <lCondition>] [FOR <lCondition>]


Display a report to the console

REPORT FORM <xcReport>
    [<scope>] [WHILE <lCondition>] [FOR <lCondition>]


Display a literal block of text



 AADD()          Add a new element to the end of an array
 ABS()           Return the absolute value of a numeric expression
 ACHOICE()       Execute a pop-up menu
 ACLONE()        Duplicate a nested or multidimensional array
 ACOPY()         Copy elements from one array to another
 ADEL()          Delete an array element
 ADIR()*         Fill a series of arrays with directory information
 AEVAL()         Execute a code block for each element in an array
 AFIELDS()*      Fill arrays with the structure of the current database file
 AFILL()         Fill an array with a specified value
 AINS()          Insert a NIL element into an array
 ALERT()         Display a simple modal dialog box
 ALIAS()         Return a specified work area alias
 ALLTRIM()       Remove leading and trailing spaces from a character string
 ALTD()          Invoke the CA-Clipper debugger
 ARRAY()         Create an uninitialized array of specified length
 ASC()           Convert a character to its ASCII value
 ASCAN()         Scan an array for a value or until a block returns true (.T.)
 ASIZE()         Grow or shrink an array
 ASORT()         Sort an array
 AT()            Return the position of a substring within a character string
 ATAIL()         Return the highest numbered element of an array
 BIN2I()         Convert a 16-bit signed integer to a numeric value
 BIN2L()         Convert a 32-bit signed integer to a numeric value
 BIN2W()         Convert a 16-bit unsigned integer to a numeric value
 BOF()           Determine when beginning of file is encountered
 BREAK()         Branch out of a BEGIN SEQUENCE...END construct
 BROWSE()*       Browse records within a window
 CDOW()          Convert a date value to a character day of the week
 CHR()           Convert an ASCII code to a character value
 CMONTH()        Convert a date to a character month name
 COL()           Return the screen cursor column position
 COLORSELECT()   Activate attribute in current color settings
 CTOD()          Convert a date string to a date value
 CURDIR()        Return the current DOS directory
 DATE()          Return the system date as a date value
 DAY()           Return the day of the month as a numeric value
 DBAPPEND()      Append a new record to the database in the current work area
 DBCLEARFIL()    Clear a filter condition
 DBCLEARIND()    Close all indexes for the current work area
 DBCLEARREL()    Clear active relations
 DBCLOSEALL()    Close all occupied work areas
 DBCLOSEAREA()   Close a work area
 DBCOMMIT()      Flush pending updates
 DBCOMMITALL()   Flush pending updates in all work areas
 DBCREATE()      Create a database file from a database structure array
 DBCREATEIND()   Create an index file
 DBDELETE()      Mark a record for deletion
 DBEDIT()        Browse records in a table layout
 DBEVAL()        Evaluate code block for each record matching scope/condition
 DBF()*          Return current alias name
 DBFIELDINFO()   Return and optionally change information about a field
 DBFILEGET()     Insert the contents of a field into a file
 DBFILEPUT()     Insert the contents of a file into a field
 DBFILTER()      Return the current filter expression as a character string
 DBGOBOTTOM()    Move to the last logical record
 DBGOTO()        Position record pointer to a specific identity
 DBGOTOP()       Move to the first logical record
 DBINFO()        Return and optionally change database file information
 DBORDERINFO()   Return and optionally change order and index file information
 DBRECALL()      Reinstate a record marked for deletion
 DBRECORDINFO()  Return and optionally change information about a record
 DBREINDEX()     Recreate all active indexes for the current work area
 DBRELATION()    Return the linking expression of a specified relation
 DBRLOCK()       Lock the record at the current or specified identity
 DBRLOCKLIST()   Return an array of the current lock list
 DBRSELECT()     Return the target work area number of a relation
 DBRUNLOCK()     Release all or specified record locks
 DBSEEK()        Move to the record having the specified key value
 DBSELECTAR()    Change the current work area
 DBSETDRIVER()   Return the database driver and optionally set a new driver
 DBSETFILTER()   Set a filter condition
 DBSETINDEX()    Empty orders from an order bag into the order list
 DBSETORDER()    Set the controlling order
 DBSETRELAT()    Relate two work areas
 DBSKIP()        Move relative to the current record
 DBSTRUCT()      Create an array containing the structure of a database file
 DBUNLOCK()      Release all locks for the current work area
 DBUNLOCKALL()   Release all locks for all work areas
 DBUSEAREA()     Use a database file in a work area
 DELETED()       Return the deleted status of the current record
 DESCEND()       Create a descending index key value
 DEVOUT()        Write a value to the current device
 DEVOUTPICT()    Write a value to the current device using a picture clause
 DEVPOS()        Move the cursor or printhead to a new position
 DIRCHANGE()     Change the current DOS directory
 DIRECTORY()     Create an array of directory and file information
 DIRMAKE()       Create a directory
 DIRREMOVE()     Remove a directory
 DISKCHANGE()    Change the current DOS disk drive
 DISKNAME()      Return the current DOS drive
 DISKSPACE()     Return the space available on a specified disk
 DISPBEGIN()     Begin buffering screen output
 DISPBOX()       Display a box on the screen
 DISPCOUNT()     Return the number of pending DISPEND() requests
 DISPEND()       Display buffered screen updates
 DISPOUT()       Write a value to the display
 DOSERROR()      Return the last DOS error number
 DOW()           Convert a date value to a numeric day of the week
 DTOC()          Convert a date value to a character string
 DTOS()          Convert a date value to a string formatted as yyyymmdd
 EMPTY()         Determine if the result of an expression is empty
 EOF()           Determine when end of file is encountered
 ERRORBLOCK()    Post a code block to execute when a runtime error occurs
 ERRORLEVEL()    Set the CA-Clipper return code
 EVAL()          Evaluate a code block
 EXP()           Calculate e**x
 FCLOSE()        Close an open binary file and write DOS buffers to disk
 FCOUNT()        Return the number of fields in the current .dbf file
 FCREATE()       Create and/or truncate a binary file to zero-length
 FERASE()        Delete a file from disk
 FERROR()        Test for errors after a binary file operation
 FIELD()         Return a field name from the current database (.dbf) file
 FIELDBLOCK()    Return a set-get code block for a given field
 FIELDGET()      Retrieve the value of a field using the field position
 FIELDNAME()     Return a field name from the current database (.dbf) file
 FIELDPOS()      Return the position of a field in a work area
 FIELDPUT()      Set the value of a field variable using the field position
 FIELDWBLOCK()   Return a set-get code block for a field in a given work area
 FILE()          Determine if files exist in the default directory or path
 FKLABEL()*      Return function key name
 FKMAX()*        Return number of function keys as a constant
 FLOCK()         Lock an open and shared database file
 FOPEN()         Open a binary file
 FOUND()         Determine if the previous search operation succeeded
 FREAD()         Read characters from a binary file into a buffer variable
 FREADSTR()      Read characters from a binary file
 FRENAME()       Change the name of a file
 FSEEK()         Set a binary file pointer to a new position
 FWRITE()        Write to an open binary file
 GETACTIVE()     Return the currently active Get object
 GETAPPLYKEY()   Apply a key to a Get object from within a reader
 GETDOSETKEY()   Process SET KEY during GET editing
 GETENV()        Retrieve the contents of a DOS environment variable
 GETPOSTVALID()  Postvalidate the current Get object
 GETPREVALID()   Prevalidate a Get object
 GETREADER()     Execute standard READ behavior for a Get object
 HARDCR()        Replace all soft carriage returns with hard carriage returns
 HEADER()        Return the current database file header length
 I2BIN()         Convert a CA-Clipper numeric to a 16-bit binary integer
 IF()            Return the result of an expression based on a condition
 IIF()           Return the result of an expression based on a condition
 INDEXEXT()      Return index extension defined by the current database driver
 INDEXKEY()      Return the key expression of a specified index
 INDEXORD()      Return the order position of the controlling index
 INKEY()         Extract a character from the keyboard buffer or a mouse event
 INT()           Convert a numeric value to an integer
 ISALPHA()       Determine if the leftmost character in a string is alphabetic
 ISCOLOR()       Determine if the current computer has color capability
 ISDIGIT()       Determine if the leftmost character in a string is a digit
 ISLOWER()       Determine if the leftmost character is a lowercase letter
 ISPRINTER()     Determine whether LPT1 is ready
 ISUPPER()       Determine if the leftmost character in a string is uppercase
 L2BIN()         Convert a CA-Clipper numeric value to a 32-bit binary integer
 LASTKEY()       Return INKEY() value of last key extracted from the keyboard
 LASTREC()       Determine the number of records in the current .dbf file
 LEFT()          Extract substring beginning with first character in a string
 LEN()           Return the length of a string or number of array elements
 LOG()           Calculate the natural logarithm of a numeric value
 LOWER()         Convert uppercase characters to lowercase
 LTRIM()         Remove leading spaces from a character string
 LUPDATE()       Return the last modification date of a database (.dbf) file
 MAX()           Return the larger of two numeric or date values
 MAXCOL()        Determine the maximum visible screen column
 MAXROW()        Determine the maximum visible screen row
 MEMOEDIT()      Display or edit character strings and memo fields
 MEMOLINE()      Extract a line of text from a character string or memo field
 MEMOREAD()      Return the contents of a disk file as a character string
 MEMORY()        Determine the amount of available free pool memory
 MEMOSETSUPER()  Set an RDD inheritance chain for the DBFMEMO database driver
 MEMOTRAN()      Replace carriage return/linefeeds in character strings
 MEMOWRIT()      Write a character string or memo field to a disk file
 MEMVARBLOCK()   Return a set-get code block for a given memory variable
 MENUMODAL()     Activate a top bar menu
 MIN()           Return the smaller of two numeric or date values
 MLCOUNT()       Count the number of lines in a character string or memo field
 MLCTOPOS()      Return position of a string based on line and column position
 MLPOS()         Determine the position of a line in a string or memo field 
 MOD()*          Return the dBASE III PLUS modulus of two numbers
 MONTH()         Convert a date value to the number of the month
 MPOSTOLC()      Return line/ column position of a string based on a position
 NETERR()        Determine if a network command has failed
 NETNAME()       Return the current workstation identification
 NEXTKEY()       Read the pending key in the keyboard buffer 
 NOSNOW()        Toggle snow suppression
 ORDBAGEXT()     Return the default order bag RDD extension
 ORDBAGNAME()    Return the order bag name of a specific order
 ORDCOND()       Specify conditions for ordering
 ORDCONDSET()    Set the condition and scope for an order
 ORDCREATE()     Create an order in an order bag
 ORDDESCEND()    Return and optionally change the descending flag of an order
 ORDDESTROY()    Remove a specified order from an order bag
 ORDFOR()        Return the FOR expression of an order
 ORDISUNIQUE()   Return the status of the unique flag for a given order
 ORDKEY()        Return the key expression of an order
 ORDKEYADD()     Add a key to a custom built order
 ORDKEYCOUNT()   Return the number of keys in an order
 ORDKEYDEL()     Delete a key from a custom built order
 ORDKEYGOTO()    Move to a record specified by its logical record number
 ORDKEYNO()      Get the logical record number of the current record
 ORDKEYVAL()     Get key value of the current record from controlling order
 ORDLISTADD()    Add orders to the order list
 ORDLISTCLEAR()  Clear the current order list
 ORDLISTREBUI()  Rebuild all orders in the order list of the current work area
 ORDNAME()       Return the name of an order in the order list
 ORDNUMBER()     Return the position of an order in the current order list
 ORDSCOPE()      Set or clear the boundaries for scoping key values
 ORDSETFOCUS()   Set focus to an order in an order list
 ORDSETRELAT()   Relate a specified work area to the current work area
 ORDSKIPUNIQUE() Move record pointer to the next or previous unique key
 OS()            Return the operating system name
 OUTERR()        Write a list of values to the standard error device
 OUTSTD()        Write a list of values to the standard output device
 PAD()           Pad character, date, and numeric values with a fill character
 PCOL()          Return the current column position of the printhead
 PCOUNT()        Determine the position of the last actual parameter passed
 PROCLINE()      Return source line number of current or previous activation
 PROCNAME()      Return name of the current or previous procedure or function
 PROW()          Return the current row position of the printhead
 QOUT()          Display a list of expressions to the console
 RAT()           Return the position of the last occurrence of a substring
 RDDLIST()       Return an array of the RDDs
 RDDNAME()       Return name of RDD active in current or specified work area
 RDDSETDEFAULT() Set or return the default RDD for the application
 READEXIT()      Toggle Up arrow and Down arrow as READ exit keys
 READFORMAT()    Return and optionally set code block to implement format file
 READINSERT()    Toggle the current insert mode for READ and MEMOEDIT()
 READKEY()*      Determine what key terminated a READ
 READKILL()      Return and optionally set whether current READ can be exited
 READMODAL()     Activate a full-screen editing mode for a GetList
 READUPDATED()   Determine whether any GET variables changed during a READ
 READVAR()       Return the current GET/MENU variable name
 RECCOUNT()*     Determine the number of records in the current database file
 RECNO()         Return the identity at the position of the record pointer
 RECSIZE()       Determine the record length of a database (.dbf) file
 REPLICATE()     Return a string repeated a specified number of times
 RESTSCREEN()    Display a saved screen region to a specified location
 RIGHT()         Return a substring beginning with the rightmost character
 RLOCK()         Lock the current record in the active work area
 ROUND()         Return a numeric value rounded to a specified number of digits
 ROW()           Return the screen row position of the cursor
 RTRIM()         Remove trailing spaces from a character string
 SAVESCREEN()    Save a screen region for later display
 SCROLL()        Scroll a screen region up or down, right or left
 SECONDS()       Return the number of seconds elapsed since midnight
 SELECT()        Determine the work area number of a specified alias
 SET()           Inspect or change a system setting
 SETBLINK()      Toggle * interpretation between blinking/background intensity
 SETCANCEL()     Toggle Alt+C and Ctrl+Break as program termination keys
 SETCOLOR()      Return the current colors and optionally set new colors
 SETCURSOR()     Set the cursor shape
 SETKEY()        Assign an action block to a key
 SETMODE()       Change display mode to a specified number of rows and columns
 SETPOS()        Move the cursor to a new position
 SETPRC()        Set PROW() and PCOL() values
 SOUNDEX()       Convert a character string to "soundex" form
 SPACE()         Return a string of spaces
 SQRT()          Return the square root of a positive number
 STR()           Convert a numeric expression to a character string
 STRTRAN()       Search and replace characters within a string or memo field
 STUFF()         Delete and insert characters in a string
 SUBSTR()        Extract a substring from a character string
 TIME()          Return the system time
 TONE()          Sound a speaker tone for a specified frequency and duration
 TRANSFORM()     Convert any value into a formatted character string
 TRIM()          Remove trailing spaces from a character string
 TYPE()          Determine the type of an expression
 UPDATED()       Determine whether a GET changed during a READ
 UPPER()         Convert lowercase characters to uppercase
 USED()          Determine whether a database file is in USE
 VAL()           Convert a character number to numeric type
 VALTYPE()       Determine the data type returned by an expression
 VERSION()       Returns CA-Clipper version
 WORD()*         Convert CALL command numeric parameters from double to int
 YEAR()          Convert a date value to the year as a numeric value


 Execute a pop-up menu

     ACHOICE(<nTop>, <nLeft>, <nBottom>, <nRight>,
        [<alSelectableItems> | <lSelectableItems>],
        [<nWindowRow>]) --> nPosition


     <nTop>, <nLeft> and <nBottom>, <nRight> are the upper-
     left and lower-right window coordinates.  Row values can range from zero
     to MAXROW() and column values can range from zero to MAXCOL().

     <acMenuItems> is an array of character strings to display as the
     menu items.  The individual menu items are later identified by their
     numeric positions in this array.

     <alSelectableItems> is a parallel array of logical values--one
     element for each item in <acMenuItems>--that specify the selectable menu
     items.  Elements can be logical values or character strings.  ACHOICE()
     will not permit a null string and stops displaying if it encounters one.
     If the element is a character string, it is evaluated as a macro
     expression which should evaluate to a logical data type.  In either
     case, a value of false (.F.) means that the corresponding menu item is
     not available, and a value of true (.T.) means that it is available.  If
     you specify <lSelectableItems> instead of an array, false (.F.) makes
     all menu items unavailable and true (.T.) makes all menu items
     available.  By default, all menu items are available for selection.

     <cUserFunction> is the name of a user-defined function that executes
     when an unrecognizable key is pressed.  Specify the function name as a
     character expression without parentheses or arguments.  Note that the
     behavior of ACHOICE() is affected by the presence of this argument.
     Refer to the discussion below for further information.

     <nInitialItem> is the position in the <acMenuItems> array of the
     item that will be highlighted when the menu is initially displayed.  If
     you specify an unavailable menu item or no argument at all, the initial
     menu item is the first selectable item in the array.

     <nWindowRow> is the number of the window row on which the initial
     menu item will appear.  Row numbering begins with zero.  By default, the
     initial menu item appears as close to the top of the window as possible,
     without leaving any empty rows at the bottom.  Thus, if there are enough
     menu items following the initial one to fill up the window, the initial
     form will appear on the first row (row zero) of the menu.  This function
     argument is used to control the initial menu appearance when there are
     more menu items than will fit in the window.

     As with all functions, optional arguments are omitted by using a comma
     instead of the actual argument.


     ACHOICE() returns the numeric position in the <acMenuItems> array of the
     menu item selected.  If the selection process is aborted, ACHOICE()
     returns zero.


     ACHOICE() is a user interface function that can create various kinds of
     pop-up menus.  Each menu uses an array of character strings as menu
     items and a parallel array of logical values to determine whether items
     are selectable.  When you invoke ACHOICE(), the list of menu items is
     displayed within the specified window coordinates.  When the user
     presses Return, the current item is selected, and ACHOICE() returns the
     position of the menu item in <acMenuItems>.  When the user presses Esc,
     ACHOICE() aborts and returns zero.

     The menu items scroll if the number of items in <acMenuItems> exceeds
     the number of rows in the menu window, and the user attempts to move the
     highlight beyond the top or bottom of the menu window.  Note that the
     highlight does not wrap when you reach the top or bottom of the list of
     items.  Pressing the first letter does, however, wrap the highlight
     within the set of items whose first letter matches the key you press.

     .  Navigating the menu:  ACHOICE() has two modes depending on
        whether the <cUserFunction> argument is specified.  If it is not
        specified the following navigation keys are active:

        ACHOICE() Keys (No User Function)
        Key            Action
        Up arrow       Go to previous item
        Down arrow     Go to next item
        Home           Go to first item in menu
        End            Go to last item in menu
        Ctrl+Home      Go to first item in window
        Ctrl+End       Go to last item in window
        PgUp           Go to previous page
        PgDn           Go to next page
        Ctrl+PgUp      Go to the first item in menu
        Ctrl+PgDn      Go to last item in menu
        Return         Select current item
        Esc            Abort selection
        Left arrow     Abort selection
        Right arrow    Abort selection
        First Letter   Go to next item beginning with first letter

     .  Color:  Menu items are displayed in standard color, the
        highlight in enhanced color, and the unavailable items in the
        unselected color.  For example, the following color statement

        SETCOLOR("W+/N, BG+/B, , , W/N")

        displays a menu that is bright white on black, the highlight is
        bright cyan on blue, and the unavailable menu items are dim white on

     .  User function: Like the other user interface functions,
        ACHOICE() supports a user function.  The user function is specified
        when you want to nest ACHOICE() invocations to create hierarchical
        menus or to redefine keys.

        When a user function is specified, ACHOICE() processes only a limited
        set of keys automatically.  These are listed in the following table.
        All other keys generate a key exception which passes control to the
        user function for handling.  Control is also passed to the user
        function when ACHOICE() goes idle (i.e., when there are no more keys
        to process).

        ACHOICE() Keys (User Function Specified)
        Key          Action
        Uparrow      Go to previous item
        Dnarrow      Go to next item
        Ctrl+Home    Go to first item in window
        Ctrl+End     Go to last item in window
        PgUp         Go to previous page
        PgDn         Go to next page
        Ctrl+PgUp    Go to the first item in menu
        Ctrl+PgDn    Go to last item in menu

        When ACHOICE() executes the user function, it automatically passes
        the following three parameters:

        -  The current ACHOICE() mode

        -  The current element in the array of items

        -  The relative row position within the menu window

        The mode indicates the current state of ACHOICE() depending on the
        key pressed and the action taken by ACHOICE() prior to executing the
        user function.  The mode parameter has the following possible values:

        ACHOICE() Modes
        Mode    Achoice.ch     Description
        0       AC_IDLE        Idle
        1       AC_HITTOP      Attempt to cursor past top of list
        2       AC_HITBOTTOM   Attempt to cursor past bottom of list
        3       AC_EXCEPT      Keystroke exceptions
        4       AC_NOITEM      No selectable items

        After the user function has performed whatever operations are
        appropriate to the ACHOICE() mode or LASTKEY(), it must RETURN a
        value requesting ACHOICE() to perform an operation from the following
        set of actions:

        ACHOICE() User Function Return Values
        Value   Achoice.ch     Action
        0       AC_ABORT       Abort selection
        1       AC_SELECT      Make selection
        2       AC_CONT        Continue ACHOICE()
        3       AC_GOTO        Go to the next item whose first character
                               matches the key pressed


     .  This example uses two literal arrays to specify the menu items
        and selection criteria.  After the menu is displayed and the user
        makes a selection, the name of the selected menu item is displayed:

        acMenuItems := {"One", "Two", "-------", "Three"}
        alSelectableItems := {.T., .T., .F., .T.}
        nPosition := ACHOICE(10, 10, 12, 15, acMenuItems,;
        ? acMenuItems[nPosition]

     .  This example declares an array of menu items and supplies a
        user-defined function which displays a message with each highlighted

        #include "achoice.ch"
        #include "inkey.ch"

        PROCEDURE Main()

           LOCAL acMenuItems[4], cUserFunction, nRetVal
           LOCAL nKey, nPos

           acMenuItems[1] := "Add"
           acMenuItems[2] := "Edit"
           acMenuItems[3] := "Delete"
           acMenuItems[4] := "Update"


           nPos := ACHOICE( 10, 10, 13, 15, acMenuItems,;
                          .T., "cUserFunction" )
           DO CASE
           CASE nPos == 1
              //  Put ADD routine here
           CASE nPos == 2
              //  Put EDIT routine here
           CASE nPos == 3
              //  Put DELETE routine here
           CASE nPos ==4
              //  Put UPDATE routine here


        FUNCTION cUserFunction( nMode, nCurElement, nRowPos )

           LOCAL nRetVal := AC_CONT     // Default, Continue
           LOCAL nKey := LASTKEY()

           DO CASE
        // After all pending keys are processed, display message
           CASE nMode == AC_IDLE
           DO CASE
              CASE nCurElement == 1
                 @ 22, 5 SAY " Adding   "
              CASE nCurElement == 2
                 @ 22, 5 SAY " Editing  "
              CASE nCurElement ==  3
                 @ 22, 5 SAY " Deleting "
              CASE nCurElement ==  4
                 @ 22, 5 SAY " Updating "

              nRetVal := AC_CONT            // Continue ACHOICE()

           CASE nMode == AC_HITTOP          // Attempt to go past Top
              TONE( 100, 3 )
           CASE nMode == AC_HITBOTTOM       // Attempt to go past
                                            // Bottom
              TONE( 100, 3 )

           CASE nMode == AC_EXCEPT          // Key Exception
              DO CASE
              CASE nKey == K_RETURN         // If RETURN key, select
                 nRetVal := AC_SELECT
              CASE nKey == K_ESC            // If ESCAPE key, abort
                 nRetVal := AC_ABORT
                    nRetVal := AC_GOTO      // Otherwise, go to item

        RETURN nRetVal

     .  The next example declares the arrays, specifies a selection
        condition for one of the menu items, and supplies a user function:

        FUNCTION MyMenu
           LOCAL acMenuItems[4], alSelectableItems[4],;
                  cUserFunction := "DoIt"
           acMenuItems[1] := "Add Record"
           acMenuItems[2] := "Edit Record"
           acMenuItems[3] := "Delete Record"
           acMenuItems[4] := "Update Record"
           alSelectableItems[1] := .T.
           alSelectableItems[2] := .T.
           alSelectableItems[3] := .T.
           alSelectableItems[4] := "!UPDATED()"
           // Selection condition

           RETURN ACHOICE(10, 10, 12, 15, acMenuItems,;
              alSelectableItems, cUserFunction)

     .  This example uses two arrays to specify menu items and
        corresponding action blocks.  After the menu is displayed and the
        user makes a selection, the ACHOICE() return value is used to
        determine which action block of the aActionItems array is evaluated:

        PROCEDURE Main()
           LOCAL nChoice
           LOCAL aMenuItems := { "Add Record   ", ;
                                    "Edit Record  ", ;
                                    "Delete Record", ;
                                    "Update Record"   }

           LOCAL aActionItems := { {|| AddFunc()  }, ;
                                    {|| EditFunc() }, ;
                                    {|| DelFunc()  }, ;
                                    {|| UpdFunc()  }  }

           nChoice := ACHOICE( 10, 10, 13, 22, aMenuItems )

           IF nChoice == 0
              QUIT      // ESCAPE was pressed

           EVAL( aActionItems[nChoice] )


 Files   Library is EXTEND.LIB, header files are Achoice.ch and Inkey.ch.



The secrets of array handling, part 1.

The secrets of array handling Part – 1