                      Clipper 5.0 Functions
                               By
                         Royce D. Bacon
                           RDB Systems



                                                     Version 1.01
                                                    April 7, 1991

                       TABLE OF CONTENTS


 1. PURPOSE OF RDBFUNC . . . . . . . . . . . . . . . . . . . .  3

 2. USING FUNCTIONS FROM RDBFUNC . . . . . . . . . . . . . . .  4

 3. RDBERROR ERROR PROCESSING SYSTEM . . . . . . . . . . . . .  5

 4. USING THE CENTER FUNCTION. . . . . . . . . . . . . . . . .  6

 5. USING THE BELL FUNCTION. . . . . . . . . . . . . . . . . .  7

 6. USING THE VALYN FUNCTION . . . . . . . . . . . . . . . . .  8

 7. USING THE ACFUNC FUNCTION. . . . . . . . . . . . . . . . .  9

 8. USING THE MSGDISP FUNCTION . . . . . . . . . . . . . . .   10

 9. USING THE PAPERLND FUNCTION. . . . . . . . . . . . . . .   11

10. USING THE PAPERPTR FUNCTION. . . . . . . . . . . . . . .   12

11. USING THE INITENVR FUNCTION. . . . . . . . . . . . . . .   13

12. USING THE CONVSTR FUNCTION . . . . . . . . . . . . . . .   14

13. USING THE SHDWBOX FUNCTION . . . . . . . . . . . . . . .   15

14. USING THE NORMCOLOR FUNCTION . . . . . . . . . . . . . .   16

15. USING THE GAUGE FUNCTIONS. . . . . . . . . . . . . . . .   18

16. USING THE DIALOGBOX FUNCTION . . . . . . . . . . . . . .   19

17. USING THE INDEXREL FUNCTION. . . . . . . . . . . . . . .   20

18. SUPPORT AND WARRANTY INFORMATION . . . . . . . . . . . .   21

 1. PURPOSE OF RDBFUNC

RDBFUNC is a set of user functions for use with Clipper 5.0
programs.  The functions provided include:
  1. Rdberror - an error processing system for Clipper 5.0
  2. Center - Function to center a character sting in an 80 column
     line
  3. Bell - Function to make a beeping sound
  4. Valyn - Function to validate a response as Y or N
  5. Acfunc - Generic function for handling Achoice key exceptions
  6. MsgDisp - Display a message and wait for response
  7. PaperLnd - Display message to load landscape paper and do
     printer setup
  8. PaperPtr - Display message to load portrait paper and do
     printer setup
  9. InitEnvr - Setup standard environment variables
 10. Convstr - Convert string of decimal values to character string
 11. ShdwBox - Display a box with shadows
 12. NormColor - Define and set color variables according the IBM
     SAA standards
 13. GaugeNew - Create new scroll gauge
 14. GaugeDisplay - Display a scroll gauge
 15. GaugeUpdate - Update a scroll gauge
 16. DialogBox - Display a dialog box with messages and selection
     buttons
 17. EnhanceColor - Set enhanced color on a dialog box
 18. IndexRel - Simulate using related alias field, e.g. db2->field
     in an index expression
 2. USING FUNCTIONS FROM RDBFUNC

You can include the functions from RdbFunc in your programs in one
of two ways:
  1. add the statement "SET PROCEDURE TO RDBFUNC" to your program. 
     This will cause the RDBFUNC program to be compiled with your
     program.
  2. Compile RDBFUNC to create an object module in the
     \CLIPPER5\OBJ directory and then include that object module in
     your link.  To compile RDBFUNC and create the object module in
     \CLIPPER5\OBJ enter the following command:
          CLIPPER RDBFUNC /M/N /O\CLIPPER\OBJ\
     To include RDBFUNC in the link enter a command like:
          RTLINK FI yourprg,RDBFUNC LIB CLIPPER,EXTEND,TR

I recommend using the second method because it eliminates the need
to recompile RDBFUNC for each program and saves the space in your
program object modules.

The error system RdbError uses the PRTSC function from the Tom
Rettig library.  The Tom Rettig library has been released to the
public domain is available on CompuServe in the NANFORUM forum and
other locations.  You must include the TR library in your link or
you may compile the program with the variable NOTRLIB defined to
skip the use of Prtsc, e.g. 
     CLIPPER RDBFUNC /M/N /O\CLIPPER\OBJ\ /DNOTRLIB

The following sections will describe the functionality and use of
each of the above functions.  Examples of using each function are
also provided.  Additional examples are contained in the program
itself since many of the functions use the other functions.

The following considerations apply to all of the functions:
  1. Many of the functions use other functions from RDBFUNC. 
     Therefore you should plan to keep all the functions together. 
     Individual functions could be replaced by your versions if
     wanted.
  2. Some of the functions rely upon the PUBLIC color variables
     defined by the NormColor function.  I know this violates the
     concepts of object oriented and some other programming
     methodologies!  However, most of these routines were designed
     some time ago and with only my use in mind.  I don't have the
     time to change them now!  My apologies!
 3. RDBERROR ERROR PROCESSING SYSTEM

RdbError is an error processing system to handle error conditions
in Clipper 5.0 programs.  It is designed to be used in production
systems to provide the maximum amount of information to you to
assist in determining the cause of a program problem.  It is also
designed to be easy for users to deal with and minimize the
dependence upon user information and actions.

RdbError is based upon the error program provided with Clipper 5.0
with the following enhancements:
  1. Printer errors are handled by displaying a dialog box that
     allows the option to retry the operation or cancel.
  2. The zero divide error condition is handled by displaying a
     message and returning a value of zero.
  3. A file not found error condition for a file with an extension
     of NTX results in an error message suggesting that the user
     reindex the databases.
  4. A file not found error condition results in a message
     suggesting the user make sure they are in the right directory.
  5. DOS error conditions result in an error message defining the
     error condition and suggesting actions to resolve the problem
     when possible.
  6. An error message indicating the procedure, line number and
     error condition is displayed on the top line of the screen.
  7. A file "ERRORMSG.ERR" is created that contains complete error
     condition information.
  8. The current record of each database in use is dumped to a file
     named database.ERR.
  9. The error message file (ERRORMSG.ERR) is printed.
 10. The current screen is printed using the Tom Rettig Library
     PRTSC function.  This function can be bypassed if you do not
     have the Tom Rettig library by defining the variable NOTRLIB
     at compile time, e.g. CLIPPER RDBFUNC /DNOTRLIB

The ERRORMSG.ERR printout can be used to help determine the cause
of the problem.  The record dumps in database.ERR are useful
information if the problem is caused by the data in a specific
record.
 4. USING THE CENTER FUNCTION

The Center function will center a character variable in a 80 column
line.

The arguments passed to the function are:
  1. string - A character string that is to be centered.  The
     string can be a character literal or a character variable.
  2. row_num - The screen row where the string is to be printed. 
     The row number may be a numeric literal or numeric variable.

The function will return:
  1. The column where the string starts as a numeric value

Examples:
     // Display/print literal on line 12
     Center('This is a character literal', 12)

     msg := 'This is a message string'  // msg to display
     row_num := 1                       // row to display on
     Center(msg, row_num)               // Display msg on row 1

 5. USING THE BELL FUNCTION

The Bell function will make a beeping sound.

There are no arguments passed or returned.

Example:
     Bell()            // Makes beeping sound

 6. USING THE VALYN FUNCTION

The Valyn function validates the passed parameter to insure that it
is a Y or N.  If the value passed is not a Y or N, an error message
is displayed and the user must press any key to continue.  This
function can be used as the VALID clause for any field that
requires a Y or N response.

The arguments passed is:
     The character string to be validated

A logical value is returned as follows:
 .T. if the value is Y or N
 .F. if the value is other than Y or N.  An error dialog box will
     be displayed in this situation.

Example:
   myn := ' '
   @ 12,5 SAY 'Delete this record? (Y/N)' GET myn VALID Valyn(myn)
   READ
 7. USING THE ACFUNC FUNCTION

The Acfunc function is a generic exception key handler for the
Achoice function.  See the Clipper documentation for Achoice for
more information on the processing required in an Achoice exception
key handler.  This function handles the following status codes and
keys:

     STATUS = 0       // Idle
          RETURN(2)           // Continue processing
     STATUS = 1       // Cursor past top of list
          RETURN(2)           // Continue processing
     STATUS = 2       // Cursor past bottom of list
          RETURN(2)           // Continue processing
     STATUS = 3       // Keystroke exception
          KEY = K_ESC      // Esc key pressed
               RETURN(0)      // Abort selection and return zero
          KEY = K_ENTER    // Enter key pressed
               RETURN(1)      // Select current item
          OTHERWISE
               RETURN(3)      // Go to item starting with letter
     STATUS = 4       // No item selectable
          RETURN(0)           // Abort selection and return zero
 8. USING THE MSGDISP FUNCTION

The MsgDisp function displays a message box of up to four lines and
waits for a response.

The arguments that must be passed are:
  1. color_cd - The color settings for the message box
  2. msg1 - A character string that is to be centered in a message
     box.
  3. msg2 - optional character string for second message line.
  4. msg3 - optional character string for third message line.
  5. msg4 - optional character string for fourth message line.

The function returns a logical value:
 .F. if the Esc key is pressed - normally indicating a request to
     exit or cancel a function.
 .T. otherwise - normally indicating a request to continue
     processing.

Example:
     go_on := MsgDisp(c_msgcritl,  ;    // Color for critcal errors
                 'The requested file was not found!', ;
                 'Press Esc to exit, any other key to continue.')
     IF !go_on        // Esc key pressed == .F.
        RETURN        // Exit requested
     ENDIF
     // Continue with processing

 9. USING THE PAPERLND FUNCTION

The PaperLnd function can be used to display a message to insert
landscape (11 x 8.5) paper and to send the printer setup string to
the printer.  The function will display a dialog box with
directions to insert landscape paper and selection buttons to
continue or cancel.  It will also display a dialog box indicating
the printer is not ready with selection buttons to retry or cancel
if the printer is not ready.

The arguments that must be passed are:
  1. The printer setup string for landscape paper.  This string
     will be send to the printer.

The function will return a logical value as follows:
 .F. if the Esc key is pressed or the cancel button was selected -
     this indicates that the function should be canceled.
 .T. otherwise - this indicates the print function can be done.

Examples:
     go_on := Paperlnd(landscp_ctrl)
     IF !go_on        // Exit requested
        RETURN
     ENDIF
     // Continue with print function
10. USING THE PAPERPTR FUNCTION

The PaperPtr function can be used to display a message to insert
portrait (8.5 x 11) paper and to send the printer setup string to
the printer.  The function will display a dialog box with
directions to insert portrait paper and selection buttons to
continue or cancel.  It will also display a dialog box indicating
the printer is not ready with selection buttons to retry or cancel
if the printer is not ready.

The arguments that must be passed are:
  1. The printer setup string for portrait paper.  This string will
     be send to the printer.

The function will return a logical value as follows:
 .F. if the Esc key is pressed or the cancel button was selected -
     this indicates that the function should be canceled.
 .T. otherwise - this indicates the print function can be done.

Examples:
     go_on := Paperptr(portrait_ctrl)
     IF !go_on        // Exit requested
        RETURN
     ENDIF
     // Continue with print function

11. USING THE INITENVR FUNCTION

The InitEnvr function sets the standard environment conditions for
a Clipper program and initializes some PUBLIC variables that I use
in all of my programs.  See the function itself for more details.

There are no arguments passed to the InitEnvr function.

The InitEnvr defines and initializes a group of PUBLIC variables. 
See the routine for a list of those variables and the values
assigned.
12. USING THE CONVSTR FUNCTION

The Convstr function converts a character sting of decimal values
to a character string of CHRs.  This function can be used to
convert printer control strings, etc. entered by users in nnn/nnn/
format to a character string to send to the printer.

The parameter to pass Convstr is:
  1. Character variable containing a string of decimal values
     specified as nnn/nnn/... 

Convstr will return:
  1. Character value of form CHR(nnn) + CHR(nnn)...

Example:
     compress := Convstr('015/')   // compressed print ctrl chars
     go_on := PaperPtr(compress)
13. USING THE SHDWBOX FUNCTION

The ShdwBox function will display a filled in box with a shadow. 
The box will be of the color specified and occupy the locations
specified.

The arguments that must be passed to ShdwBox are:
  1. top_row - numeric upper row of box
  2. col_left - numeric left-most column of box
  3. bot_row - numeric lower row of box (shadow extends one line
     below)
  4. col_right - numeric right-most column of box (shadow extends
     one column to the right)
  5. box_color - The color settings for the box

The function will return:
  1. A character string containing the saved screen area displaced
     by the box

Example:
     // Save partial screen image and display box at 10,5 to 14,75
     // Note that shadow on box extends to 15,76
     sv_screen := ShdwBox(10, 5, 14, 75, c_msgnote)
     Center('Printing report.  Please wait...', 12)
     // Do the printing function
     ...
     // Restore portion of screen displaced by box
     // Note that second row and column are 1 greater than those
     //      specified in the ShdwBox command
     RestScreen(10, 5, 15, 76, sv_screen)

14. USING THE NORMCOLOR FUNCTION

The NormColor function defines and initializes a set of PUBLIC
variables containing the standard IBM SAA colors.

You must pass this function the following parameter:
  1. usecolor - logical variable indicating if we should use the
     color mode - .T. = use color, .F. = use black & white

The NormColor function will define and initialize the following
PUBLIC variables:
*  COLOR DISPLAYS
   *  NORMAL PANELS
   c_bar = 'N/BG,BG/N,,,BG/N'           && ACTION BAR
   c_panel = 'B/W,W/GR,,,W/N'           && DISPLAY PANEL
   c_pnlget = 'N/W,W/GR,,,W/N'          && PANEL DURING GETS
   c_fkeys = 'N/W,W/N'                  && FUNCTION KEYS
   c_msgnote = 'N/W,W/N'                && NOTIFICATION MSGS
   c_msgwarn = 'N/GR+,GR+/N'            && WARNING MSGS
   c_msgcritl = 'W/R,R/W'               && CRITICAL MSGS
   *  HELP PANELS
   c_hlpbar = 'N/BG,BG/N,,,N/BG'        && ACTION BAR
   c_hlppnl = 'BG/B,B/GR+,,,B/BG'       && DISPLAY PANEL
   c_hlpget = 'W/B,B/GR+,,,B/W'         && PANEL DURING GETS
   c_hlpfkeys = 'W/B,B/W'               && FUNCTION KEYS
   c_hlpnote = 'N/W,W/N'                && NOTIFICATION MSGS
   c_hlpwarn = 'N/GR+,GR+/N'            && WARNING MSGS
   c_hlpcritl = 'W/R,R/W'               && CRITICAL MSGS
   *  POP UP WINDOWS
   c_popbar = 'N/W,W/N,,,N/W'           && ACTION BAR
   c_poppnl = 'B/BG,BG/CR+,,,BG/B'      && DISPLAY PANEL
   c_popget = 'N/BG,BG/CR+,,,BG/N'      && PANEL DURING GETS
   c_popfkeys = 'N/BG,BG/N'             && FUNCTION KEYS
   c_popnote = 'N/W,W/N'                && NOTIFICATION MSGS
   c_popwarn = 'N/GR+,GR+/N'            && WARNING MSGS
   c_popcritl = 'W/R,R/W'               && CRITICAL MSGS

*  MONOCHROME DISPLAYS
   *  NORMAL PANELS
   c_bar = 'N/W,W/N,,,N/W'              && ACTION BAR
   c_panel = 'W/N,N/W+,,,N/W'           && DISPLAY PANEL
   c_pnlget = 'W/N,N/W+,,,N/W'          && PANEL DURING GETS
   c_fkeys = 'W/N,N/W'                  && FUNCTION KEYS
   c_msgnote = 'W/N,N/W'                && NOTIFICATION MSGS
   c_msgwarn = 'W+/N,N/W+'              && WARNING MSGS
   c_msgcritl = 'N/W,W/N'               && CRITICAL MSGS
   *  HELP PANELS
   c_hlpbar = 'N/W,W/N,,,N/W'           && ACTION BAR
   c_hlppnl = 'W/N,N/W+,,,N/W'          && DISPLAY PANEL
   c_hlpget = 'W/N,N/W+,,,N/W'           && PANEL DURING GETS
   c_hlpfkeys = 'W/N,N/W'               && FUNCTION KEYS
   c_hlpnote = 'W/N,N/W'                && NOTIFICATION MSGS
   c_hlpwarn = 'W+/N,N/W+'              && WARNING MSGS
   c_hlpcritl = 'N/W,W/N'               && CRITICAL MSGS
   *  POP UP WINDOWS
   c_popbar = 'N/W,W/N,,,N/W'           && ACTION BAR
   c_poppnl = 'N/W,W+/N,,,N/W'          && DISPLAY PANEL
   c_popget = 'N/W,W+/N,,,N/W'          && PANEL DURING GETS
   c_popfkeys = 'N/W,W/N'               && FUNCTION KEYS
   c_popnote = 'N/W,W/N'                && NOTIFICATION MSGS
   c_popwarn = 'N/W+,W+/N'              && WARNING MSGS
   c_popcritl = 'W/N,N/W'               && CRITICAL MSGS

15. USING THE GAUGE FUNCTIONS

The GaugeNew, GaugeDisplay, and GaugeUpdate functions are copied
from the samples provided with Clipper 5.0.  Please refer to the
source code for information on their use.  They are included here
because some of my functions make use of them.
16. USING THE DIALOGBOX FUNCTION

The DialogBox function will display a dialog box with one or more
messages and two or more selection buttons.  The function allows
the selection of any of the specified selection buttons.  Movement
between the buttons is done with the arrow or Tab keys.  Selection
of a button is done with the Enter key.

The arguments you must pass to DialogBox are:
  1. MsgArray: An array containing the messages to be displayed in
     the dialog boxes (must be single dimension array).
  2. ColorArray: An array containing the colors to use as follows:
     [1]: Color of the Dialog box
     [2]: Color of non-selected buttons, selected buttons are
          displayed in the enhanced color.  Defaults for both are
          the current color
  3. ButtonArray: An array containing text for the buttons to be
     displayed

The DialogBox returns:
  1. The number of the button selected, e.g. 1, or a -1 if the box
     won't fit on the screen.

Example:
     LOCAL msgs[1], colors[2], buttons[2]
     msgs[1] := 'File not found!'
     colors[1] := colors[2] := c_msgcritl
     buttons[1] := 'Cancel'
     buttons[2] := 'Continue'
     btn_sel := DialogBox(msgs, colors, buttons)
     IF btn_sel == 1         // Cancel selected
        RETURN
     ENDIF
     // Continue with processing
17. USING THE INDEXREL FUNCTION

The IndexRel function is a user function that can be used in place
of using a relational alias in an INDEX command.  This is required
for the initial release of Clipper 5.0 because using an alias, e.g.
DB2->FIELD, in an INDEX command doesn't work currently.

The arguments you must pass IndexRel are:
  1. rel_var - the value of the relational variable, e.g. oeclntnbr
  2. db - the name of the database that is the object of the
     relation, e.g. CUSTDB
  3. return_var - the name of the variable whose value is to be
     returned, e.g. CSTSLSMN

IndexRel will return:
  1. The value of the variable indicated by return_var

Example:
     INDEX ON IndexRel(oeclntnbr, 'CUSTDB', 'CSTSLSMN') TO TEMP

18. SUPPORT AND WARRANTY INFORMATION

Shareware Donations Appreciated

RdbFunc is being provided on a shareware basis.  Feel free to test
it to determine it's usefulness to you.  If you find that it is
useful, donations of $10 are appreciated.  They can be sent to:
     Royce D. Bacon
     RDB Systems
     8942 W. Lawrence Ave.
     Milwaukee, WI  53225

Support

I have used these functions in numerous systems currently in use
without any known problems.  However, if you have problems,
questions or suggestions on RdbFunc I can be reached by mail at the
above address or on CompuServe user-id 70042,1001.

Limited Warranty

RDB Systems does not warrant that the licensed software will meet
your requirements or that the operation of the software will be
uninterrupted or error free.  The warranty does not cover any media
or documentation which has been subjected to damage or abuse by you
or others.  The software warranty does not cover any copy of the
software which has been altered or changed in any way.

Limitation of Liability

RDB Systems is not responsible for any problems or damage caused by
the software that may result from using the software.  This
includes, but is not limited to, computer hardware, computer
software, operating systems, and any computer or computing
accessories.  End user agrees to hold RDB Systems harmless for any
problems arising from the use of this software.

RDB Systems SHALL NOT IN ANY CASE BE LIABLE FOR ANY SPECIAL,
INCIDENTAL, CONSEQUENTIAL, INDIRECT OR OTHER SIMILAR DAMAGES
ARISING FROM ANY BREACH OF THESE WARRANTIES EVEN IF RDB Systems HAS
BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

In no case shall RDB Systems liability exceed the $10 donation made
for the software.
License To Copy

You are granted a limited license to copy RDBFUNC.ZIP ONLY FOR THE
TRIAL USE OF OTHERS subject to the terms of this software agreement
described herein.  RDBFUNC.ZIP must be copied in an unmodified form
and must contain the following files:
     RDBFUNC.PRG ---> RdbFunc program source
     RDBFUNC.DOC ---> This documentation
     README.1ST  ---> Initial instructions
No fee, charge or other compensation may be accepted or requested
for RdbFunc by anyone without the written permission of RDB
Systems.  Public Domain Disk Vendors may not charge a fee for
RdbFunc itself.  However they may include RdbFunc on a diskette for
which they charge a nominal distribution fee.  Operators of
electronic bulletin boards may post RdbFunc for downloading by
their users without written permission as long as no specific fee
is charged for RdbFunc.
