home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 19
/
CD_ASCQ_19_010295.iso
/
dos
/
prg
/
builder
/
libc5x.doc
< prev
next >
Wrap
Text File
|
1994-10-26
|
175KB
|
5,530 lines
Page: 1
Aeolus Software
FUNCTION LIBRARY REFERENCE GUIDE
COPYRIGHT
c 1992, 1993, 1994 by Aeolus Software
All rights reserved.
Aeolus Software
P.O. Box 11915
St. Paul, MN 55111-0915
(612) 730-4135
Mark H. Kania, CIS# 76270,2436
Page: 2
Contents
INTRODUCTION . . . . . . . . . . . . . . . . . 5
Conventions: . . . . . . . . . . . . . . . . . 6
Alphabetical Proc/Func summary . . . . . . . . 7
@..ABPROMPT ... / @..WINPROMPT ... . . . . . .16
@..GET / @..WINGET . . . . . . . . . . . . . .17
@..WINSAY .... . . . . . . . . . . . . . . . .19
@....WINDOW .... . . . . . . . . . . . . . . .20
ABGOBOTTOM() . . . . . . . . . . . . . . . . .21
ABGOTOP(). . . . . . . . . . . . . . . . . . .22
ABTBSKIP() . . . . . . . . . . . . . . . . . .23
ADD_REC(). . . . . . . . . . . . . . . . . . .24
ADDGET() . . . . . . . . . . . . . . . . . . .25
ADDMPAD(). . . . . . . . . . . . . . . . . . .26
*ADDPROMPT() . . . . . . . . . . . . . . . . .27
APOP() . . . . . . . . . . . . . . . . . . . .28
ASC2BIN(). . . . . . . . . . . . . . . . . . .30
ASK(). . . . . . . . . . . . . . . . . . . . .31
ASKMENU(). . . . . . . . . . . . . . . . . . .33
BCHOICE(). . . . . . . . . . . . . . . . . . .35
BETWEEN(). . . . . . . . . . . . . . . . . . .36
BLDRERR(). . . . . . . . . . . . . . . . . . .37
BROWSEDB() . . . . . . . . . . . . . . . . . .38
BROWSER(). . . . . . . . . . . . . . . . . . .39
BRWMOUSE() . . . . . . . . . . . . . . . . . .40
CENTER() . . . . . . . . . . . . . . . . . . .41
CHGDIR() . . . . . . . . . . . . . . . . . . .42
CHGDSK() . . . . . . . . . . . . . . . . . . .43
CHKCHR() . . . . . . . . . . . . . . . . . . .44
CKPRTR() . . . . . . . . . . . . . . . . . . .46
CRTMNUARRY() . . . . . . . . . . . . . . . . .47
DBCHANGED(). . . . . . . . . . . . . . . . . .48
DBREPL() . . . . . . . . . . . . . . . . . . .49
DBSTATE(). . . . . . . . . . . . . . . . . . .50
DBSTOR() . . . . . . . . . . . . . . . . . . .51
DEC2HEX(). . . . . . . . . . . . . . . . . . .53
DELCOLPUT(). . . . . . . . . . . . . . . . . .54
DICTGET(). . . . . . . . . . . . . . . . . . .55
DICTPUT(). . . . . . . . . . . . . . . . . . .56
DELMPAD(). . . . . . . . . . . . . . . . . . .58
DRVTST() . . . . . . . . . . . . . . . . . . .59
DUPCHK() . . . . . . . . . . . . . . . . . . .60
. Page: 3
EDT_MEMO() . . . . . . . . . . . . . . . . . .62
ERRTONE(). . . . . . . . . . . . . . . . . . .63
ETC(). . . . . . . . . . . . . . . . . . . . .64
FEOF() . . . . . . . . . . . . . . . . . . . .65
FGETS(). . . . . . . . . . . . . . . . . . . .66
FGETSR() . . . . . . . . . . . . . . . . . . .67
FIL_LOCK() . . . . . . . . . . . . . . . . . .68
FLD_REPL() . . . . . . . . . . . . . . . . . .69
GEN_MAINT(). . . . . . . . . . . . . . . . . .70
GENVLD() . . . . . . . . . . . . . . . . . . .74
GETEDIT(). . . . . . . . . . . . . . . . . . .76
GOT(). . . . . . . . . . . . . . . . . . . . .78
HEX2DEC(). . . . . . . . . . . . . . . . . . .79
HNDLS(). . . . . . . . . . . . . . . . . . . .80
IN_CANADA(). . . . . . . . . . . . . . . . . .81
IN_USA() . . . . . . . . . . . . . . . . . . .82
INFILE() . . . . . . . . . . . . . . . . . . .83
INPATH() . . . . . . . . . . . . . . . . . . .85
IOCTL(). . . . . . . . . . . . . . . . . . . .86
ISEEK(). . . . . . . . . . . . . . . . . . . .88
KYBD() . . . . . . . . . . . . . . . . . . . .90
MAKE_EMPTY() . . . . . . . . . . . . . . . . .91
MAKDIR() . . . . . . . . . . . . . . . . . . .92
MAXHNDLS() . . . . . . . . . . . . . . . . . .93
MENU() . . . . . . . . . . . . . . . . . . . .94
MESSAGE(). . . . . . . . . . . . . . . . . . .97
MGETROWCOL() . . . . . . . . . . . . . . . . .98
MOUSCRS(). . . . . . . . . . . . . . . . . . .99
MOUSEINIT(). . . . . . . . . . . . . . . . . 100
MOUSEINT() . . . . . . . . . . . . . . . . . 101
MSETROWCOL() . . . . . . . . . . . . . . . . 103
MSGBOX() . . . . . . . . . . . . . . . . . . 104
NET_USE(). . . . . . . . . . . . . . . . . . 106
NOT_REQ(). . . . . . . . . . . . . . . . . . 107
NUMERIC(). . . . . . . . . . . . . . . . . . 109
OPEN_FIL() . . . . . . . . . . . . . . . . . 110
PCKVLD() . . . . . . . . . . . . . . . . . . 112
PLIST(). . . . . . . . . . . . . . . . . . . 115
PUTKEY() . . . . . . . . . . . . . . . . . . 120
READGETS() . . . . . . . . . . . . . . . . . 121
REC_LOCK() . . . . . . . . . . . . . . . . . 122
REL_MAINT(). . . . . . . . . . . . . . . . . 123
. . . . . . . . . . . . . . . . . . . Page: 4
REQ(). . . . . . . . . . . . . . . . . . . . 126
RGHT_JST() . . . . . . . . . . . . . . . . . 127
SAVE_IT(). . . . . . . . . . . . . . . . . . 128
SETMOUSE() . . . . . . . . . . . . . . . . . 130
SETMSGLIN(). . . . . . . . . . . . . . . . . 133
SHADOW() . . . . . . . . . . . . . . . . . . 134
SHOW_MEMO(). . . . . . . . . . . . . . . . . 135
SHOW_TXT() . . . . . . . . . . . . . . . . . 136
TEXTVIEW() . . . . . . . . . . . . . . . . . 138
THERMOMETR() . . . . . . . . . . . . . . . . 142
TIMEOUT(). . . . . . . . . . . . . . . . . . 144
VAR(). . . . . . . . . . . . . . . . . . . . 148
VARINIT(). . . . . . . . . . . . . . . . . . 150
WAITKEY(). . . . . . . . . . . . . . . . . . 151
WINBOTT(). . . . . . . . . . . . . . . . . . 152
WINLEFT(). . . . . . . . . . . . . . . . . . 153
WINPOP() . . . . . . . . . . . . . . . . . . 154
WINPUSH(). . . . . . . . . . . . . . . . . . 155
WINRIGHT() . . . . . . . . . . . . . . . . . 157
WINSTYLE() . . . . . . . . . . . . . . . . . 158
WINTOP() . . . . . . . . . . . . . . . . . . 159
Page: 5
INTRODUCTION
The Aeolus Builder Clipper(tm) function library contains
many varied and useful functions that make programming in
Clipper faster and easier than ever before. Thank you for
trying this shareware library. Mark H. Kania: Owner Aeolus
Software: ASP Member.
The functions in this document do not contain the real
function names as they appear in the library. The library
function names are spelled exactly the same as this document
suggests except that they are prefixed by the letters "Ab"
(Aeolus Builder). The source code you write and that is
generated by the Aeolus Code Generators does not need to use
the prefix characters. The prefix characters are added by
the Clipper preprocessor, the file "Builder.ch" contains a
"#xtranslate" preprocessor directive for every function as
it is named in this document and prefixes it with the
letters "Ab". This makes the source code (and the library
documentation) much more readable and at the same time makes
it so that the function names are unique.
If you write programs that access these library functions
and do not "#include" the "Builder.ch" header file, you will
have to enter the "Ab" function name prefix every time you
call a Builder library function.
Examples of many of these functions can be seen in the
Builder demonstration companion program. Look for
BDEM22.ZIP on CompuServe or any ASP approved BBS.
* These functions are located in BLDRASM.LIB.
WARNING: Do NOT link BLDRASM.LIB into an overlay because
some of the routines take over system interrupts. If these
routines are in an overlay, your computer WILL lockup! That
is why it is a separate library.
++ These functions are new to BUILDER.LIB v2.2.
^^ These functions are obsolete with Builder version 2.2.
|| These functions are copied from the book "Programming
in Clipper" 2nd Edition by Stephen J. Straley (use by
permission)
I would also like to highly recommend Steves's new book
"Clipper Power Tools" from Sirius Software it comes with a
diskette of indispensable Clipper routines.
Page: 6
Conventions:
<expC>: A character expression
<expL>: A logical expression (i.e. .t. or .f.)
<expD>: A date expression
<expN>: A numeric expression, a number or calculation
<expA>: An array
<exp>: An expression that may be of different types
<expB>: A Code Block
<expO>: A Clipper Object
Parameters notated inside square brackets ([]) are optional
parameters, defaults will be given where applicable.
Page: 7
Alphabetical Proc/Func summary
@ <row>, <col> ABPROMPT <expC> TO <expA>
[EXECUTE <exp>]
[WHEN <expL>]
[MESSAGE <expC> AT <expN1>, <expN2>]
@ <row>, <col> GET <var> [normal getclauses]
[VALIDBLOCK <expB> | VALID <expL>]
-OR-
@ <row>,<col> GET <var> USING MENU <expA>
-OR-
@ <row>,<col> GET <var> USING DROPDOWN <expA>
@ <winrow>, <wincol> WINGET <var> [normal getclauses]
[VALIDBLOCLK <expB> | VALID <expL>]
-OR-
@ <winrow>,<wincol> WINGET <var> USING MENU <expA>
-OR-
@ <winrow>,<wincol> WINGET <var> USING DROPDOWN <expA>
@ <winrow>, <wincol> WINPROMPT <expC> TO <expA>
[EXECUTE <exp>]
[WHEN <expL>]
[MESSAGE <expC> [AT <expN1>, <expN2>]]
@ <winrow>, <wincol> WINSAY [say clauses]
@ <top>,<left>,<bottom>,<right> WINDOW
[NOSAVE] [NOCLEAR] [NOSHADOW]
[NOBORDER] [STYLE <expC>]
[COLOR <expC>]
*ABGOBOTTOM( <expO> )
TBrowse go bottom procedure.
*ABGOTOP( <expO> )
TBrowse go top procedure.
*ABTBSKIP( <expN>, <expO> )
TBrowse database movement procedure.
Page: 8
*ADD_REC(<expN>)
Adds a blank .DBF record.
ADDMPAD(<expN1>,<expN2>,<expN3>,<expN4>,<expN5>,<expB>)
Add mouse pad.
*ADDPROMPT(<expA>,<expN1>,<expN2>,<expC1>[,<expB>][,<expN3>]
;
[,<expN4>][,<expC2>])
Add a prompt to a menu array.
ASC2BIN(<expC>)
Converts ASCII control indicators to control characters.
ASK(<expC1>,<expC2>,<expN1>,<expN2>[,<expN3>][,<expC3>] ;
[,<expC4>])
Prompt and response function.
ASKMENU(<expC1>,<expA>,<expN1>,<expN2>[,<expN3>][,<expC2>] ;
[,<expC3>])
Prompt and response function.
APOP(<expN1>,<expN2>,<expN3>,<expN4>,<expA>,<expN5>[,<ex
pC2>][,<expC3>])
Choose multiple menu items from array.
BCHOICE( <expN1>, <expN2>, <expN3>, <expN4>, <expA>[,
<expN2>][, <expL>] )
Similar to ACHOICE() but will accept mouse input.
BETWEEN(<exp1>,<exp2>,<exp3>)
Evaluates if expression 1 is greater than and equal to
expression 2 and less than and equal to expression 3.
*BLDRERR( <expO>, <expC> )
Builder error system.
BROWSEDB( <expA>[, <expL>] )
Operate a TBrowse object or and array of TBrowse
objects.
++BROWSER(
<expN1>,<expN2>,<expN3>,<expN4>[,<expC>][,<expN5>][,<exp
N6>])
Sets up window to browse a database.
*BRWMOUSE(<expN1>,<expN2>,<expN3>,<expN4>,<expO>)
Set up or remove mouse pads for a TBrowse object.
Page: 9
CENTER(<expC1>,<expN1>,<expN2>,<expN3>[,<expC2>])
Centers text on the screen or within a window.
CHGDIR(<expC>)
Changes the DOS default directory.
CHGDSK(<expC>)
Changes the DOS default drive.
*CHKCHR(<expC1>,<expC2>,<expN1>,<expN2>,<expN3>[,<expC3>])
VALID, tests if keyed input is in <expC1>.
CKPRTR(<expN>)
Checks if parallel printer is available.
CRTMNUARRY(<expN1>,<expN2>,<expA>)
Create an 'across' type menu array.
DBCHANGED(<expA>)
Returns true if database fields do not exactly match
memory variables.
*DBREPL(<expA>)
Replaces database field variables with memory variables.
DBSTATE([<expC1>])
Returns all relevant database info in a string and, sets
back to a previous DBSTATE() also.
DBSTOR(<expA>)
Stores database field variables to memory variables.
DEC2HEX(<expN>)
Returns a Hexadecimal string of the passed integer.
DELCOLPUT( <expO>, <expN> )
Remove a column from a TBrowse object an place in the
the 'recoverable' columns list.
DELMPAD(<expN>)
Delete a mouse pad.
DICTGET( <expA>, <expC>, <exp> )
Get a value from a dictionary array.
DICTPUT( <expA>, <expC>, <exp> )
Put a value in a dictionary array.
DRVTST(<expC>)
Page: 10
Test for floppy drive ready.
*DUPCHK(<expC1>,<expC2>,<expN1>,<expC3>,<expN2>,<expN3>, ;
<expN4>,
<expL>, <expC4>)
VALID function to test for a duplicate condition for the
keyed input.
EDT_MEMO(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>,<expC2>
,<expC3>, ;
<expC5>,<expC6>[,<expN5>][,<expL>]
Either stand alone or VALID function to display/edit a
Memo field inside a border.
ERRTONE([<expN>])
Beep speaker with optional sounds.
ETC(<expC>,<expN1>,<expN2>,<expN3>)
Calculate estimated time to complete an iterative
process.
FEOF([<expL>])
EOF detection when reading a .SDF file using FGETS().
FGETS(<expN>)
Returns next record in a .SDF type file.
FGETSR(<expN>)
Returns the previous record in a .SDF type file.
FIL_LOCK(<expN>)
Locks a file for exclusive type activity.
FLD_REPL(<expC1>,<expC2>)
Replace one database field in a shared or single user
environment.
GETEDIT(<expC2>,<expN1>,<expN2>)
Save GETs to a database record.
*GEN_MAINT( ;
<expN1>,<expN2>,<expN3>,<expN4>,<expC1>,<expA>[,<expN5>]
;
[,<expL>][,<expC2>][,<expB>])
Generic file maintenance.
*GENVLD(<expL1>,<expC1>,<expN1>,<expN2>,<expN3>,<expL2>[
,<expC2>])
Page: 11
VALID generic function to test a user defined condition
on a GET.
*GOT(<expC>,<expN1>,<expN2>)
Get field data from a database record number and field
number.
HEX2DEC(<expC>)
Converts a string of Hexadecimal characters to a numeric
integer.
HNDLS()
Returns the maximum number of files handles configured
for the computer.
IN_CANADA(<expC>)
Returns true if the passed two byte string is a valid
Canadian province code.
IN_USA(<expC>)
Returns true if the passed two byte string is a valid
U.S. state code.
*INFILE(<expC1>,<expN1>,<expC2>,<expN2>,<expN3>,<expN4>,
<expL> [,<expC3>])
VALID function to only force data entered into a GET
field to be found in another file.
INPATH(<expC1>[,<expC2>])
Returns the pathname where the file <expC1> is located.
Checks directories listed in DOS environment variable
"PATH" or <expC2> environment variable if passed.
IOCTL( <expN1>, <expN2> )
Allows binary IO on files opened using low-level file
IO.
++ISEEK(<exp>,<expC>,<expN>,<expL>)
Locate a record in a database via an index.
KYBD( <expC> )
Stuff the keyboard buffer.
MAKDIR(<expC>)
Creates a DOS directory.
MAKE_EMPTY(<expC>)
Create an empty memory variable based on the passed
Page: 12
variable.
MAXHNDLS(<expN>)
Tests system configuration for number of file handles.
MENU(<expA>[,<exp>][,<expO>][,<expL>])
Process a menu array.
MESSAGE(<expC1>,<expN1>,<expN2>[,<expN3>][,<expC2>])
Display a screen message.
MGETROWCOL(@<expN1>,@<expN2>)
Returns mouse row, column, and button state.
MOUSCRS(<expL>)
Turns the mouse cursor on and off.
MOUSEINIT()
Initialize mouse for a BUILDER application.
MOUSEINT(<expN1>,<expN2>,<expN3>,<expN4>)
Call the mouse driver interrupt.
MSETROWCOL(<expN1>,<expN2>)
Sets mouse rows and column position.
MSGBOX(<expC1>[,<expC2>][,<expC3>][,<expC4>][,<expN1>] ;
[,<expN2>][,<expN3>][,<expN4>])
Display a message box on the screen, optionally ask a
question.
*NET_USE(<expC1>,<expL>,<expN>,<expC2>[,<expC3>])
Network file open function.
NOT_REQ(<expC1>,<expN1>,<expN2>,<expN3>[,<expC2>])
VALID function to force a GET field to be empty.
NUMERIC(<expC>)
Check a character string for any non-numeric characters.
++OPEN_FIL(<expC1>[,<expL1>][,<expC2>][,<expL2>][,<expC3>])
All purpose file open routine.
PCKVLD(<expC1>,<expN1>,<expN2>,<expL1>,<expC2>,<expL2> ;
[,<expC3>][,<expC4>])
VALID function to force entry into a GET field to be in
another database. Gives user a pick list of the nearest
data to what was keyed.
Page: 13
PLIST(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>,<expN5>,<expC1
>, ;
<expC2>[,<expL1>][,<expC3>][,<expC4>][,<expB1>][,<expB2>
]
[,<expL2>][,<expL3>][,<expC5>]
Picklist window function.
PUTKEY( <expN> )
Places a keystroke in the BIOS keyboard buffer.
READGETS( <expA>, <expL>, <expN> )
READs a getlist. Provides cursor change on insert mode.
*REC_LOCK(<expN>)
Record lock function.
*REL_MAINT(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>, ;
<expB1>,<expC2>,<expA>,<expN5>[,<expC3>][,<expB2>])
Child relation file maintenance.
*REQ(<expC1>,<expN1>,<expN2>,<expN3>[,<expC2>])
VALID function to force a GET field to not be empty.
*RGHT_JST([<expC>])
VALID function to right justify input to a GET field.
SAVE_IT(<expC>,<expA>,<expN>,<expL>)
All purpose file I/O routine.
SETMOUSE([<expN1>][,<expN2>])
Get/Set mouse button status. Set up mouse for 'closed'
functions.
SETMSGLIN([<expC>])
Function to Get/Set the application message line.
*SHADOW(<expN1>,<expN2>,<expN3>,<expN4>)
Puts a shadow on a box.
SHOW_MEMO(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>, ;
<expL>[,<expC2>][,<expN5>])
Display/Edit a Memo field without a border or message
line or title.
SHOW_TXT(<exp>,<expN1>,<expN2>,<expN3>[,<expC>])
VALID function to display data after input from a GET.
TEXTVIEW(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>[,<expC2>])
Page: 14
Display a text file.
THERMOMETR(<expN1>,<expN2>,<expN3>,<expN4>)
Creates a thermometer to show the progress of a routine.
TIMEOUT(<expN1>,<expN2>)
Set up an application timeout if idle for a passed
length of time.
*TOTALKEYON()/TOTALKEYOFF()
Enables/Disables drop down menu right and left
scrolling.
VAR(<expN>[,<exp>])
Get and optionally set Aeolus Builder system variables.
*VARINIT()
Initialize Aeolus Builder system variables.
WAITKEY([<expN>])
Works like INKEY(0) but allows SET KEY TO ...'s to be
processed.
WINBOTT()
Returns the top row value for the current window.
WINLEFT()
Returns the left column value for the current window.
*WINPOP()
Remove a window from the screen that was created using
WINPUSH.
*WINPUSH(<expN1>,<expN2>,<expN3>,<expN4>[,<expL1>] ;
[,<expL2>][,<expL3>][<expL4>])
Put a window on the screen, may be saved for later
removal.
WINRIGHT()
Returns the right column value of the current window.
WINSTYLE(0
Returns the window style string for the current window.
WINTOP()
Returns the top row value for the current window.
* Functions preceded by an asterisk (*) are either dealt
Page: 15
with entirely by BUILDER generated code or are called by
another library function. You will probably never need to
use these and are included for the sake of completeness.
++ Functions preceded by this symbol are obsolete when
except for Summer '87 style code.
Page: 16
@..ABPROMPT ... / @..WINPROMPT ...
Syntax:
@ <row1>,<col1> ABPROMPT <expC1> TO <expA> ;
[EXECUTE <exp>] ;
[WHEN <expL>] ;
[MESSAGE <expC2> AT <row2>,<co2l>]
Description:
The ABPROMPT and WINPROMPT work identically except for
the screen row and column coordinates. ABPROMPT
takes actual screen coordinates and WINPROMPT uses
window offsets. A window offset is a screen
coordinate that positions the menu prompt as if the
upper left corner of the window were screen
coordinate 0,0. Therefore positioning a menu pad,
using WINPROMPT, at coordinate 01,01 would place in
on the top left of the current window.
In both places where they appear the <row> and <col>
symbols mean screen row and column. Use this
command instead of the Builder AddPrompt() function.
The command is preprocessed to call AddPrompt().
<expC1> will be displayed/used as a menu pad at <row1>,
<col1>. The menu array will be stored in <expA>.
<exp> will be executed whenever the menu pad <expC1> is
selected. The menu pad will only be selectable when
<expL> returns .T..
When the menu pad is highlighted <expC2> will be
displayed at <row2>, <col2>.
See AddPrompt(), Menu()
Page: 17
@..GET / @..WINGET
Syntax:
@ <row>, <col> GET <var> [normal getclauses] ;
[VALIDBLOCK <expB>]
-OR-
@ <row>,<col> GET <var> USING MENU <expA>
-OR-
@ <row>,<col> GET <var> USING DROPDOWN <expA>
Description:
The @..GET and @..WINGET work identically except for
the screen row and column coordinates. @..GET takes
actual screen coordinates and @..WINGET uses window
offsets. A window offset is a screen coordinate
that positions the GET as if the upper left corner
of the window were screen coordinate 0,0. Therefore
positioning a GET, using WINGET, at coordinate 01,01
would place in on the top left of the current
window.
The differences between a Clipper GET and a Builder
GET/WINGET are very small. Besides using @..WINGET
window offsets there are only two differences. You
may use the VALIDBLOCK clause instead of the VALID
to pass a codeblock as a valid condition for a
GET/WINGET. And you may use the USING MENU or USING
DROPDOWN clauses. Note, however, if either USING
MENU or USING DROPDOWN is used it is the only GET
clause allowed. In other words, if you use one of
them, you may not use VALID, COLOR or any other GET
clause.
The USING MENU clause is unique to Builder. Simply
pass a one dimensional array of character strings as
the argument to this clause to create a 'Menu GET'.
The USING MENU mechanism will read the data type of
the GET variable (must be Character or Numeric) and
set the GET variable accordingly.
The USING DROPDOWN clause works similarly to USING MENU
in that you pass a one dimensional array of
character strings to use as prompt values. The
difference is that the USING DROPDOWN will create a
drop down listbox and the <var> MUST be a numeric
value. The up/down arrow keys will not move the
Page: 18
focus from this type of GET but instead will move among the
array elements, display each as up and down arrows are
entered. Also the alt+down arrow key combination will
display the available options in a list format.
Page: 19
@..WINSAY ...
Syntax:
@ <row>, <col> SAY [sayclauses]
Description:
The @..WINSAY works exactly like the Clipper @..SAY
command except for the screen row and column
coordinates. @..SAY takes actual screen coordinates
and @..WINSAY uses window offsets. A window offset
is a screen coordinate that positions the SAY as if
the upper left corner of the window were screen
coordinate 0,0. Therefore positioning a SAY, using
WINSAY, at coordinate 01,01 would place in on the
top left of the current window.
Page: 20
@....WINDOW ...
Syntax:
@ <top>,<left>,<bottom>,<right> WINDOW ;
[NOSAVE] [NOCLEAR] [NOSHADOW]
[NOBORDER] [STYLE <expC1>]
[COLOR <expC>]
Description:
The Builder @....WINDOW command places a new window on
the screen at the <top>,<left>,<bottom>,<right>
screen coordinates. The screen area used is saved
so that the next WINDOW REMOVE command will restore
the screen unless the NOSAVE clause is used. The
interior of the window is cleared (spaces displayed)
unless the NOCLEAR clause is used. A shadow will be
placed on the bottom and right edges of the window
unless the NOSHADOW clause is used. A border is
placed on the window unless the NOBORDER clause is
used. The window border style will be the current
default [Var( WNDW_STYLE ) ] unless the STYLE clause
is used. The color of the window will be the
current default unless the COLOR clause is used.
Pass a Clipper color string as an argument to this
clause.
STYLE clause values should be passed as the manifest
constants located at the beginning of the Builder.ch
include file. These are:
W_DOUBLE - Double border
W_SINGLE - Single border
W_DOUBLE_SINGLE - Double horizontal, single vertical
W_SINGLE_DOUBLE - Single horizontal, double vertical
W_3D_PLUS - 3d pulling out of screen
W_3D_MINUS - 3d pushing into screen
Or any two characters, the first character will be used
as the horizontal window edge, and the second the
vertical.
See WinPush()
Page: 21
ABGOBOTTOM()
Syntax:
AbGoBottom(<expO>)
Pass:
<exp> - a TBrowse object.
Returns:
NIL always.
Description:
This functions should be used as the :goBottomBlock
code block on a Builder TBrowse. It will use the
"BOUNDS" and "BNDKEYS" dictionary elements, if
needed, when executing a :goBottom() method.
Page: 22
ABGOTOP()
Syntax:
AbGoTop( <expO>)
Pass:
<expO> - a TBrowse object.
Returns:
NIL always.
Description:
This functions should be used as the :goTopBlock code
block on a Builder TBrowse. It will use the
"BOUNDS" and "BNDKEYS" dictionary elements, if
needed, when executing a :goTop() method.
Page: 23
ABTBSKIP()
Syntax:
AbTbSkip(<expN>,<expO>)
Pass:
<expN> - Number of records to skip, pass as a negative
number to skip backwards.
<expO> - TBrowse object whose :cargo dictionary should
be used.
Returns:
A numeric value of the number of records actually
moved. The return value will be negative if
backward movement occurred.
Description:
This function should be used as the :skipBlock code
block for Builder TBrowses. It will use the
"BOUNDS" and "BNDKEYS" dictionary elements, if
needed, for all database movement.
Page: 24
ADD_REC()
Syntax:
add_rec(<expN>)
Pass:
<expN> seconds until timeout, zero for no timeout.
Returns:
a logical expression.
Description:
Attempts to add a blank record to the currently
selected database for timeout period of <expN>
seconds. If a record cannot be added after the
timeout period an error box is presented to try
again, if No is selected, a logical false is
returned. If <expN> is zero or not passed to the
function, ADD_REC() will wait indefinitely.
Comment:
This function is called by the SAVE_IT() function
therefore it should never need to be used by you in
a program, use the SAVE_IT() function to do file I/O
instead. It is included here only for complete
ness.
Page: 25
ADDGET()
Syntax:
ADDGET(<expN1>,<expN2>,<expB1>,<expC1>[,<expC2>][,<e
xpB2>] ;
[,<expB3>][,<expB4>])
Pass:
<expN1> - Screen row for GET.
<expN2> - Screen column for GET.
<expB1> - Code block to return value of GET var and
set GET var, you may use the MemVarBlock()
function here.
<expC1> - GET variable name.
<expC2> - PICTURE string.
<expB2> - Code block to perform VALID for GET.
<expB3> - Code block to perform WHEN for GET.
<expB4> - Code block of alternate GET reader.
Returns:
NIL always
Description:
The BUILDER ADDGET() function does exactly the same
thing as the Clipper @...GET statement with the
addition of allowing the alternate GET reader code
block.
Note that BUILDER will create ADDGET()'s instead of
@...GETs when generating non-Summer '87 code.
Page: 26
ADDMPAD()
Syntax:
ADDMPAD(<expN1>,<expN2>,<expN3>,<expN4>,<expN5>,<expB>)
Pass:
<expN1> - Upper left row screen coordinate.
<expN2> - Upper left column screen coordinate.
<expN3> - Bottom right row screen coordinate.
<expN4> - Bottom right column screen coordinate.
<expN5> - 1 or 0, for left mouse button press or
release.
<expB> - Code block to execute.
Returns:
A numeric expression indicating the Mouse Pad Index
number.
Description:
The ADDMPAD() function add a mouse 'hot spot' to the
screen. If the left mouse button is activated
within the passed screen coordinates, <expB> is
evaluated.
If <expN5> is passed as 0 (zero), <expB> is evaluated
when the left mouse button is released. If <expN5>
is passed as 1 (one), <expB> is evaluated repeatedly
while the left mouse button is pressed.
Be sure to save the return value, without it you cannot
deactivate the mouse 'hot spot'!
See: DELMPAD(),MOUSEINIT(),SETMOUSE()
Page: 27
*ADDPROMPT()
Syntax:
ADDPROMPT(<expA>,<expN1>,<expN2>,<expC1>[,<expB>][,<
expN3>] ;
[,<expN4>][,<expC2>])
Pass:
<expA> - Array to append.
<expN1> - Screen row to display prompt.
<expN2> - Screen column to display prompt.
<expC1> - Prompt text.
<expB> - Code block to execute when this menu prompt
is selected.
<expN3> - Screen row to display prompt message.
<expN4> - Screen column to display prompt message.
<expC2> - Message text to display when prompt is
highlighted.
Returns:
NIL always.
Description:
The ADDPROMPT() function is similar to the Clipper
@...PROMPT command. See any BUILDER generated
source for ADDPROMPT() examples.
See: MENU(),CRTMNUARRY()
Page: 28
APOP()
Syntax:
apop(<expN1>,<expN2>,<expN3>,<expN4>,<expA>,<expN5> ;
[,<expC1][,<expC2>])
Pass:
<expN1> top left row.
<expN2> top left column.
<expN3> bottom right row.
<expN4> bottom right column.
<expA> array name (prefixed with @).
<expN5> max element to show.
<expC1> alternate color choice.
<expC2> alternate reverse color choice.
Returns:
Nothing.
Description:
The APOP() function will put a box on the screen using
<expN1> through <expN4> as screen coordinates and
allow you to scroll through elements 1 to <expN5> of
the array <expA>. When a selection is made by
pressing the 'T' or ENTER key. That element will be
tagged and displayed with a check mark in front (û).
<expC1> is an optional color value, <expC2> is an
alternate reverse color option. Defaults for
<expC1> and <expC2> are the current colors.
Upon return from APOP() check the first character of
each array element for Chr(251) for tagged elements.
Sample:
** APOP() example code to allow the selection of
multiple
** names from a list and then display the selected
items.
**
Names := {"Rosa
lind","Mark","John","Lisa","Amy","Jeff","Cathy
", ;
"Jordan"}
** call APOP()
Apop(05,05,13,18,@Names,10)
** the check character -Chr(251)- is left on the
array elements that have
** been selected, so if it is in the first character
Page: 29
position, that element was
** selected by the user.
For j := 1 to Len(Names)
If Left(Names[j],1) == Chr(251)
? Substr(Names[j],2)+" Was Selected."
Endif
Next
Page: 30
ASC2BIN()
Syntax:
ASC2BIN(<expC>)
Pass:
<expC> string with control character expressions
embedded.
Returns:
Character expression. The converted string.
Description:
The ASC2BIN() function converts a character expression
that contains one or more caret (^) symbols followed
by a character to it's 'control' or binary value.
Use this function for creating printer control
strings. For example :
c := ASC2BIN("^A") // caps important !]
? asc(c) // would display the number 1
Sample:
***********************************************
** print a message on a laser printer in
** landscape using HP escape sequence
prtrt := "^[&l0O" // caret, left bracket (escape),
// ampersand, lower case L, zero,
// upper case O
lndscp := "^[&l1O" // caret, left bracket (escape),
// ampersand, lower case L, one,
// upper case O
set print on
?? asc2bin(lndscp) // set printer to landscape
? "This text printed using landscape."
?? asc2bin(prtrt) // set printer back to portrait
set print off
Page: 31
ASK()
Syntax:
ASK(<expC1>,<expC2>,<expN1>,<expN2>[,<expN3>][,expC3
][,<expC4>])
Pass:
<expC1> prompt text.
<expC2> list of acceptable input characters.
<expN1> row for prompt.
<expN2> column for prompt.
<expN3> pad prompt to length.
<expC3> alternate color.
<expC4> "ESC" to allow ESC key.
Returns:
Character expression. The keyboard character pressed.
Description:
<expC1> will be displayed at row <expN1> and column
<expN2>. ASK() will wait until any keyboard
character contained in the list <expC2> is pressed.
<expC2> may be passed in upper or lower case, ASK()
does not distinguish. If you pass "YN" either a
lower or upper case 'Y' key press will return an
upper case "Y" from ASK(). Also if you pass "yn"
either a lower or upper case 'Y'key press will
return an upper case "Y".
<expN3> spaces will be displayed before the message in
<expC1> to clear previous text, optional. default
is the length of <expC1>.
<expC3> is color to display <expC1>. Default is
current color.
If <expC4> is equal to "ESC" then ASK() can be exited
using the ESC key. If the ESC key is used to exit
ASK() a null string will be the return value. The
default is to not allow ESCaping.
Sample:
**********************************************
*******
** display the question on line 24 column 0 and pad
** the text to 80 characters. Wait until a Y or N
** is pressed on the keyboard.
Page: 32
cAnswer := Ask("Do You Wish to Continue?
(Y/N)","YN",24,0,80)
IF cAnswer == "Y"
? "You do wish to continue"
ELSE
? "You do not wish to continue"
ENDIF
** the character variable "answer" will equal either
"Y"
** or "N" depending on what the key is pressed.
Page: 33
ASKMENU()
Syntax:
ASKMENU(<expC1>,<expA>,<expN1>,<expN2>[,<expN3>][,ex
pC3] ;
[,<expC4>])
Pass:
<expC1> prompt text.
<expA> array of menu prompts.
<expN1> row for prompt.
<expN2> column for prompt.
<expN3> pad prompt to length
<expC3> alternate color.
<expC4> "ESC" to allow ESC key.
Returns:
Character expression. The unique (highlighted)
character of the menu prompt selected. The returned
character will always be in upper case. A space
character is return if ESC is pressed.
Description:
<expC1> will be displayed at row <expN1> and column
<expN2> immediately followed by each of the menu
prompts contained in <expA>. ASKMENU() will wait
until a prompt is selected by a press of the ENTER
key or a click of the left mouse button.
<expN3> spaces will be displayed before the message in
<expC1> to clear previous text, optional. default
is the length of <expC1>.
<expC3> is the color to display <expC1> and the menu.
The default is the current color.
If <expC4> is equal to "ESC" (case important) then
ASKMENU() can be exited using the ESC key. If the
ESC key is used to exit ASKMENU() a space character
will be the return value. The default is to not
allow ESCaping.
Sample:
**********************************************
*******
** display the question on line 24 column 0. Wait
** until an answer is selected.
LOCAL cAnswer
Page: 34
cAnswer := AskMenu("Do You Wish to Continue?", ;
{"Yes,"No"},24,0)
** the character variable "Answer" will equal either
"Y"
** or "N" depending on what option is selected.
Page: 35
BCHOICE()
Syntax:
BChoice(<expN1>,<expN2>,<expN3>,<expN4>,<expA>
[,<expC>][,<expN5>][,<expL>])
Pass:
<expN1> - Top screen row.
<expN2> - Left screen column.
<expN3> - Bottom screen row.
<expN4> - Right screen column.
<expA> - Array of choices.
<expC> - Title to display. Default none.
<expN5> - Initial element to highlight. Default 1.
<expL> - Remove window on function exit.. Default
true.
Returns:
A numeric value of the element selected. Returns
zero if ESC was pressed.
Description:
The Builder BChoice() function works very similar to
the Clipper AChoice() function. The differ
ence is that BChoice() will accept mouse input
and AChoice() will not.
Page: 36
BETWEEN()
Syntax:
between(<exp1>,<exp2>,<exp3>)
Pass:
<exp1> value to test.
<exp2> minimum value.
<exp3> maximum value.
Returns:
A logical expression.
Description:
A logical true will be returned if <exp1> is greater
than and equal to <exp2> and less than and equal to
<exp3>. The arguments passed to the BETWEEN()
function may be of type Character, Numeric or Date;
however all three arguments must be the same data
type.
Page: 37
BLDRERR()
Syntax:
BldrErr( <expO>, <expC> )
Pass:
<expO> - Clipper error object.
<expC> - Determines where error output goes.
Returns:
A logical false always.
Description:
The BldrErr() function can be posted using the Clipper
ErrorBlock() function. The Builder error system can
post error information to a database file
(BLDRERR.DBF) or the screen. In both instances the
message box where the original error message appears
can be cleared by mouse input, using the Clipper
error system will not allow mouse inputs. Pass
<expC> as the literal value "FILE" to send output to
the BLDRERR.DBF database or as "SCREEN" to send
error output to the screen. In either case more
information is provided than the Clipper error
system and it is displayed in a more presentable
manner.
Page: 38
BROWSEDB()
Syntax:
BrowseDb(<expO>/<expA>[, <expL>] )
Pass:
<expO>/<expA> - a TBrowse object or an array of
TBrowse objects to execute.
<expL> - TRUE (default) to hilight the browse window
with input focus.
Returns:
a logical value. True is returned if Ctrl+Enter is
used to exit the TBrowse. False is returned if ESC
is pressed to exit the TBrowse.
Description:
Calls to the BrowseDb() function are normally created
by Builder. These calls can be modified by passing
an array of TBrowse objects. Passing more than one
browse object will cause all the TBrowse objects to
be stabilized and active at once. The Alt+PgDn and
Alt+PgUp keys will be activated to move from one
browse to the next. Inactive browses can also be
selected with a mouse click. Use caution when doing
this so that the browse windows tile onto the
screen, if they overlap they will mess up the
screen. In using the multi-browse you will probably
want to issue a SET RELATION ... Clipper command
before the BrowseDb() call.
Page: 39
BROWSER()
Syntax:
browser(<expN1>,<expN2>,<expN3>,<expN4>[,<expC>] ;
[,<expN5>][,<expN6>]
Pass:
<expN1> top left row.
<expN2> top left column.
<expN3> bottom right row.
<expN4> bottom right column.
<expC> key exception function name.
<expN5> start field number.
<expN6> end field number.
Description:
The BROWSER function will "browse" the currently
selected database using the Clipper DBEDIT()
function. <expN1> through <expN4> define the
coordinates of the box that will be displayed,
<expC> is the user defined function executed on each
key press. <expN5> and <expN6> are the start and
end field numbers (i.e. the FCOUNT() number) to
browse. If <expN5> is not passed the first field
will be browsed. If <expN6> is not passed the
<expN5>th through FCOUNT() fields will be browsed.
For more information on using the <expC> user defined
function consult your Clipper manual on the DBEDIT()
function. <expC> is merely passed to DBEDIT() as
the UDF for each key press.
Sample:
**********************************************
********
** BROWSER sample call
**
USE Customer NEW
Browser(5,3,17,73)
** this will put a box on the screen from row 5
column 3 to row
** 17 column 73 and browse all the fields in the
database
** CUSTOMER.
Note that this function is obsolete and you should
create TBrowse windows in Builder instead
Page: 40
BRWMOUSE()
Syntax:
BrwMouse( <expN1>, <expN2>, <expN3>, <expN4>, <expO> )
Pass:
Either:
<expN1> - Top screen row.
<expN2> - Left screen column.
<expN3> - Bottom screen row.
<expN4> - Right screen column.
<expO> - a TBrowse object.
Or nothing
Returns:
NIL always.
Description:
The BrwMouse() function adds and removes the mouse pads
to a Builder TBrowse. Builder normally creates the
call to this function. The first four parameters
are the window window border coordinates, and the
last parameter is the TBrowse object. If no
parameters are passed, the last set of mouse pads
are removed.
Page: 41
CENTER()
Syntax:
center(<expC1>,<expN1>,<expN2>,<expN3>[,<expC2])
Pass:
<expC1> message to display.
<expN1> row to begin centering computation.
<expN2> column to begin centering computation.
<expN3> length for centering computation.
<expC2> alternate color.
Returns:
Start column of centered text.
Description:
The CENTER() function displays <expC1> on row <expN1>
column <expN2> centered within a width <expN3> wide.
<expC2> is an alternate color choice. The default
color is the current from the last SET COLOR TO . .
. statement.
Sample:
****************************************************
** CENTER() function example
**
** put a box on the screen
@ 5, 5, 15, 45 WINDOW STYLE "3+"
** center text in the box
Center("Yoo Hoo, I'm Centered",
WinTop()+2,WinLeft()+1,29)
Waitkey()
** remove box
WINDOW REMOVE
Page: 42
CHGDIR()
Syntax:
chgdir(<expC>)
Pass:
<expC> - a DOS subdirectory name on the current
drive.
Returns:
A numeric value indicating a DOS error code.
Description:
The CHGDIR assembly subroutine simply attempts to
change to the subdirectory named in the passed
parameter <expC>.
One of the following will be returned:
0 - No error occured
1 - Invalid function number
2 - File not found
3 - Path not found
4 - Too many open files (no handles left)
5 - Access denied
6 - Invalid handle
7 - Memory control blocks destroyed
8 - Insufficient memory
9 - Invalid memory block address
10 - Invalid environment
11 - Invalid format
12 - Invalid access mode (open mode is invalid)
13 - Invalid data
14 - Reserved
15 - Invalid drive specified
16 - Attempt to remove current directory
17 - Not same device
18 - No more files
Page: 43
CHGDSK()
Syntax:
chgdsk(<expC>)
Pass:
<expC> - A single byte indicating the disk drive
letter to set as the new default drive.
Returns:
A numeric value indicating a DOS error code.
Description:
The CHGDSK assembly subroutine simply attempts to
change the default DOS disk drive to the passed
drive letter parameter <expC>. If a number greater
than zero is returned, then a DOS error has occured.
See the CHGDIR() function in this manual for a list
of possible DOS error codes.
Page: 44
CHKCHR()
Syntax:
chkchr(<expC1>,<expC2>,<expN1>,<expN2>,<expN3>,[<exp
C3>])
Pass:
<expC1> - A list of allowable entry data into the
GET.
<expC2> - Error message on entry of non-allowable
data.
<expN1> - Row for error message to display.
<expN2> - Column for error message display.
<expN3> - Rightmost column for error message display.
<expC3> - Optional color for error message. default
WERR_CLR.
Returns:
A logical expression.
Description:
This function is designed to be use as a VALID function
to a GET only. It will test if the data keyed into
the GET is embedded in the <expC1> string. If it
is, the GET is allowed otherwise an error beep is
sounded and the error message <expC2> is displayed
at screen row <expN1> column <expN2> and will be
padded or truncated to screen column <expN3>. If
<expC3> is passed as a parameter the error message
will be displayed using it as the color value,
otherwise the color contained in the public memory
variable WERR_CLR will be used.
Samples:
** cType is a one byte variable with allowable
values of 1, 2, or 3
** only. Use ChkChr() to force a 1, 2, or 3 into
this field like this ...
cType := " "
@ 02,21 WINGET cType PICTURE "9" VALID ;
ChkChr("123","1, 2, 3 Only Allowed",WinBott()-
1,WinLeft()+2,WinRight()-2)
SET CURSOR ON
READ
SET CURSOR OFF
** Same example, but allow cType to be blank. Just
add a
** space as an allowable character in the list!
Page: 45
cType := " "
@ 02,21 WINGET cType PICTURE "9" VALID ;
ChkChr(" 123","1, 2, 3 or Blank
Only",WinBott()-1,WinLeft()+2,WinRight()-2)
SET CUROSR ON
READ
SET CURSOR OFF
If QTYPE (or whatever field) is more than one character
long, be sure to use a separator between allowable
field values.
** cType2 allowable values are "EA" for Each, "PK"
for
** Package, or "WT" for Weight.
** You can use ChkChr() in the following manner to
** force the field cType2 to be one of these
values...
cType2 := " "
@ 02,21 WINGET cType2 PICTURE "!!" VALID ;
ChkChr("EA~PK~WT","Enter EA-Each, PK-Package,
or WT-Weight", ;
WinBott()-1,WinLeft()+2,WinRight()-2)
Note though that if the user entered "A~" or "~P"
ChkChr() would allow it. You may choose to use a
separator that cannot be entered from the keyboard,
however, I cannot foresee a user accidentally
stumbling onto the tilde condition.
Page: 46
CKPRTR()
Syntax:
ckprtr([<expN>])
Pass:
nothing or 1, 1 if ESCaping is allowed.
Returns:
a logical expression.
Description:
The CKPRTR() function returns a logical true if the
Clipper ISPRINTER() function returns a logical true.
CKPRTR() displays an error box if ISPRINTER()
returns false and checks the ISPRINTER() function
again after a key is pressed.
You can see that an infinite loop will be created if
the printer cannot be brought on-line, if <expN> is
a value of one (1) then the ESC key will allow an
exit from CKPRTR() when the printer is not operating
and if ESCaped CKPRTR() will return false (.f.).
Sample:
*************************************************
** CKPRTR() function example
PROCEDURE a_report()
SET DEVICE TO PRINTER
DO WHILE !EOF()
IF !CkPrtr(1) && check printer on each
print line
EXIT
ENDIF
.
print report commands .
.
ENDDO
>>COMMENT:
The CKPRTR() function will only work with parallel
printers.
Page: 47
CRTMNUARRY()
Syntax:
CRTMNUARRY(<expN1>,<expN2>,<expA>)
Pass:
<expN1> - Screen row to display menu.
<expN2> - Starting screen column to display menu.
<expA> - Array of menu prompts.
Returns:
An array that can be passed to the ABMENU() function.
Description:
This can be used instead of several ADDPROMPT()'s. It
only creates menus on one screen row where the menu
highlight moves left and right. It is used
primarily when creating menus within a GET stream.
See the BUILDER manual section on entering the @MENU
Picture clause.
See: ADDPROMPT(), ABMENU()
Page: 48
DBCHANGED()
Syntax:
dbchanged(<expA>)
Pass:
<expA> - Array of values to compare to database
fields.
Returns:
A logical value.
Description:
The DBCHANGED() function returns true (.T.) if any of
the database field values are different from the
memory variables, otherwise false (.F.) is returned.
See DBSTOR
Page: 49
DBREPL()
Syntax:
dbrepl(<expA>)
Pass:
Array of values to be entered into database fields.
Description:
DBREPL replaces all the field variables in a record
using array elements from <expA> that have exactly
the same ordinal position as the field variables.
See DBSTOR and SAVE_IT().
Sample:
***************************************************
** DBREPL example
**
** a database with the following structure is
assumed
**
** FNAME Character 15
** LNAME Character 20
** ADDRESS Character 35
** PHONE Character 10
**
Local aAddrBook := {}
Use AddrBook New
DbStor( aAddrBook, "EMPTY" )
** declares mfname,mlname,maddress,mphone as memory
vars
aAddrBook[1] := "DENISE"
aAddrBook[2] := "JOHNSON"
aAddrBook[3] := "123 MAPLE ST"
aAddrBook[4] := "6125551234"
Append Blank // add a blank record
DbRepl( aAddrBook ) // replace all field vars.
Page: 50
DBSTATE()
Syntax:
dbstate([<expC>])
Pass:
Nothing or a string returned from a previous DBSTATE()
function call.
Returns:
A string of the complete state of the currently
selected database. Select area, record number,
index order number, filter expression, and all
relation information.
Description:
DBSTATE() saves all the information possible for the
currently selected work and returns it to the
program in a single character string. Passing a
string saved from a previous DBSTATE() call as
<expC> will set the work area of that DBSTATE()
string to the state it was in.
This function is very useful when you want to preserve
the current database conditions exactly but you also
need to use the same database for another purpose.
WARNING: DBSTATE() CANNOT be used on a database using
the "DBFMDX" or "DBPX" RDDs!!
Sample:
SELECT A_Database
cDbState := DbState() // save state of A_DATABASE
** change state of A_DATABASE
A_Database->( DBSETORDER( 3 ) )
SET FILTER TO The_Field == "A"
SET RELATION TO
A_Database->( DBGOTOP() )
SELECT Another
DbState( cDbState ) // selects A_DATABASE and puts it
in the
// state it was in on the first DBSTATE()
// call.
Page: 51
DBSTOR()
Syntax:
dbstor(<expA>[,<expC>])
Pass:
<expA> Array with the same length as fCount() would
return in the current work area.
<expC> nothing for data or "EMPTY" for empty values.
Description:
DBSTOR stores all the field variables in a record to
array elements with exactly the same ordinal
position as the field variables in the current work
area.
If <expC> is passed as "EMPTY" then all memory
variables will be assigned as if the record were
blank.
See DBREPL and SAVE_IT().
Sample:
***************************************************
** DBSTOR example
**
** a database with the following structure is
assumed
**
** FNAME Character 15
** LNAME Character 20
** ADDRESS Character 35
** PHONE Character 10
LOCAL aAddrBook := {}
USE AddrBook NEW
** declares mfname,mlname,maddress,mphone as public,
you must
** do this in order to use DBSTOR
DbStor( aAddrBook, "EMPTY" ) // create 'blank'
vars
CLS
@ 0,0 SAY "First Name" GET aAddrBook[1] PICTURE "@!
@ 1,0 SAY "Last Name" GET aAddrBook[2] PICTURE "@!"
@ 2,0 SAY "Address" GET aAddrBook[3] PICTURE "@!
@ 3,0 SAY "Phone" GET aAddrBook[4] PICTURE "@R (999)
999-9999"
READ
Page: 52
Append Blank // add a blank record
DbRepl( aAddrBook ) // replace all field vars.
Comment:
<expC> should be kept as short as possible otherwise
the uniqueness to your field variables can be lost,
I suggest a length of one, two as an absolute
maximum.
Page: 53
DEC2HEX()
Syntax:
dec2hex(<expN>)
Pass:
A numeric integer value.
Returns:
A character string of the hexadecimal value of the
passed integer.
Description:
This function is the compliment to the HEX2DEC()
function. If you have a need to convert numbers to
hexadecimal, you will find this function useful.
Page: 54
DELCOLPUT()
Syntax:
DelColPut(<expO>,<expN>)
Pass:
<expO> - a TBrowse object.
<expN> - the TBrowse column number to remove.
Returns:
NIL always.
Description:
Use this function in a Builder TBrowse procedure after
the TBrowse object has be completely created but
before the BrowseDb() function is called. Use it to
remove columns from the TBrowse and place them in
the 'recoverable' columns list. That way you can
have columns available to users of your TBrowse but
not have them cluttering up the initial set of
available columns.
Page: 55
DICTGET()
Syntax:
DictGet(<expA>,<expC>,<exp>)
Pass:
<expA> - a two dimensional dictionary array created by
the DictPut() function.
<expC> - a dictionary identifier.
<exp> - the reutrn return value to use if <expC>
is not found.
Returns:
The value found in the dictionary that corresponds with
<expC> or <exp> if <expC> cannot be found.
Description:
The DictGet() function is used by BrowseDb() to get
additional information about Builder TBrowses placed
there by the DictPut() function. A two dimensional
dictionary array is placed on every Builder TBrowse
and TBColumn object :cargo instance variable and
contains the information needed for the added
functionality of Builder TBrowses.
Page: 56
DICTPUT()
Syntax:
DictPut(<expA>,<expC>,<exp>)
Pass:
<expA> - An empty array or a two dimensional
dictionary array already seeded by DictPut().
<expC> - an element key or index value.
<exp> - the value to associate with <expC>.
Returns:
An updated dictionary array.
Description:
Dictput adds <expC> and <exp> to <expA> if <expC> was
not located in the input array otherwise <exp> is
updated in the array.
A dictionary array can be used for many purposes,
Builder creates dictionary arrays and places them in
the :cargo instance variable of TBrowse and TBColumn
objects for adding to their functionality.
The Builder BrowseDb() function reads the following
dictionary elements from TBrowse and TBColumn
objects:
These are initialized by Builder and will probably not
require any change on your part:
FREEZE DELETE AWIDTH
CHGORD IDXSRC APPEND
APPVAL RECNBR RECTGL
DELREC BNDFLD HGLTBAR
BNDKEYS ALIAS ORDER
DELINDX
These are added with a NIL value and are only set by
making changes to the generated source code:
BNDPFX ORDEXCPT KYHNDLR
BNDPFX - Used if the TBrowse is a bounded list. The
BNDPFX value should be set to that portion of the
index key that preceeds the bounded by field
(BNDFLD). This is only needed when the index search
option is turned on.
ORDEXCPT - Array - This is used to exclude items from
the index change menu. When the index change menu
Page: 57
is selected from a Builder TBrowse, all indexes are
displayed for selection except those in the one
dimensional array set as this dictionary element.
KYHNDLR - Codeblock - If used the codeblock will be
executed after a keyboard key has been pressed but
before the keystroke has been applied to the browse.
Two parameters are passed to the user defined key
handler: the browse object, and the INKEY() value of
the keypress. The key handler must return a numeric
value. If zero (0) is returned, the Builder key
handler will be called to process the key, return
one (1) and the Builder key handler will be
bypassed, return two (2) to exit the TBrowse.
Page: 58
DELMPAD()
Syntax:
DELMPAD(<expN>)
Pass:
Mouse pad index (return value of ADDMPAD())
Returns:
Logical true if successful, false if failed.
Description:
Use DELMPAD() to deactivate a mouse 'hot spot'.
See: ADDMPAD()
Page: 59
DRVTST()
Syntax:
DRVTST(<expC>)
Pass:
<expC> - Floppy drive letter to test.
Returns:
Numeric indicator of disk error.
Description:
DrvTst() tests a floppy drive to see if it is available
and ready. Only floppy drives can be tested with
this function. The BIOS error code returned is as
follows:
0 - No error
1 - Invalid drive or hard drive
2 - Bad sector
3 - Diskette write protected
4 - Sector not found
8 - DMA overrun
9 - DMA access across 64k boundary
12 - Invalid media
16 - ECC/CRC error on disk read
32 - Controller error
64 - Seek failure
128 - Time out, drive not ready
255 - Sense operation failed
Note to OS/2 users, this function will not operate in
an OS/2 VDM. It will cause your system to crash,
the DOS session AND OS/2!
Page: 60
DUPCHK()
Syntax:
dupchk(<expC1>,<exp>,<expN1>,<expC2>,<expN2>,<expN3>
,<expN4>, ;
<expL>[,<expC3>])
Pass:
<expC1> - either "A" to check if the Addition of a
record will cause a
duplicate, or "C" to check if Changing the
record will cause a
duplicate.
<exp> - Key value to duplicate check.
<expN1> - Index order number for duplicate check.
<expC2> - Error message to display.
<expN2> - Screen row to display error message.
<expN3> - Screen column to display error message.
<expN4> - Rightmost screen column to display error
message.
<expL> - GET is required (.T.) or may be blank
(.F.).
<expC3> - Color to display error message, default is
WERR_CLR.
Returns:
A logical value, this function is to be used as a VALID
for a GET only.
Description:
The DUPCHK() valid function tests the value entered
into a GET field to see if it will cause a duplicate
record when saved.
This function is useful when two indexes are maintained
on a single database and both keys must not contain
duplicates.
If you are using GEN_MAINT or REL_MAINT pass G_FUNC as
<expC1> as it will contain "A" on Adds and "C" on
changes.
The 2nd parameter (<exp>) should (almost has to)
include the GET memvar somewhere within it.
Sample:
Let's say you have a file maintenance routine of
customer information. This file has a primary key
of customer number which is a unique number your
Page: 61
company assigns to each customer. One of the fields in your
customer information file is a serial number which is the
serial number of the product your company sold them. Since
no two customers can possess the same product at the same
time you would like to make sure all the product serial
numbers entered into the database are unique.
This is a situation where DUPCHK() could be used
effectively.
Let's now assume the system you designed contains a
file called CUSTOMER containing the customer
information and index order number three (3) is on
the a field called SERIAL_NBR.
You could program DUPCHK() to make sure inventory items
are never keyed duplicated in the customer file as
follows:
Other file maintenance GETs.
.
.
.
@ WinTop()+05,WinLeft()+22 GET cSerial_Nbr VALID ;
DupChk(cG_Func, "CUSTOMER",cSerial_Nbr,3, ;
"ERROR: Serial Number Already in
Use",WinBott()-1,WinLeft()+2,WinRight()-2,.t.)
The DUPCHK() Valid above would force entry into the
SERIAL_NBR field to be unique. The error message
would be displayed if the field were or would create
a duplicate. Because the ninth parameter is set to
true (.T.) the error message would display if the
user attempted to leave the field blank. An error
beep accompanies the error message display and the
user is not allowed to proceed to the next field in
the GET stream.
Note that BUILDER is able to generate DupChk() Valid
function calls.
Page: 62
EDT_MEMO()
Syntax:
edt_memo(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>,<ex
pC2>, ;
<expC3>,<expC4>,<expC5>[,<expN5>][,<expL1>][,<expL2>
]
Pass:
<expN1> - Top row screen coordinate.
<expN2> - Left column screen coordinate.
<expN3> - Bottom row screen coordinate.
<expN4> - Right column screen coordinate.
<expC1> - Memo field memvar.
<expC2> - Memo field database field name.
<expC3> - Memo title.
<expC4> - Color for memo data.
<expC5> - Color for title display.
<expN5> - Maximum lines memo may contain. Default
unlimited.
<expL1> - .F. view only, .T. allow editing. Default
.T.
<expL2> - .F. does nothing, .T. starts editing at the
end of the memo text. Default .F.
Returns:
Nothing.
Description:
EDT_MEMO() Puts a border on the screen, a title on the
top line of the border, Displays an appropriate
message line, and Saves the memo data if Ctrl+W is
pressed. This function may be used as a Valid
function (BUILDER can create the call) or as a stand
alone command.
If used as a Valid function, DO NOT try to GET the memo
field. Issue a GET on a one byte character memvar
and EDT_MEMO() will force the user to press "Y" to
edit the memo data or "N" to bypass the field.
Page: 63
ERRTONE()
Syntax:
errtone([<expN>])
Pass:
Nothing or zero (0) through four (4).
Returns:
Nothing.
Description:
The ERRTONE() function beeps the speaker in one of five
ways, a two tone error beep if no parameters (or
zero) are passed, a short high pitched single tone
if one (1) is passed. Passing a two (2) will make a
two-tone ON indication sound, three (3) will make
the opposite or a two-tone OFF sound. Passing a
four (4) makes a long low error tone.
Page: 64
ETC()
Syntax:
etc(<expC>,<expN1>,<expN2>,<expN3>)
Pass:
<expC> start time of process
<expN1> start value of operation
<expN2> maximum value of operation
<expN3> current value, must be between <expN1> and
<expN2>
Returns:
A character expression.
Description:
The ETC() function will calculate the estimated time to
completion of an iterative process. In order to be
accurate, be sure to use this only in loops that
occur at regular intervals. Looping where some
iterations are longer than others will cause some
very unusual time estimates.
See THERMOMETR()
Sample:
**********************************************
*****************
** ETC() function example to display current
estimated time
** to compete a process.
cStartTime := time()
cOldTime := time()
FOR J := 1 TO 500
IF time() < > cOldTime // Should only
recalculate on time change
@ 1,0 SAY etc(cStartTime,1,500,j)
cOldTime := time()
ENDIF
Waitkey( .25 )
NEXT
Page: 65
FEOF()
Syntax:
feof([<expL>])
Pass:
A Logical Expression or Nothing
Returns:
A logical expression
Description:
The FEOF() function is designed only to be used in
conjunction with the FGETS() function. FEOF()
Returns .T. when end of file is encountered while
reading a file using the FGETS() function.
Before using FEOF() you must first initialize its
internal variables by issuing FEOF(.F.). See the
example code in the description for FGETS().
Page: 66
FGETS()
Syntax:
fgets(<expN>)
Pass:
A file handle of a previously FOPEN()'d or FCREATE()'d
file.
Returns:
Next logical record in a CR/LF delimited file.
Description:
The FGETS() function will attempt to read the next
logical record in a CR/LF delimited file.
Sample:
**********************************************
********
** Sample code to read the AUTOEXEC.BAT file using
the **
** Aeolus FGETS() function. **
**********************************************
********
** Open the AUTOEXEC.BAT file
nHandle := Fopen("C:\AUTOEXEC.BAT")
FEof(.f.) // initialize FEOF()
DO WHILE !FEof()
? FGets( nHandle ) // read next AUTOEXEC record
ENDDO
FClose( nHandle )
Page: 67
FGETSR()
Syntax:
fgetsr(<expN>)
Pass:
A file handle of a previously FOPEN()'d or FCREATE()'d
file.
Returns:
The previous logical record in a CR/LF delimited file.
Description:
The FGETSR() function will attempt to read the previous
logical record in a CR/LF delimited file.
Sample:
**********************************************
********
** Sample code to read the AUTOEXEC.BAT file using
the **
** Aeolus FGETS and FGETSR() functions. **
**********************************************
********
** Open the AUTOEXEC.BAT file
nHandle := Fopen( "C:\AUTOEXEC.BAT" )
FEof( .f. ) // initialize FEOF()
DO WHILE !FEof()
? FGets( nHandle ) // read next AUTOEXEC record
ENDDO
** file pointer is at the end of file, let's use
FGETSR()
** to read and display AUTOEXEC.BAT backwards.
FEof(.f.) // reinitialize FEOF()
DO WHILE !FEof()
? FGetsR( nHandle )
ENDDO
FClose( nHandle )
Page: 68
FIL_LOCK()
Syntax:
fil_lock(<expN>)
Pass:
<expN> seconds to wait before returning false, zero
will not return false.
Returns:
A logical expression.
Description:
The FIL_LOCK() function will attempt to lock a
previously opened .DBF database, if it fails in
<expN> seconds an error box is displayed allowing
the user to try again or abort the operation. If
<expN> is passed as a value of zero then FIL_LOCK()
will wait indefinitely to attempt the lock.
FIL_LOCK returns true if the lock is successful and
false if the lock is unsuccessful.
Note that all other file or record locks will be
rejected while you have a successful FIL_LOCK(), be
sure to UNLOCK the file or close the database so
others on the LAN can use it.
Sample:
**********************************************
********
** Attempt to lock a database previously opened in
shared mode.
**
USE AddrBook SHARED NEW
IF Fil_Lock( 5 )
.
.
.
ENDIF
UNLOCK
Page: 69
FLD_REPL()
Syntax:
fld_repl(<expC>,<exp>[,<expN>])
Pass:
<expC> The name of the field in the currently
selected database to be replaced.
<exp> The value to place in the database field
<expC>
<expN> Timeout seconds if record cannot be locked.
Description:
Use FLD_REPL whenever you need to REPLACE a single
database field. This function will work in a shared
or single user application. Using this function on
single field REPLACEs will allow your application to
be changed from a single to multi-user program
simply by changing the NETWORK system variable from
.F. to .T.!
Sample:
** replace a date field in the currently selected
database
** with today's date - will work if single or multi
user
Fld_Repl( "CURRNT_DT", DATE() )
Page: 70
GEN_MAINT()
Syntax:
gen_maint(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>, ;
<expA>[,<expN5>][,<expN6>][,<expL>][,<expC2>][,<expB>])
Pass:
<expN1> top left row
<expN2> top left column
<expN3> bottom right row
<expN4> bottom right column
<expC1> procedure name suffix
<expA> DbStor() array name
<expN5> fast delete index order number
<expL> .T. to allow duplicates in file
<expC2> menu options to use
<expB1> codeblock to execute after file writes and
just before exit. default none.
<expB2> codeblock to execute when Ctrl+Enter is
pressed. default none.
Description:
The GEN_MAINT function is one of two generic file
maintenance functions included with the function
library and is designed to be used as an all purpose
file maintenance routine.
Before you can call the GEN_MAINT function you must
first code four procedures yourself, GSAYS_????,
GGETS_????, GEDIT_???? and GKEY_????. Where ???? is
the value passed as <expC1>. The GSAYS_????
procedure must contain the screen displays,
GGETS_???? the get's, and GEDIT_???? additional code
performed after a READ command.
Call GEN_MAINT with <expN1> through <expN4> equal to
the screen coordinates required. <expC1> must equal
the suffix portion of the three procedures you
write. <expA> is the array name that contains the
data for each database record to be edited.
Optionally pass <expN5> as the 'fast delete' index
order number. A fast delete index is created by
issuing the following Clipper command:
INDE ON IF(DELE(),"*"," ") TO ...
If <expN5> is not passed or passed with a value of zero
deleted records will accumulate in your database.
Using the fast delete, records marked for deletion
Page: 71
are used as 'add space' so your database doesn't grow
indefinitely. Note that you must use either SET DELETED ON
or SET FILTER TO !DELE() for fast delete to work correctly.
<expL> may be passed as true if duplicate records are
to be allowed. The default is false.
<expC2> is used to tell GEN_MAINT which of the three
basic menu options to use, Add-Change- and/or
Delete. Pass a character string with the first
letter of each of the menu options to allow during
the GEN_MAINT. Passing "AC" for example will only
put "Add", and "Change" on the file maintenance
menu, skipping "Delete" and "Find". Passing a null
string ("") will only allow "Find". The default is
"ACD" if this is parameter is not passed.
<expB> is a code block function to be executed on every
file "Add", "Change", or "Delete" and before the
File Maintenance isexited. A character parameter is
passed to this function indicating the action that
has taken place "A" for Add, "C" for Change, "D" for
Delete and "E" for Exit. You must return a logical
value from this function. The return value is NOT
checkedfor Adds, Changes, or Deletes. However, on
Exit if the return value is false (.F.) then the
user will not be allowed to exit the file mainte
nance.
You can create your own sample calls to GEN_MAINT by
creating file maintenance windows in BUILDER.
Sample:
#Define ASLS_NBR aTcsReps[1]
#Define ALNAME aTcsReps[2]
#Define AFNAME aTcsReps[3]
#Define APHONE aTcsReps[4]
Func Fmnt_Exmpl()
Local aTcsReps := {}
LOCAL nTop, nLeft, nBott, nRight
** func to call a generic maintenance routine
**
nTop := 04
nLeft := 30
nBott := 12
nRight := 67
SELECTY TCSREPS
aTcsReps := Array(FCount())
Page: 72
Gen_Maint(nTop,nLeft,nBott,nRight,"REPS",aTcsR
eps,.f., ;
"AC",{|x|TestFunc(x)})
** since the 8th parm is "AC" only Adds and
Changes will be allowed
** screen SAY's for generic maint of sales rep file
**
FUNCTION GSays_Reps( cG_Func )
@ 2,2 WINSAY "Sales Rep #:"
@ 4,2 WINSAY "Last Name:"
@ 5,2 WINSAY "First Name:"
@ 7,2 WINSAY "Phone:"
IF cG_Func $ "AC"
SET CURSOR ON
READ
SET CURSOR OFF
ENDIF
** screen GET's for generic maint of sales rep file
**
FUNCTION GGets_Reps( cG_Func )
// A-Add, C-Change, D-Delete or null if
// display only.
@ 2,15 WINGET ASLS_NBR PICTURE "9999"
CLEAR GETS
@ 4,15 WINGET ALAST PICTURE "@!"
@ 5,15 WINGET AFIRST PICTURE "@!"
@ 7,15 WINGET APHONE PICTURE "@R (999) 999-
9999"
** Function to edit data called after a screen is
keyed but
** before the disk write
**
FUNCTION GEdit_Reps(cG_Func)
RETURN( .t. )
** key GET's for generic maint of division file
**
FUNCTION GKey_Reps( cGk_Func )
// A-Add, D-Del, C-Change
@ WinBott()-2, WinRight()-15, WinBott()+3,
WinRight()+09 WINDOW
SetMsgLin("Enter Sales Rep Number or Press ESC
Page: 73
to Abort")
cKey := Space( 4 )
@ WinBott()-1,WinRight()-13 SAY "Sales Rep #:"
GET cKey PICTURE "9999"
@ WinBott()+1,WinRight()-13 SAY "Enter Sales
Rep # Code"
IF cGk_Func < > "A"
@ WinBott()+2,WinRight()-13 SAY "Blank for
Current Rec"
ELSE
@ WinBott()+2,WinRight()-13 SAY "to Add or
ESC to Exit"
ENDIF
READ
SetMsgLin( "" )
WINDOW REMOVE
ASLS_NBR := IF(empty(cKey .or. ;
lastkey()==27, ; ASLS_NBR,cKey)
RETURN( cKey )
FUNCTION TestFunc( cFunction )
// "A"-Add, "C"-Change, "D"-Delete, "E"-Exit.
DO CASE
CASE cFunction == "A"
** Record was added to database, do
whatever we need to after that
** activity.
CASE cFunction == "C"
** Current database record was Changed, do
whatever is needed in
** that case.
CASE cFunction == "D"
** Current database record is now a
Deleted record, do whatever is
** needed (usually delete child relation
records).
CASE cFunction == "E"
** User is trying to exit the file
maintenance, make sure it is ok for
** them to do so at this time. If it is
then return true (.T.) otherwise
** return false (.F.) to keep them in the
file maintenance.
ENDCASE
RETURN( .T. ) // gotta return a logical
Page: 74
GENVLD()
Syntax:
genvld(<expL1>,<expC1>,<expN1>,<expN2>,<expN3>,<expL2>
[,<expC2>])
Pass:
<expL1> - The validation test expression.
<expC1> - The error message on incorrect GET input.
<expN1> - The screen row number to display the error
message.
<expN2> - The screen column number to display the
error message.
<expN3> - The screen rightmost column number to
pad/allow the error message to display.
<expL2> - Required indicator. True (.T.) if field
cannot be empty or false (.F.) if field is
allowed to be empty.
<expC2> - Color string for error message to display,
default is WERR_CLR.
Returns:
A logical value.
Description:
The GENVLD() function is a generic valid function used
to validate a GET for any logical expression and
display an error message on invalid input.
Sample:
You have a two byte character GET for the U.S. state
code and you would like to make sure what is keyed
is legitimate code. The following GENVLD() would do
this:
@ 05,22 WINGET cState PICTURE "!!" VALID ;
GenVld( in_usa( cState ), ;
"ERROR: Not a Valid U.S. State
Code",WinBotT()-1,WinLeft()+2,WinRight()-
2,.t.)
See the IN_USA() function in this text also.
In the above sample code the user would be forced to
enter a valid U.S. state code into the STATE field.
Attempting to leave the field blank would produce an
error beep and the error message due to the sixth
parameter being set to true.
Any expression that returns a logical value (including
Page: 75
your own UDFs) may be used in place of the IN_USA()
function in the example.
Page: 76
GETEDIT()
Syntax:
GETEDIT(<expC1>,<expN1>,<expN2>)
Pass:
<expC1> - Database alias name.
<expN1> - Screen row coordinate to display "Save
Changes?" prompt.
<expN2> - Screen column coordinate to display "Save
Changes?" prompt.
Returns:
NIL always.
Description:
The GetEdit() function is placed immediately after a
series of @..GET statements. It will execute a READ
for the GETs. When the GETs are exited, if any
changes were made, the user is prompted "Save
Changes?" which requires a yes or no response. If
the no option is selected, the cursor is placed at
the first GET again. If yes, the memory variables
are saved to like field variables in the database
<expC1> and the function is exited. If ESC is
pressed while editing the GETs, the function is
exited.
The field variable names are determined by removing the
first character of the memory variable named in each
GET.
Sample:
You have modified your OPTIONS.DBF database by adding
three fields to contain printer control information.
The fields you added are: PCMPRS-C-40, PBOLD-C-40,
PRESET-C-40. You want to allow the users of your
system to edit the printer control strings. This is
easily accomplished by converting a Builder dialog
box as follows:
Note that adding the three fields to OPTIONS.DBF and
then generating source code from Builder, will
create these three memory variables QPCMPRS, QPBOLD,
and QPRESET automatically.
Then in Builder, create a dialog box to edit these
three memory variables.
Next, in your dialog box to edit the printer control
Page: 77
strings, delete the following source that Builder
creates:
ReadGets( @GetList )
IF LASTKEY() == K_ESC
EXIT
ENDIF
Replace the deleted lines of code with these:
GetEdit("OPTIONS",WinBott()-1,WinLeft()+2)
EXIT
Thats all there is to it, delete seven and add two!
Page: 78
GOT()
Syntax:
got(<expC>,<expN1>,<expN2>)
Pass:
<expC> database alias name
<expN1> field number in database
<expN2> record number of database
Returns:
An expression determined by FIELDGET(<expN1>).
Description:
Normally used in a valid function to pop up a scroll
box and put the selected item in the READ field.
<expC> is the database alias used for the look up,
<expN1> is <expN1>th field in the database whose
alias is <expC>. <expN2> is the record number in
that database, usually a call to the PLIST()
function.
The return value is whatever is the value of the
databases <expN1>th field at record <expN2>.
Note that this function is called by the BUILDER
PckVld() function, and it is recommended that you
use PckVld() instead of Got(). PckVld() is easier
to use and can be created by BUILDER generated code.
Page: 79
HEX2DEC()
Syntax:
HEX2DEC(<expC>)
Pass:
<expC> - A string of hexadecimal digits.
Returns:
A numeric decimal integer of the passed hexadecimal
number.
Description:
HEX2DEC() converts a hexadecimal character string to a
numeric integer value. This function is useful when
calling some of the assembly routines in the BLDRASM
library.
See the TIMEOUT assembly routine also.
Page: 80
HNDLS()
Syntax:
HNDLS()
Pass:
Nothing.
Returns:
number of file handles.
Description:
This function locates the DOS System File Table (SFT)
and returns the number of file descriptor tables
configured for the computer. The number returned is
five minus the actual value to account for the DOS
used handles for the standard input, standard
output, standard error, starndard auxilary, and
standard print devices.
This number will be the CONFIG.SYS FILE= number minus
five in most instances.
Page: 81
IN_CANADA()
Syntax:
in_canada(<expC>)
Pass:
<expC> - A two byte character string
Returns:
A logical expression.
Description:
The IN_CANADA() function tests the passed parameter and
returns true (.T.) if the value is a valid Canadian
province code (see list below), otherwise false
(.F.) is returned. This function is useful when
building VALID functions. See the GENVLD() sample
code also.
Notes:
Canadian provinces tested in IN_CANADA():
AB - Alberta NS - Nova Scotia
BC - British Columbia ON - Ontario
MB - Manitoba PQ - Quebec
NB - New Brunswick SK - Saskatchewan
NF - Newfoundland
Page: 82
IN_USA()
Syntax:
in_usa(<expC>)
Pass:
<expC> - A two byte character string
Returns:
A logical expression.
Description:
The IN_USA() function tests the passed parameter and
returns true (.T.) if the value is a valid U.S.
State code (see list below), otherwise false (.F.)
is returned. This function is useful when building
VALID functions. See the GENVLD() sample code also.
Notes:
U.S. State codes tested by IN_USA():
AL - Alabama KY - Kentucky ND - North Dakota
AK - Alaska LA - Louisiana OH - Ohio
AZ - Arizona ME - Maine OK - Oklahoma
AR - Arkansas MD - Maryland OR - Oregon
CA - California MA - Massachusetts PA - Pennsylva
nia
CO - Colorado MI - Michigan RI - Rhode Island
CT - Connecticut MN - Minnesota SC - South Carolina
DE - Delaware MS - Mississippi SD - South Dakota
DC - Washington D.C. MO - Missouri TN - Tennessee
FL - Florida MT - Montana TX - Texas
GA - Georgia NE - Nebraska UT - Utah
HI - Hawaii NV - Nevada VT - Vermont
ID - Idaho NH - New Hampshire VA - Virginia
IL - Illinois NJ - New Jersey WA - Washington
IN - Indiana NM - New Mexico WV - West Virginia
IA - Iowa NY - New York WI - Wisconsin
KS - Kansas NC - North Carolina WY - Wyoming
Note: The codes for Puerto Rico (PR) and the U.S. Virgin
Islands (VI) are not tested.
Page: 83
INFILE()
Syntax:
infile(<expC1>,<expN1>,<expC2>,<expN2>,<expN3>,<expN4>,
;
<expL>[,<expC3>])
Pass:
<expC1> - File alias name of look up table.
<expN1> - Index order number for SEEK.
<expC2> - The error message on incorrect GET input.
<expN2> - The screen row number to display the error
message.
<expN3> - The screen column number to display the
error message.
<expN4> - The screen rightmost column number to
pad/allow the error message to display.
<expL> - Required indicator. True (.T.) if field
cannot be empty or false (.F.) if field is
allowed to be empty.
<expC3> - Color string for error message to display,
default is WERR_CLR.
Returns:
A logical value.
Description:
The INFILE() function tests the input of the @...GET
and displays an error message if the value entered
is not FOUND() in a database. The programmer may
allow or disallow the entry of a blank into the
field with <expL>
Sample:
You have a four byte character GET for an employee
number and you would like to make sure what is keyed
is a legitimate code. Further there is an employee
file with index order one (1) on the four digit
employee code. The following GET will force the
entry of a valid employee code based on the look up
table (called EMPLYEE).
@ 05,22 WINGET cEmpNbr PICTURE "!!" VALID ;
InFile("EMPLYEE",1, ;
"ERROR: Not a Valid Employee Code",WinBott()-
1,WinLeft()+2,WinRight()-2,.t.)
In the above sample code the user would be forced to
enter a valid employee code into the EMP_NBR field.
Attempting to leave the field blank would produce an
Page: 84
error beep and the error message due to the seventh
parameter being set to true.
The INFILE() function is only useful if you specifi
cally do not want to help your users find the
required field entry from the look up table.
Sometimes this is necessary, however, I believe you
will find the PCKVLD() function will be useful in
more situations.
Page: 85
INPATH()
Syntax:
inpath(<expC1>[,<expC2>])
Pass:
<expC1> - DOS filename to locate.
<expC2> - environment variable with pathnames
separated by semicolons of paths to search for
<expC1>. Default value is "PATH".
Returns:
A character value of the path where <expC1> is located.
A null string is returned if it was not found. A
"." (period character) is returned if it was found
in the current directory.
Description:
The INPATH() function first searches the current DOS
directory for the file <expC1> and returns "." if it
is found. It then searches each directory in the
DOS PATH environment variable or if <expC2> is
passed that environment variable is used instead.
If <expC2> is passed it must contain directory names
separated by semicolons just like the DOS PATH.
Page: 86
IOCTL()
Syntax:
ioctl( <expN1>,<expN2>)
Pass:
<expN1> The file handle of a currently opened file.
<expN2> a 1 (one) to change the IO from text to
binary, or 0 (zero) to change the IO to
text.
Returns:
A DOS error code from the following table:
000 No error
001 Invalid function number
002 File not found
003 Path not found
004 Too many open files (no handles left)
005 Access denied
006 Invalid handle
007 Memory control blocks destroyed
008 Insufficient memory
009 Invalid memory block address
010 Invalid environment
011 Invalid format
012 Invalid access mode (open mode is invalid)
013 Invalid data
014 Reserved
015 Invalid drive specified
016 Attempt to remove current directory
017 Not same device
018 No more files
019 Attmept to write on a write-protected diskette
020 Unknown unit
021 Drive not ready
022 Unknown command
023 CRC error
024 Bad request structure length
025 Seek error
026 Unknown media type
027 Sector not found
028 Printer out of paper
029 Write fault
030 Read fault
031 General failure
032 Sharing violation
033 Lock violation
034 Invalid disk change
035 FCB unavailable
Page: 87
036 Sharing buffer overflow
037 Reserved
038 Unable to complete file operation
039 - 049 Reserved
050 Network request not supported
051 Remote computer not listening
052 Duplicate name on network
053 Network name not found
054 Network busy
055 Network device no longer exists
056 NetBIOS command limit exceeded
057 Network adapter error
058 Incorrect network response
059 Unexpected network error
060 Incompatible remove adapter
061 Print queue full
062 No space for print file
063 Print file deleted
064 Network name deleted
065 Access denied
066 Network device type incorrect
067 Network name not found
068 Network name limit exceeded
069 NetBiOS session limit exceeded
070 Temporarily paused
071 Network request not accepted
072 Print or disk redirection is paused
073 - 080 Reserved
080 File already exists
081 Reserved
082 Cannot make directory entry
083 Fail on INT 24
084 Too many redirections
085 Duplicate redirections
086 Invalid password
087 Invalid parameter
088 Network device fault
089 Function not supported by network
090 Required system component not installed
Description:
This function is useful when you need to read a
graphics file or want to write a function to
download printer fonts. These types of files cannot
be read properly with the default DOS IO control
setting for reading text files.
Page: 88
ISEEK()
Syntax:
iseek(<exp>[,<expC>][,<expN>][,<expL>])
Pass:
<exp> expression to SEEK
<expC> database alias name, default is current select
alias.
<expN> index order number to use for SEEK command,
default used is the current index order.
<expL> .T. to use SOFTSEEK ON, .F. for SOFTSEEK OFF,
default is the current SOFTSEEK setting.
Returns:
a logical expression.
Description:
The ISEEK() function does an indexed search of a
database and returns the FOUND() condition.
<exp> is the key value to search for, <expC> is the
database alias to SELECT for the indexed search.
<expN> is the index order number to use in the
search, if zero or not supplied the current index
order is used. Set <expL> to true to use 'softseek
on' or false for 'softseek off', if <expL> is not
passed the current SOFTSEEK setting is used.
Sample:
**********************************************
********
** ISEEK() function example
**
USE Customer NEW
INDEX ON Cust_Nbr TO Cstmr1
INDEX ON TRIM( LName ) + " " + FName TO Cstmr2
SET INDEX TO Cstmr1,Cstmr2
CLS
cCust_Nbr := Space( 9 )
@ 1,1 SAY "Enter Customer Number" GET cCust_Nbr
READ
IF ISeek( cCust_Nbr, "CUSTOMER", 1, .F. )
@ 2,1 SAY "Customer Number Found."
ENDIF
Note that with Clipper version 5.01 and above you
Page: 89
should use the Clipper DBSEEK() function instead of ISeek().
Consider ISeek() obsolete for use with Clipper 5.01 and up.
Page: 90
KYBD()
Syntax:
Kybd( <expC> )
Pass:
<expC> a character string of keys to place in
the keyboard buffer.
Returns:
NIL always.
Description:
The Kybd() function simply executes a Clipper KEYBOARD
command using <expC> as the parameter. The
advantage Kybd() offers is that it can be executed
from a codeblock. This is useful when setting up
mouse pads.
See AddMPad()
Page: 91
MAKE_EMPTY()
Syntax:
make_empty(<expC>)
Pass:
<expC> existing memory variable name
Returns:
The same data type as the variable named in <expC>.
Description:
The memory variable name <expC> is returned in its
empty form. A character variable is spaces the
length of the passed variable, a numeric is returned
as zero, etc.
Sample:
**********************************************
********
*** Make empty function example
***
dTestDate := DATE()
? Make_Empty("TST_DAT") // same as ctod(" / / ")
nTestNumber := 998
? Make_eEpty("TST_NBR") // same as 0 (zero)
cTestCharacter := "Software Can be Groovy"
? Make_Empty("TST_CHR") // same as space(22)
Page: 92
MAKDIR()
Syntax:
makdir(<expC>)
Pass:
<expC> - Name of new DOS subdirectory to create.
Returns:
DOS error code.
Description:
The MAKDIR assembly subroutine attempts to create the
DOS subdirectory passed as <expC>.
This routine is useful when writing installation
programs or end of year archiving and any other
reason you may have to create a DOS subdirectory
from your Clipper program. You can test the results
of MAKDIR using CHGDIR, CHGDSK and CURDIR()
See CHGDIR(), CHGDSK()
Page: 93
MAXHNDLS()
Syntax:
maxhndls([<expN>])
Pass:
Zero/nothing or a numeric expression
Returns:
If zero or nothing is passed MAXHNDLS() returns the
maximum number of DOS file handles available to the
computer. This number does not mean your program
will be able to open that number of files. The
CLIPPER environment variable or the program command
line MUST set the file handles also. If BOTH the
DOS and Clipper configuration settings for file
handles are not set, you may get DOS ERROR 4's.
If a number is passed, MAXHNDLS returns true if the
number of DOS file handles available is equal or
greater, otherwise MAXHNDLS() returns false. If
false is to be returned MAXHNDLS() will display an
error box before returning.
Description:
Allows a Clipper program to determine the maximum
number of available DOS file handles in the current
system configuration.
Also displays errors if fewer than <expN> file handles
are present in the current configuration.
Page: 94
MENU()
Syntax:
MENU(<expA>[,<exp>][,<expO>][,<expL>])
Pass:
<expA> - Array created by ADDPROMPT() or
CRTMNUARRY().
<exp> - Default menu option to highlight.
<expO> - Current GET object. Only use when MENU()
is being used as a GET reader.
<expL> - Display only if .T.. Default .F..
Returns:
Indicator of selected menu option.
Description:
To use the MENU() function, first create a menu array
using either the @..ABPROMPT or @..WINPROMPT Builder
command or using the CRTMNUARRY() Builder function.
You can look at Builder generated code to see
samples.
Once a menu array is established, the MENU() function
will display the menu options and return an
indicator of which prompt, if any, was selected.
Pass <exp> to set the default menu option. <exp> can
be passed as either a Numeric or Character data
type. If passed as a Numeric, MENU() will return a
Numeric value. If passed as a Character, MENU()
will return a Character value.
If <exp> is Numeric or not passed as a parameter,
MENU() will return the array element number of the
user menu selection. Zero (0) is returned if the
ESC key or right mouse button are pressed.
If <exp> is Character, MENU() will return the unique
character highlighted within the menu prompt when
selected or a space character if the ESC key or
right mouse button are pressed.
Note that if ALL menu prompts have a code block to
execute upon selection, MENU() can only return a
zero (0) or space, only menu prompts added without a
code block will return a value greater than zero or
space.
<expO> and <expL> are used only when MENU() is being
Page: 95
used as a GET reader. With <expO> as the value of the
current GET object, and <expL> used to initially display a
menu in a GET stream. See the example below on how this is
accomplished. Note that Builder is capable of generating
all the needed code to create menus in a GET stream, see the
@MENU picture option.
// First a 'normal' menu
LOCAL aMenuArray := {}
LOCAL xOpt
// set up all the menu prompts and have each execute
a code block.
@ 05, 10 ABPROMPT " First " TO aMenuArray EXECUTE
FuncOne()
@ 06,10 ABPROMPT " Second " TO aMenuArray EXECUTE
FuncTwo()
@ 07,10 ABPROMPT " Third " TO aMenuArray EXECUTE
FuncThr()
@ 08,10 ABPROMPT " Fourth " TO aMenuArray EXECUTE
FuncFor()
// xOpt := " " // uncomment this line and ABMENU()
will return
// "F", "S", "T", or "O" instead of 1, 2, 3,
or 4
xOpt := Menu(aMenuArray) // execute the menu
// Of course this is a 'trick' menu, Opt can ONLY
get set to zero. After a
// code block executes, it returns to MENU(), since
each prompt has a code
// block the only way to return from MENU() is to
ESC.
RETURN( NIL )
FUNCTION FuncOne()
MsgBox("First Menu Option")
RETURN( NIL )
FUNCTION FuncTwo()
MsgBox("Second Menu Option")
RETURN( NIL )
FUNCTION FuncThr()
MsgBox("Third Menu Option")
Page: 96
RETURN( NIL )
FUNCTION FuncFor()
MsgBox("Fourth Menu Option")
RETURN( NIL )
Sample 2:
// the same as the previous example with a different
programming style
LOCAL aMenuArray := {}
LOCAL xOpt
// set up menu prompts
@ 05,10 ABPROMPT " First " TO aMenuArray
@ 06,10 ABPROMPT " Second " TO aMenuArray
@ 07,10 ABPROMPT " Third " TO aMenuArray
@ 08,10 ABPROMPT " Fourth " TO aMenuArray
xOpt := " "
DO WHILE .T.
xOpt := Menu( aMenuArray, xOpt )
DO CASE
CASE xOpt == " "
EXIT
CASE xOpt == "F"
FuncOne()
CASE xOpt == "S"
FuncTwo()
CASE xOpt == "T"
FuncThr()
CASE xOpt == "O"
FuncFor()
ENDCASE
ENDDO
RETURN( NIL )
Note:
Sample 1 above is easily created by the BUILDER
program, there is no need to learn ALL the syntax.
Also see the @MEMO and @MENU Picture functions in
the BUILDER manual.
Page: 97
MESSAGE()
Syntax:
message(<expC1>,<expN1>,<expN2>[,<expN3>][,<expC2>])
Pass:
<expC1> text to display on the screen
<expN1> row to display
<expN2> column to display
<expN3> length to pad/truncate message text
<expC2> alternate color choice
Returns:
Nothing.
Description:
The MESSAGE() function places <expC1> on the screen at
row <expN1> column <expN2> and pads <expC1> (or
trims it) to a length of <expN3>. <expC2> may be
used as an alternate color choice. If <expN3> is
not passed, the LEN(<expC1>) is used instead. If
<expC2> is not passed, the current color is used.
Sample:
**********************************************
*************
*** MESSAGE function example.
***
Message( "Test Message 1", 01, 00, 80, "+w/b" )
Waitkey()
Page: 98
MGETROWCOL()
Syntax:
MGETROWCOL(@<expN1>,@<expN2>)
Pass:
<expN1> - A numeric variable passed by reference.
<expN2> - A numeric variable passed by reference.
Returns:
Integer indicating mouse button status and sets <expN1>
and <expN2> with the current mouse cursor row and
column.
0 - No button pressed.
1 - Left button pressed.
2 - Right button pressed.
3 - Left and right button pressed.
4 - Middle button pressed.
5 - Left and middle buttons pressed.
6 - Right and middle buttons pressed.
7 - All three buttons pressed.
Description:
<indent 3/4 inch> Use when adding mouse capability to a
pre-existing routine. Do not use the mouse button
return information from this function, only use the
row and column information. The Builder SETMOUSE()
function should be used to check mouse button
status.
See: MSETROWCOL(),ADDMPAD(),DELMPAD(),MOUSEINIT(),
SETMOUSE(),MOUSCRS()
Page: 99
MOUSCRS()
Syntax:
MOUSCRS(<expL>)
Pass:
<expL> - Set to true to turn mouse cursor on, false
to turn it off.
Returns:
NIL always.
Description:
This function simply turns the mouse cursor off and on.
Every time a call is made to turn the mouse cursor
off, the mouse driver saves the screen byte and
attribute at the current mouse cursor location. The
driver also increments an internal counter for use
when trying to turn the cursor back on. The mouse
cursor will only be turned on by the mouse driver
when it's internal counter is set to zero. Each
call to turn the cursor back on will decrement the
mouse driver counter; except when the counter is
zero, it will remain zero.
What this all means is that every call to MousCrs(.f.)
will have to have a matching MousCrs(.t.). If you
make two calls to AbMousCrs(.f.), it will take two
calls to MousCrs(.t.) to put the mouse cursor back
on the screen.
See: MGETROWCOL(),ADDMPAD(),DELMPAD(),MOUSEINIT(),
SETMOUSE(),MSETROWCOL()
Page: 100
MOUSEINIT()
Syntax:
MOUSEINIT([<expN>])
Pass:
<expN> - An INKEY() value.
Returns:
NIL always.
Description:
This function initializes the Builder mouse routines.
<expN> is the INKEY() value for the hot key used
when configuring mouse action in a Clipper or 3rd
party 'closed' function. Clipper 'closed' functions
are ACHOICE(), MEMOEDIT() and the like, where the
keyboard loop is not accessible.
When first executed in a program MOUSEINIT() turns the
mouse cursor on at screen row 24 column 79 and
executes the function SETMOUSE(). The SETMOUSE()
function monitors mouse activity at ALL times, even
inside 'closed' functions.
See the SETMOUSE() function for more information.
Builder enters the MOUSEINIT() function in the source
code for you, and sets the default 'hot key' to
KP_ALT_MINUS. The Builder function EDT_MEMO() and
the Builder help system require this 'hot key' if
mouse functionality is to be used in these areas. It
is strongly reccomended this is not changed.
Page: 101
MOUSEINT()
Syntax:
MouseInt(<expN1>,<expN2>,<expN3>,<expN4>)
Pass:
<expN1> - Value to pass for AX register.
<expN2> - Value to pass for BX register.
<expN3> - Value to pass for CX register.
<expN4> - Value to pass for DX register.
Returns:
NIL always. You can obtain register value after the
mouse driver interrupt is called by passing any
argument by reference.
Description:
This function simply executes the calls to the mouse
driver interrupt.
Example 1:
// Source code for the AbMGetRowCol() function
FUNCTION AbMGetRowCol( nRow, nCol )
LOCAL AX,BX,CX,DX
nRow := If( nRow==NIL, 0, nRow )
nCol := If( nCol==NIL, 0, nCol )
AX := 3 // mouse driver call to get cursor
screen
// location
// I don't need to know AX, but do need BX,
CX, and DX values
// after the interrupt
MouseInt( AX, @BX, @CX, @DX ) // execute
mouse interrupt
nRow := Int( DX / 8 ) // convert to rows
nCol := Int( CX / 8 ) // convert to columns
RETURN( BX ) // return button status
Example 2:
// Source code for function AbMSetRowCol()
FUNCTION AbMSetRowCol( nRow, nCol )
LOCAL AX,BX,CX,DX
Page: 102
AX := 4 // mouse driver call to set screen
// cursor location
CX := nCol * 8 // assign converted columns
DX := nRow * 8 // assign converted rows
MouseInt( AX, BX, CX, DX ) // execute mouse
interrupt
// All agruments passed by value, no informa
tion is returned by this call
// Note that BX value was passed as NIL. This
is OK for the function.
RETURN( NIL )
Page: 103
MSETROWCOL()
Syntax:
MSETROWCOL(<expN1>,<expN2>)
Pass:
<expN1> - Screen row coordinate to place mouse
cursor.
<expN2> - Screen column corrdinate to place mouse
cursor.
Returns:
NIL always.
Description:
This function is used to change the mouse cursor
position. Note: you will most likely never need to
use this function.
See: MGETROWCOL(),ADDMPAD(),DELMPAD(),MOUSEINIT(),
SETMOUSE(),MOUSCRS()
Page: 104
MSGBOX()
Syntax:
msgbox(<expC1>[,<expC2>][,<expC3>][,<expC4>][,<expN1>]
[,<expN2>][,<expN3>][,<expN4>])
Pass:
<expC1>/<expA1> message for line one or array name
to display.
<expC2> alternate color choice
<expC3> message for line two - input prompt
<expC4>/<expA2> character list for allowable input
(null ("") for any key) or array of menu
prompts.
<expN1> top left row
<expN2> top left column
<expN3> bottom right row
<expN4> bottom right column
Returns:
nothing or a character expression depending on the
value of <expC4>.
Description:
This function puts a message box on the screen and
waits for an acknowledgment.
If only <expC1> is passed as an argument a box is
centered on the screen sized to fit <expC1> inside.
The message is displayed in bright yellow with a red
background by default, useful for error messages.
Pass <expC2> as an alternate color choice.
<expC3> and <expC4> usually work together, <expC3> is a
prompt and <expC4> is a list of characters that,
when entered from the keyboard, will remove the box
from the screen.
<expC4> need only contain one of each alphabetic
character as it is converted to upper case before
being used by MSGBOX().
<expN1> and <expN2> are optional row and column screen
positions for the box.
<expN3> and <expN4> may be passed to optionally size
the box.
Sample:
Page: 105
**********************************************
***********
*** MSGBOX function example
***
MsgBox( "Error Message" )
MsgBox( "Information Message", "+w/b" )
IF MsgBox( "Do You Play the Piano?", "+w/b", "Press
Y or N", ;
"YN", 10, 5 ) == "Y"
MsgBox( "You Pressed Yes", "+w/b" )
ELSE
MsgNox( "You Pressed No", "+w/b" )
ENDIF
** ONLY FOR ARRAYs: Each element may (optionally)
be prefixed with
** "@L" to left justify, "@R" to right justify or
"@C" to center that
** element inside the box. If not used the
default is "@L".
MsgBox( {"An ARRAY message", ;
"for the MsgBox() function to", ;
"Display", ;
"@CI'm Centered !", ;
"@RRight Justified" })
Page: 106
NET_USE()
Syntax:
net_use(<expC1>,<expL>,<expN>,<expC2>[,<expC3>])
Pass:
<expC1> database alias name
<expL> .T. for exclusive open, .F. for shared
<expN> error timeout seconds if cannot be opened
<expC2> alias to use when file is opened
<expC3> RDD driver name.
Returns:
a logical expression.
Description:
Opens the database <expC1> in exclusive mode if <expL>
is true or non-exclusive if <expL> is false. If
<expN> is greater than zero in a network environment
and the database cannot be opened in <expN> seconds
a timeout error will be displayed. <expC2> is the
alias that will be used. If <expC3> is passed, that
RDD driver will be used.
Comment:
It is suggested that you use the OPEN_FIL function
instead of the NET_USE() function, as it automati
cally handles error conditions and parameter passing
is more convenient.
Page: 107
NOT_REQ()
Syntax:
not_req(<expC1>,<expN1>,<expN2>,<expN3>[,<expC2>])
Pass:
<expC1> - Error message if field is not blank.
<expN1> - Screen row coordinate to display error
message.
<expN2> - Screen column coordinate to display error
message.
<expN3> - Rightmost screen column to display error
message.
<expC2> - Color to display error message. Default is
WERR_CLR.
Returns:
A logical value.
Description:
There are times when you may want to force a user to
enter an @...GET as a blank. The NOT_REQ() valid
function is used in these (rare) cases. Usually
conditionally executed.
Sample:
In the following sample @...GETs the user is required
to enter a state code and a country name. If the
state code is a validU.S. state then the country
name must be blank otherwise the country name field
is required.
Program this using BUILDER valids as follows:
** Force a valid U.S. State or Canadian Province or
blank
**
@ 07, 17 WINGET cState PICTURE "!!" VALID ;
GenVld( In_USA( cState ) .OR. In_Canada(
cState ), ;
"ERROR: Not a Valid State or Province",
WinBott() - 1, WinLeft() + 2, WinRight() - 2,
.F. )
** if the state code is valid U.S. state then the
country name
** must be blank, otherwise the country name is
required.
@ 08, 17 WINGET cCountry VALID ;
IF( In_USA( cState ), ;
Page: 108
Not_Req( "Leave Country Blank", WinBott() - 1,
WinLeft() + 2, WinRight() - 2), ;
Req( "Country Name is Required", WinBott() -
1, WinLeft() + 2, WinRight() - 2 ) )
Page: 109
NUMERIC()
Syntax:
numeric(<expC>)
Pass:
<expC> a string that may or may not contain all
numerics
Returns:
a logical expression.
Description:
This function scans every character in <expC> and if
every character is between '0' and '9' then it
returns true, otherwise false is returned.
Page: 110
OPEN_FIL()
Syntax:
open_fil(<expC1>[,<expL1>][,<expC2>][,<expC3>][,<exp
L2>])
Returns:
a logical expression.
Pass:
<expC1> database name to open.
<expL1> .T. for shared open, nothing or .F. for
exclusive open. Default
value is .F.
<expC2> alias name when open, if other than database
name. Default is the database name.
<expC3> RDD driver name. Default is the default RDD.
<expL2> .T. to exit to DOS on open errors, .F. to
return false on open errors. Default is .T.
Description:
The OPEN_FIL function will attempt to open the file
<expC1> in exclusive mode-even if SET EXCLUSIVE OFF
is in effect-unless the second parameter is sent as
true. Use the third parameter to set the alias if
you want the alias other than the default of
<expC1>. <expL2> determines how the OPEN_FIL
function will react when it cannot open a .DBF file,
passing .T. (or not passing this parameter) will
cause OPEN_FIL to exit to DOS on error conditions.
Passing <expL2> as .F. will cause OPEN_FIL to return
a logical false if it fails to open the file.
The OPEN_FIL function tests for three (3) error
conditions. If an error is detected, an error box
is displayed and OPEN_FIL either exits to DOS or
returns false to the application depending on the
value of <expL2>. The errors tested for are as
follows:
If <expC3> is passed, that RDD driver will be used for
the database being opened.
1. Invalid Alias Name. If no specific alias name is
sent to the OPEN_FIL function the file name
(<expC1>) is used. A valid alias name must contain
the letter 'A' through 'Z' in the first character
position. The second through tenth character
positions can contain 'A' through 'Z', '0' through
Page: 111
'9' or '_'.
2. File not found. Before a database is USEd OPEN_FIL
tests the Clipper FILE() function to determine if
the file exists.
3. Already in Use. The database is already USEd in
EXCLUSIVE mode or the file has been locked.
Note that the Open_Fil() function is obsolete with
Clipper version 5.0 and above. The extra error
trapping that is done in Open_Fil() is also done in
the Clipper 5.x error system.
Page: 112
PCKVLD()
Syntax:
pckvld(<expC1>,<expN1>,<expN2>,<expL1>,<expC2>,<expL2>
;
[,<expC3>][,<expC4>])
Pass:
<expC1> - File alias name for picklist.
<expN1> - Field ordinal number in database to place
in GET field on pick list selection.
<expN2> - Index order number to use with <expC1> to
find the GET input data.
<expL1> - .T. = Use QWERTY scroll. .F. = Do not use
QWERTY scroll.
<expC2> - Display expression for picklist.
<expL2> - .T. = Required, do not accept blank for GET
input, .F. = blank ok.
<expC3> - Key value SEEK prefix. Default nothing.
<expC4> - STAY AT field name for a bounded by
picklist. Default is no bounded by field.
Returns:
A logical expression.
Description:
The PCKVLD() function can only be used in the VALID of
a GET. PCKVLD() will SEEK on the <expC1> database
using index order <expN2> and if value of
FIELD(<expN1>) is equal to the value entered into
the GET the cursor will move to the next field in
the GET stream. If there is not an exact match a
pick list is given to the user with the highlight
bar positioned to the nearest record to the GET
input. The user may then move to the desired
record, and press ENTER to put that data into the
GET field and move to the next field in the GET
stream.
See PLIST().
Sample:
You are building an order entry system and one of the
fields on the order is 'Sales Person'. This field
is a three character field of the persons initials.
You want to verify that what is entered into this
field is a valid employee, but also that the
employee is a sales person. PCKVLD() can be used to
do this in the following manner.
Page: 113
Technical assumptions:
Employee file is called "EMPLYEE".
The field EMPLYEE->TYPE is a one byte character
field indicating the
department the employee works in.
That EMPLYEE->TYPE="S" is the sales department.
The field EMPLYEE->INITIALS is a three byte
character field of the
employees initials.
Index order number one has the index key
TYPE+INITIALS on the
EMPLYEE file.
The field EMPLYEE->INITIALS is the second field in
the database.
** The following PCKVLD() will not allow
QINV_SLSMAN to be
** blank. Will only allow entry if these
Clipper program statements ...
**
** SELECT EMPLYEE
** SET ORDER TO 1
** SEEK "S"+QINV_SLSMAN
**
** ... set FOUND() to .T.
**
** If the entry is not FOUND() then a pick
list is presented displaying
** the initials, first, and last name. The
picklist will only display
** EMPLYEE->TYPE="S" records because of the
index key
** expression, the key prefix passed, and the
bounded by being set.
**
@ 11,23 WINGET cInv_Slsman PICTURE "!!!" VALID
;
PckVld( "EMPLYEE", 2, 1, .F., ;
'initials " "+fname+" "+lname', .T., "S",
"TYPE" )
The PCKVLD() function is easier to digest if you
understand the PLIST() function. The source code to
Page: 114
call this function can be automatically generated by
BUILDER.
Page: 115
PLIST()
Syntax:
plist(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>,<expN5
>,<expC2> ;
[,<expL1>][,<expC3>][,<expC4>][,<expB1>][,<expB2>] ;
[,<expL2>][,<expL3>][,<expC5>]
Pass:
<expN1> top row for picklist box.
<expN2> left column for picklist box.
<expN3> bottom row for picklist box.
<expN4> right column for picklist box.
<expC1> database alias name.
<expN5> index order number to use for picklist.
<expC2> expression to display on each picklist line.
<expL1> enable QWERTY scroll function, default false.
<expC3> memvar for QWERTY scroll initialization
(prefix with @) default none.
<expC4> color for pointer bar, default is WREV_CLR.
<expB1> execute on ENTER key. Default, nothing.
<expB2> condition expression for bounded picklist.
Default, no bounds.
<expL2> PLIST() to display message line? Default is
.T.
<expL3> PLIST() to display border? Default is .T.
<expC5> Seek prefix when QWERTY scroll is used.
Default nothing.
Returns:
A numeric expression. The record number selected.
Description:
The PLIST() function creates a scrollable pick list box
to be presented on the screen. This function is a
replacement for the POP() function of BUILDER ver
1.0.
<expN1> and <expN2> are the row and column of the upper
left corner of the pick list box.
<expN3> and <expN4> are the height and width of the box
respectively
<expC1> is the database alias to 'browse'.
<expN5> is the index order number to use when this
picklist is being viewed.
Page: 116
When <expC2> is evaluated as a macro it is displayed on
each line in the box.
If <expL1> is passed as true then a field delimited
with square brackets will be placed on the top of
the box. Any QWERTY text entered will be displayed
between the brackets and that text will be used as a
SEEK key and the PLIST() box will be refilled using
that value. If <expC5> was passed the SEEK value
will be <expC5> + QWERTY value before refilling the
PLIST() box.
<expC3> is used in conjunction with <expL1> and
contains the name of the memory variable that
contains the starting key value to be placed between
the square brackets. If you choose to set <expL1>
to true and not use this argument the QWERTY area
will be sized according to the length of the
INDEXKEY(0) function.
<expC4> is an optional color for the pointer bar.
<expB1> is an optional (strongly recommended) code
block to be executed on selection of an element.
<expB2> is an optional code block that returns a
logical expression that will restrict scrolling only
while the expression returns true (.T.). This
expression must return true (.T.) when PLIST() is
initially called.
Warning: if you use <expB2> to set database bounds AND
<expL1> is set to true, you will need to also use
<expC5> (SEEK prefix)!
Use <expL2> and <expL3> to optionally turn off some
PLIST() default display items. Both <expL2> and
<expL3> default to true (.T.). Pass false (.F.) in
<expL2> and PLIST() will not display it's default
message line. Pass false (.F.) in <expL3> and
PLIST() will not display a window border around the
PLIST() data.
Sample 1:
**********************************************
*******
* This example displays a pick list box at row 2
column 40, it is 9 rows tall
Page: 117
* and 23 columns wide. It displays the field
COUNTRY from the database
* INTRNTNL and provides the user a field to enter
QWERTY text to move
* to different parts of the database. If a record
is selected the function
* INTL_DTL is executed.
SELECT Intrntnl
Intrntnl->( DBGOTOP() )
** display international
**
cKeyField := Space( 20 )
nRecord := Plist( 02, 40, 9, 23, "INTRNTNL", 1,
"country", .T., ;
@cKeyField,, {|| intl_dtl() })
Sample2:
**********************************************
*******
* This example displays a pick list box at row 2
column 19, it is 9 rows tall
* and 20 columns wide. It displays the fields
PART_NBR and
* PART_END from the database MSPART.
* If a record is selected the function MS_DETAIL is
executed.
SELECT MsPart
MsPart->( DBGOTOP() )
** display part list
**
cDisplay := 'part_nbr+"-"+part_end'
nRecord := Plist( 02, 19, 11, 39, "MSPART", 1,
cDisplay, .T.,,,, ;
{|| ms_detail() })
Sample 3:
**********************************************
***************
** This example will display a picklist box on the
screen and combine both
** the Bounded by AND the QWERTY scroll features.
Page: 118
The last parameter
** passed allows this, however, careful consider
ation must also be given to
** the index and database being used.
**
** We will browse the database PARTS which is a very
large database with
** part numbers and names we want to display. This
database also has a
** code to indicate what type of part the record
contains. There are three
** part type codes "P"-Plumbing, "H"-Heating, and
"E"-Electrical.
**
** Before reaching this point in the program the
user has already selected
** the part type to be viewed. So the picklist
should be bounded by the
** PART_TYP field. The only part type to be
displayed in this pick list is
** indicated in the memvar cPartType which is equal
to "P", "H", or "E" before
** this area of the program is executed.
**
** Since there are so many parts of each type, we
will also provide a
** QWERTY scroll field to allow faster locating.
**
** Index order one has the index key expression of:
** PART_TYP+PART_NBR
**
** PART_TYP is Character 1 byte long
** PART_NBR is Character 12 bytes long
**
** If a part number is selected, proceed to the
order entry screen, procedure
** ORD_ENTRY
cPartType := Parts->Part_Typ
bCondition := {| |cPART_TYP==BPART_TYP}
cKeyField:= Space( 12 ) // length of part number for
qwerty
// scroll default would be length of
// index expression, in this case 13.
** set up the display expression
cDisplay := 'TRANSFORM( Part_Nbr, "@R 99-999999-999-
!" ) + " " + Desc'
Page: 119
** display the picklist
Plist( 02, 01, 14, 66, "PARTS", 1, cDisplay, .T.,
@cKeyField,, {|| Ord_Entry() }, ;
bCondition, .T., .T., cPartType )
** Parms 1-4 set the screen coordinates.
** Parms 5 and 6 are the database alias name and
index order used during
** picklist operation.
** Parm 7 (cDisplay) is the display expression
defined above.
** Parm 8 (.T.) turns on the QWERTY scroll feature.
** Parm 9 (@cKeyField) passes the QWERTY scroll
initialization value. This could
** also have been initialized like:
** cKeyField := Parts->Part_Nbr
** to put something IN the picklist entry field.
** Parm 10, nothing, use the default color for the
highlight bar.
** Parm 11 ({|| Ord_Entry() }) the funciton named
ORD_ENTRY will get
** executed after the ENTER key is pressed. i.e. a
part is selected.
** Parm 12 (bCondition) passes the Bounds condition
variable.
** This memvar is set above and if Eval'd returns
true, all contigious
** records where this returns false will not be
visible in this picklist.
** Parms 13 and 14 tell PLIST() to display a window
border and a default
** message line.
** Parm 15 (cPartType) Required for Bounded QWERTY
picklists. When a
** QWERTY key is pressed, the SEEK will be on
cPartType + {Current-
** QWERTY-Text}.
Page: 120
PUTKEY()
Syntax:
Putkey( <expN> )
Pass:
<expN> A keyboard scan code to place in the keyboard
buffer
Returns:
A logical value. True if the key was successfully
placed in the keyboard buffer, false if the keyboard
buffer was full.
Description:
Many keys cannot be placed in the keyboard buffer using
the Clipper KEYBOARD command. Specifically any key
with an INKEY() value greater than 255 will not
work. The Builder PUTKEY() function will work on
any key, simply use the table from the TIMEOUT()
function in this manual for the complete list when
needed.
Sample:
// Place the key Shift - TAB in the keyboard buffer
// Note that it cannot be done using the KEYBOARD
// command.
Putkey( Hex2Dec( "0F00" ) )
Page: 121
READGETS()
Syntax:
ReadGets( @<expA>[, <expL>][, <expN>] )
Pass:
<expA> a GetList array.
<expL> Set to .F. to preserve the GetList on
exit. Default .T.
<expN> GetList array to initially place the
cursor. Default one.
Description:
The Builder ReadGets() function is a replacement for
the Clipper READ command. The advantage of the
ReadGets() function is that it will turn on the
cursor, change the cursor size according to the
insert state, and turn the cursor off on exit.
Page: 122
REC_LOCK()
Syntax:
rec_lock(<expN>)
Pass:
<expN> seconds before error timeout, pass zero to never
timeout.
Returns:
A logical expression.
Description:
Attempts to lock the current record of the currently
selected database for timeout period of <expN>
seconds. If the record cannot be locked after the
timeout period an error box is presented to try
again, if No is selected, a logical false is
returned. If <expN> is zero or not passed to the
function, REC_LOCK() will wait indefinitely.
Comment:
The SAVE_IT() function performs all record locking
before any file I/O and you should not have to use
this function.
However...
some shops require that a record is locked during
editing and all the functions and procedures in
BUILDER only lock a record immediately before any
file I/O so you may need to use this function after
all.
Page: 123
REL_MAINT()
Syntax:
REL_MAINT(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>, ;
<expB1>,<expC2>,<expA>,<expN5>,<expN6>[,<expC3>][,<e
xpB2>][,<expB3>])
Pass:
<expN1> The upper left corner screen row where the
Rel_Maint() is being
displayed.
<expN2> The upper left corner screen column where the
Rel_Maint() is
being displayed.
<expN3> The lower right corner screen row where the
Rel_Maint() is being displayed.
<expN4> The lower right corner screen column where
the Rel_Maint() is
being displayed.
<expC1> You must declare a function that contains the
GETs for the
maintenance the first three letters of which
must be 'GET'. Pass in <expC1> the characters
you add to make the procedure unique.
<expB1> The condition that relates the file to be
edited, this must be a
logical true when evaluated. All contigous
records where the condition remains true will
be available for editing.
Note: The SET RELATION TO ... command does NOT
need to be in effect to use this function, the
databases merely need to have a one to many
relationship.
<expC2> Database alias name to be edited.
<expA> Memory variable prefix character(s).
<expN5> The 'delete index' order number, zero (0) if
a 'delete index' is not used.
<expC3> The first character of each menu pad to use.
Default "ACD"
<expB2> codeblock executed on file I/O and before
exit. Default none.
<expB3> codeblock executed when Ctrl+Enter is
pressed. Default none.
<expC3> and <expB2> work identically to the last two
parameters passed to GEN_MAINT. See the documenta
tion on that function for more information on these
parameters.
Page: 124
Description:
The REL_MAINT function is used to edit the 'many'
records in the child database when a one-to-many
database relationship exists.
Rel_Maint() calls can easily be constructed by Builder.
See the Rel_Maint() section in the Builder manual
for more information on automatically creating
Rel_Maint()'s.
If you are unsure what a 'delete index' is refer to the
GEN_MAINT function for clarification.
Look carefully at the following sample to see how to
set up a REL_MAINT call.
Sample:
**********************************************
** CALLED BY: Pick List Window Proc: PLST003 **
** Comment: Model Maint Dialog **
**********************************************
PPRCEDURE Dlog004()
LOCAL cPartNo
LOCAL aRPartNo
** save key to a memory variable
** important you code something like this!
cPartNo := Model->PartNo
SETCOLOR( Var( WNDW_CLR_ ) )
@ 15, 45, 19, 77 WINDOW STYLE "3+"
@ 02, 04 WINSAY "Model Number"
** call rel_maint to edit all contiguous
records in the MODEL
** database with the field Model->PartNo equal
to the memory
** variable cPartNo.
SELECT RPartNo
aRpartNo := ARRAY( FCOUNT() )
cPartNo := Model->PartNo
RPartNo->( DBSETORDER( 1 ) )
RPartNo->( DBSEEK( Model->PartNo ) )
Rel_Maint( ;
WinTop(), WinLeft(), WinBott(),
WinRight(), "004", {||Model->PartNo =
Page: 125
cPartNo};
"MODEL", aRpartNo, 2 )
WINDOW REMOVE
** this func created by moving the GETs created by
BUILDER to a proc
** with the first three characters equal to "GET", I
arbitrarily chose "004"
** as the second part of the name (because it
matches DLOG004)
** and pass "004" as the fifth parameter above.
FUNCTION Get004( cG_Func )
LOCAL GetList := {}
** absolutely IMPERATIVE the key variables get
set from
** previously saved memory variables here!!
aRpartNo[1] := Model->RPartNo
@ 02,18 WINGET aRpartNo[2] PICTURE "@!"
IF cG_Func $ "AC"
ReadGets( @GetList )
ENDIF
Not including the comments only four lines of code were
added to a BUILDER dialog box to create this (many
more were deleted).
This is a small example, but should clearly show how to
set up a REL_MAINT of your own.
Page: 126
REQ()
Syntax:
req(<expC1>,<expN1>,<expN2>,<expN3>[,<expC2>])
Pass:
<expC1> - Error message if field is blank.
<expN1> - Screen row coordinate to display error
message.
<expN2> - Screen column coordinate to display error
message.
<expN3> - Rightmost screen column to display error
message.
<expC2> - Color to display error message. Default is
WERR_CLR.
Returns:
A logical value.
Description:
This VALID function forces entry of an @...GET field to
be non-blank. It simply checks if the GET value is
EMPTY() and only allows the cursor past the GET is
it is not EMPTY().
Sample:
In this example the system you are building has a date
field on a screen and the field must be entered, it
cannot be blank. That is all the validation that
can be performed. The following REQ() function will
accomplish this.
@ 05,11 WINGET dTestDate VALID ;
Req( "A Date is Required", WinBott()-1,
WinLeft()+2,WinRight()-2)
Page: 127
RGHT_JST()
Syntax:
rght_jst([<expC>])
Returns:
A logical true (.T.)
Pass:
<expC> - Fill character after field is right justified.
Default space.
Description:
The RGHT_JST() VALID function will right justify and
fill a character field with <expC> or spaces if
<expC> is not passed.
Sample:
Suppose you have a field to be keyed by a user and for
whatever reason it makes sense to make it a
character field. You also want to right justify and
zero fill the field because the field will be used
as the key value to look up something in another
database. Use the RGHT_JST() function to accomplish
this in the following manner:
cKeyVal := Space( 07 )
@ 01,14 WINGET cKeyVal PICTURE "9999999" VALID ;
Rght_jJt( "0" )
If the user keys one (1) and then presses ENTER then
cKeyVal will equal "0000001". If twenty-one (21) is
entered then cKeyVal will equal "0000021"
The field will be right justified.
Page: 128
SAVE_IT()
Syntax:
save_it(<expC1>,<expA>,<expN>,<expC2>)
Pass:
<expC1> "ADD", "CHG", "DEL", or "RCL" only.
<expA> name of array containing database field data
<expN> fast delete index order number
<expC2> database alias name
Returns:
A logical expression.
Description:
The SAVE_IT() function will add, change, delete, or
recall the current record from the database <expC2>.
The SAVE_IT() function uses record locking if the
memory variable NETWORK is set to true. The <expC1>
argument must be equal to "ADD", "CHG", "DEL", or
"RCL" to tell SAVE_IT() to add, change, delete, or
recall a record. <expA> is the array name which
contains the data to be placed in the database
fields with matching ordinal positions (See the
DBSTOR function). Use <expN> to pass the order
number of the "fast delete" index created like:
INDEX ON IF(DELE(),"*"," ") TO ...
Send <expN> as zero (0) if you are not using a "fast
delete".
If the NETWORK memory variable is set to true and the
SAVE_IT() function cannot lock the requested record
and the user replies "No" to try the lock again,
then the SAVE_IT() function will return false.
Sample:
**********************************************
************
*** SAVE_IT() function example
***
LOCAL aCustomer := {}
USE Customer NEW INDEX Cust1, Cust2
aCustomer := ARRAY( FCOUNT() )
DbStor( aCustomer, "EMPTY" ) // set original values
** cust1 indexed on cust_nbr
Page: 129
** cust2 indexed on if(dele(),"*"," ")
.
. program statements to
. change array elements to values for new record
.
IF !Save_It( "ADD", aCustomer, 2, "CUSTOMER" )
MsgBox( "ERROR_RECORD NOT ADDED !" )
RETURN
ENDIF
Page: 130
SETMOUSE()
Syntax:
SETMOUSE(<expN1>,<expN2>)
Pass:
<expN1> - Initialize or re-initialize mouse button
status.
<expN2> - Decimal value of keyboard scan code to
place in keyboard buffer on mouse button
action.
Returns:
A numeric integer in the range 0 - 4 inidicating the
mouse button status.
Description:
The SETMOUSE() function should be used to set and set
remove the keyboard scan code only. This function
can most effectively be use in conjunction with the
ADDMPAD() mouse 'hot pad' function. The ADDMPAD()
function will work without SETMOUSE() in most
instances. SETMOUSE() will be needed when adding
mouse functionality to a 'closed' function. A
'closed' function is defined as one where access to
the keyboard loop is not available. Examples of
'closed' functions are MEMOEDIT() and ACHOICE().
Many third part libraries also have non-mouseable
'closed' functions. SETMOUSE() will allow mouse
control of these functions.
The SETMOUSE() returns the last mouse button action
until either reset to zero (0) or another mouse
button is press or released.
0 - Nothing has happened yet.
1 - The left mouse button is currently pressed.
2 - The left mouse button was released.
3 - The right mouse button is currently pressed.
4 - The right mouse button was released.
Example:
// Example of setting up an ACHOICE() with ability
to use the mouse.
// Pressing and holding the left mouse button on the
top or bottom border
// will move the highlight bar up and down just as
if the up and down arrow
// keys were used.
Page: 131
// Also, by releasing the left mouse button inside
the ACHOICE() screen
// area, the option with the mouse cursor on it will
be selected.
LOCAL aCars, nUpIdx, nDnIdx, nEnIdx, nSelect
aCars := {"Bu
ick","Chevrolet","Chrysler","Dodge","Nissan",
; "Toy
ota","Mazda","Volkswagon","Volvo","Ferrari", ;
"Lamborghini","Jaguar"}
// Set up mouse 'hot pads'
nUpIdx :=
AddMPad(10,10,10,23,1,{||__KeyBoard(K_UP)})
nDnIdx :=
AddMPad(16,10,16,23,1,{||__KeyBoard(K_DOWN)})
nEnIdx := AddMPad(11,11,15,22,0,{||MouseEnter()})
// This will activate mouse checking during
ACHOICE()
// Note that 4A00 Hex is the Numeric Keypad Alt
Minus key, whenever
// that key is used, all the mouse 'hot pads' are
checked.
SetMouse( 0, Hex2Dec( "4A00" ) )
WinPush(10,10,16,23)
@ 10, 10, 16, 23 WINDOW STYLE "3+"
nSelect := Achoice( 11, 11, 15, 22, aCars )
IF nSelect > 0
MsgBox(aCars[nSelect]+" Was Selected")
ENDIF
// Be sure to turn it off when not in use.
SetMouse( 0, 0 )
DelMPad( nUpIdx )
DelMPad( nDnIdx )
DelMPad( nEnIdx )
WINDOW REMOVE
// This function executed whenever the left mouse
button is
// released inside the ACHOICE() area
//
Page: 132
FUNCTION MouseEnter()
LOCAL nMouseRow, nMouseCol, nKey
AbMGetRowCol( @nMouseRow, @nMouseCol ) // get
mouse cursor position
IF nMouseRow < Row() // Row() is current
highlight bar row
nKey := K_UP
ELSE
nKey := K_DOWN
ENDIF
KEYBOARD Replicate( Chr( nKey ), Abs(
nMouseRow - Row() ) ) + ;
Chr( K_ENTER )
RETURN( NIL )
Page: 133
SETMSGLIN()
Syntax:
setmsglin([<expC>] | [<expN>])
Pass:
Either a character expression or a numeric expression
only.
Returns:
The text on the screen line set as the message line.
Description:
The SETMSGLIN() function returns the screen text on the
message line. If <expC> is passed then <expC> is
displayed on the message line using the value of
Var(MSG_CLR_ ) as the color value.
The message line defaults to screen line 24. Pass a
numeric value to change the message line to another
screen line. If the message line is set to a value
that is not between zero (0) and MAXROW() then
character expressions subsequently sent to this
function will not display.
SetMsgLin() will return a character value of the
contents of the message line.
Example:
LOCAL cMsgLin
SetMsgLin( 23 ) // Change the message line to
screen row 23
// save what's on line 23 and display a message
there
cMsgLin := SetMsgLin( "Display this on line 23!" )
// redisplay the previous message on line 23
SetMsgLin( cMsgLin )
// Turn the message line off
SetMsgLin( -1 )
SetMsgLin( "This Won't Display" )
Page: 134
SHADOW()
Syntax:
shadow(<expN1>,<expN2>,<expN3>,<expN4>)
Pass:
<expN1> top left row
<expN2> top left column
<expN3> bottom right row
<expN4> bottom right column
Description:
Places a shadow on the area bounded by the four passed
coordinates, where <expN1> and <expN2> are the upper
left row and column coordinates and <expN3> and
<expN4> are the lower right.
Comment:
The BUILDER WinPush() function uses this function to
place a shadow on windows it creates. You,
therefore, should not have to use this function.
Page: 135
SHOW_MEMO()
Syntax:
show_memo(<expN1>,<expN2>,<expN3>,<expN4>,<expC1>, ;
<expL1>[,<expC2>][,<expN5>][,<expL2>])
Pass:
<expN1> - Top row screen coordinate.
<expN2> - Left column screen coordinate.
<expN3> - Bottom row screen coordinate.
<expN4> - Right column screen coordinate.
<expC1> - Memo field database field name.
<expL1> - .F. view only, .T. allow editing.
<expC2> - Color for memo data.
<expN5> - Maximum lines memo may contain. Default
unlimited.
<expL2> - .F. does nothing, .T. starts editing at the
end of the memo text. Default .F.
Description:
The SHOW_MEMO function calls the Clipper MEMOEDIT()
function and provides a few small additional
functions. It does not put a border or title on the
screen. This function is called by the EDT_MEMO()
function. If you want to use your own screen border
and message line use this instead of EDT_MEMO().
The additional functionality is provided by the last
three parameters and are self explanatory.
See EDT_MEMO(), MEMFUNC()
Page: 136
SHOW_TXT()
Syntax:
show_txt(<expC1>,<expN1>,<exp>,<expC2>,<expN2>,<expN3>,
;
<expN4>[,<expC3>])
Pass:
<expC1> - Alias name of database for SEEK.
<expN1> - Index order number of <expC1> for SEEK.
<exp> - Key expression for SEEK.
<expC2> - Screen display expression.
<expN2> - Screen row coordinate for display.
<expN3> - Screen column coordinate for display.
<expN4> - Rightmost screen column to display.
<expC3> - Alternate color choice for display, default
is WMSG_CLR
Returns:
A logical true (.T.).
Description:
The SHOW_TXT() function is a very useful VALID function
that simply puts text on the screen after a user
moves past the field where the SHOW_TXT() VALID is
located.
Sample:
Suppose you have a database for customer purchases and
one of the fields in this database is a Part Number.
This represents the item your customer has
purchased. When the Part Number is keyed you would
like to display the Part Description that corre
sponds to the Part Number. The SHOW_TXT() VALID
function can do this in the following manner:
Technical assumptions:
The customer database is called CUSTOMER and contains a
five byte character field called PART_NBR which
contains the Part Number the customer purchased.
The look up table database with the part descriptions
is called PARTS and index order one (1) is on the
PART_NBR field.
The PARTS database part description field is called
PART_DESC.
.
.
Page: 137
.
** add the DBSEEK()/Message() to have the display of
the
** Part Description on PgUp's and PgDn's
**
Parts->( DBSEEK( cPart_Nbr, .F. ) )
Message( Parts->Part_Desc, WinTop()+10, WinLeft()+2,
WinRight()-2, Var( WMSG_CLR_ ) )
**
@ 09,16 WINGET cPart_Nbr PICTURE "!!!!!" VALID ;
Show_Txt( "PARTS", 1, cPart_Nbr, Parts-
>Part_Desc, ;
WinTop()+10,WinLeft()+2,WinRight()-2)
.
.
Page: 138
TEXTVIEW()
Syntax:
textview(<expN1>,<expN2>,<expN3>,<expN4>,<expC1> ;
[,<expL>][,<expC2>])
Pass:
<expN1> - Top row screen coordinate.
<expN2> - Left column screen coordinate.
<expN3> - Bottom row screen coordinate.
<expN4> - Right column screen coordinate.
<expC1> - Name of a CR/LF delimited text file,
include the extension.
<expL> - Print key enable/disable. Pass .T. to
enable or .F. to disable. Default is
disabled.
<expC2> - Name of a user defined function to program
alternate keystrokes and use TEXTVIEW passed
parameters.
Description:
The TEXTVIEW function simply displays a CR/LF (carriage
return/line feed) delimited text file within the
passed screen coordinates, <expN1> through <expN4>.
The advantage of this function over the MEMOEDIT()
function provided by Clipper is that TEXTVIEW can
view any size file whereas MEMOEDIT() is restricted
to a maximum of 64K (If you can spare the memory!).
TEXTVIEW does not read the whole file into memory,
only the portion of the file currently displayed is
in memory, so TEXTVIEW uses very little of the
programs available memory.
Passing <expC2> the programmer can customize TEXTVIEW
by examining the parameters passed and writing
custom routines for viewing text files.
The parameters passed to the UDF are:
<expN1> - The leftmost column of the file currently
being displayed.
<expC> - The status of TEXTVIEW when the UDF was
called:
"BF" - Beginning of File.
"EF" - End of File.
"BP" - Beginning to Print.
"EP" - End of Print.
<expN2> - Length of the longest record in the
current display window.
<expN3> - INKEY() value of the last key pressed.
Page: 139
<expN4> - The file handle of the text file being
viewed.
The return value from the UDF MUST be a logical value,
if your function returns true (.T.) then the screen
will be refreshed. If your function returns false
(.F.) then the screen will not be changed.
Sample:
A TEXTVIEW call with a UDF to display a report file.
.
.
.
SETCOLOR( Var( WNDW_CLR_ ) )
@ 05, 05, 20, 75 WINDOW STYLE "3+"
SetMsgLin( "²
"+chr(27)+chr(26)+"/TAB/Shft+TAB/"+chr(24)+chr
(25)+ ;
"/PgUp/PgDn/Home/End-Scroll ² Alt+P-Print ²
ESC-Exit ²" )
@ WinTop(), WinRight()-12 SAY Chr( 181 ) +
"REPORT.TXT" + Chr( 198 )
SETCOLOR( Var( WMSG_CLR_ ) )
TextView( WinTop()+1, WinLeft()+1, WinBott()-1,
WinRight()-1, "REPORT.TXT", .T., "TEXTFUNC" )
SETCOLOR( Var( WNDW_CLR_ ) )
WINDOW REMOVE
**********************************************
***************
** Example function called by TEXTVIEW text file
viewer with examples
** of how to use the passed parameters.
**********************************************
***************
FUNCTION TextFunc( nLeft, cStatus, nMaxWidth, nKey,
nHandle )
LOCAL cOldColor
**********************************************
***********
** nLeft - Leftmost column position in the current
display window.
** cStatus - BF-Beginning of File; EF-End of File; BP-
Begin of Print;
Page: 140
** EP-End of Print; or nul if no status to
report.
** nWidth - Character width of the widest record in
the current
** display window.
** nKey - INKEY() value of the last key pressed. Use
nKey to
** program your own keystrokes during a TEXTVIEW.
** nHandle - File handle of file being viewed.
**********************************************
***********
** check all status conditions and display
result
SETCOLOR( Var( WNDW_CLR_ ) )
DO CASE
CASE cStatus == "BF"
@ 0,1 WINSAY Chr( 181 ) + "TOP" + Chr(198)
CASE cStatus == "EF"
@ 0, 1 WINSAY Chr( 181 ) + "BOT" + Chr(198)
CASE cStatus == "BP"
cOldColor := SETCOLOR( )
SETCOLOR( "*" + cOldColor )
@ 0,2 WINSAY "PRT"
SETCOLOR( cOldColor )
CASE cStatus == "EP"
@ 0, 1 WINSAY Chr( 181 ) + " " + Chr( 198 )
OTHERWISE
@ 0, 1 WINSAY Chr( 181 ) + " " + Chr( 198 )
ENDCASE
** display left/right helper arrows if needed
IF nLeft > 1
@ WinBott(), WinLeft() SAY Chr( 27 )
ELSE
@ WinBott(), WinLeft() SAY Chr( 200 )
ENDIF
IF nLeft + ( WinRight() - WinLeft() ) - 2 <
nWidth
@ WinBott(), WinRight() SAY Chr( 26 )
ELSE
@ WinBott(), WinRight() SAY Chr( 188 )
ENDIF
SETCOLOR( Var( WMSG_CLR_ ) )
** Trap CTRL+HOME key and make it do the same
Page: 141
thing as
** the HOME key.
IF nKey = K_CTRL_HOME
FSeek( nHandle, 0, 0 ) // go to the beginning
of the file
RETURN( .T. ) // make TEXTVIEW redisplay window
ENDIF
RETURN (.F. ) // no need to redisplay the
window
Page: 142
THERMOMETR()
Syntax:
thermometr(<expN1>,<expN2>,<expN3>,<expN4>)
Pass:
<expN1> thermometer length
<expN2> start value of operation (i.e. 0%)
<expN3> maximum value of operation (i.e. 100%)
<expN4> current value, must be between <expN2> and
<expN3>
Returns:
A character expression.
Description:
The THERMOMETR() function is used to display the
progress of iterative program activity graphically.
The <expN1> argument is the length you want your
thermometer, <expN2> is the number of the starting
position of your process, <expN3> is the ending
position and <expN4> is the current position.
Sample:
**********************************************
**************
** THERMOMETR() function example
**
Trnsactn->( DBGOTOP() )
nStart := 1
nEnd := LASTREC()
nWidth := 40
cOldThm := " " // old thermometer for comparison
DO WHILE !EOF()
cThm := Thermometr( nwidth, nStart, nEnd,
RECNO() )
IF cThm < > cOldThm // only display changes
@ 1,0 SAY cThm
cOldThm := cThm
ENDIF
.
.
.
Trnsactn->( DBSKIP() )
Page: 143
ENDDO
Page: 144
TIMEOUT()
Syntax:
timeout(<expN1>,<expN2>)
Pass:
<expN1> - Computer idle time in seconds.
<expN2> - Keyboard scan code to put in keyboard
buffer on a timeout condition.
Returns:
"Y" if timeout occured or "N" if not a timeout.
Description:
The TIMEOUT assembly subroutine tests the computer's
keyboard, disk(s), serial port, video interface,
and printer port(s) for activity. If no activity
has occurred and one (1) second has passed, an
internal variable is incremented. If any activity
whatsoever occurs on the computer the internal
variable is set to zero. If the subroutine's
internal variable counter reaches the value passed
as <expN1> then <expN2> is put in the keyboard
buffer as if the key was pressed on the keyboard and
any subsequent calls to TIMEOUT() will be returned a
value of "Y".
So if the computer is completely idle (i.e. NO ACTIVITY
AT ALL) for <expN1> seconds then <expN2> is put in
the keyboard buffer.
WARNING * WARNING * WARNING * WARNING * WARNING
TIMEOUT CANNOT (!) BE USED IN AN OVERLAY. IT TAKES
OVER SYSTEM INTERRUPTS. IF PUT IN AN OVERLAY, YOUR
PROGRAM WILL (WILL !!) CRASH.
WARNING * WARNING * WARNING * WARNING * WARNING
It is up the Clipper program to be set up to deal with
these conditions. See the following example and
also see the program source for DEMO.PRG included in
the BUILDER Demo package.
.
.
.
SET KEY 259 TO TmOut_Xit // Ctrl+2 INKEY() value
** Clipper program to time out after one hour (3600
seconds)
**
Page: 145
** Hex 0300 is the keyboard scan code for Ctrl+2
**
TimeOut( 3600, Hex2Dec( "0300" ) )
.
.
.
** Proc executed on every press of Ctrl+2
** if cIDLE_VAR="Y" then the program timed out, so
set errorlevel and exit.
**
PROCEDURE TmOut_Xit( cPrc, nLin, cVar )
IF TimeOut() != "Y"
RETURN
ENDIF
SET CURSOR ON
SET COLOR TO w/n
ERRORLEVEL( 1 )
CLS
QUIT
Use the following table to find keyboard scan codes:
TIMEOUT Keyboard Scan Codes
Key Normal Shifted w/Ctrl w/Alt
A 1E61 1E41 1E01 1E00
B 3062 3042 3002 3000
C 2E63 2E42 2E03 2E00
D 2064 2044 2004 2000
E 1265 1245 1205 1200
F 2166 2146 2106 2100
G 2267 2247 2207 2200
H 2368 2348 2308 2300
I 1769 1749 1709 1700
J 246A 244A 240A 2400
K 256B 254B 250B 2500
L 266C 264C 260C 2600
M 326D 324D 320D 3200
N 316E 314E 310E 3100
O 186F 184F 180F 1800
P 1970 1950 1910 1900
Q 1071 1051 1011 1000
R 1372 1352 1312 1300
S 1F73 1F53 1F13 1F00
T 1474 1454 1414 1400
Page: 146
U 1675 1655 1615 1600
V 2F76 2F56 2F16 2F00
W 1177 1157 1117 1100
X 2D78 2D58 2D18 2D00
Y 1579 1559 1519 1500
Z 2C7A 2C5A 2C1A 2C00
1 0231 0221 7800
2 0332 0340 0300 7900
3 0433 0423 7A00
4 0534 0524 7B00
5 0635 0625 7C00
6 0736 075E 071E 7D00
7 0837 0826 7E00
8 0938 092A 7F00
9 0A39 0A28 8000
0 0B30 0B29 8100
- 0C2D 0C5F 0C1F 8200
= 0D3D 0D2B 8300
[ 1A5B 1A7B 1A1B 1A00
] 1B5D 1B7D 1B1D 1B00
273B 273A 2700
' 2827 2822
' 2960 297E
\ 2B5C 2B7C 2B1C 2600 (same as Alt L)
, 332C 333C
. 342E 343E
/ 352F 353F
F1 3B00 5400 5E00 6800
F2 3C00 5500 5F00 6900
F3 3D00 5600 6000 6A00
F4 3E00 5700 6100 6B00
F5 3F00 5800 6200 6C00
F6 4000 5900 6300 6D00
F7 4100 5A00 6400 6E00
F8 4200 5B00 6500 6F00
F9 4300 5C00 6600 7000
F10 4400 5D00 6700 7100
F11 8500 8700 8900 8B00
F12 8600 8800 8A00 8C00
BackSpace 0E08 0E08 0E7F 0E00
Del 5300 532E 9300 A300
Down Arrow 5000 5032 9100 A000
End 4F00 4F31 7500 9F00
Enter 1C0D 1C0D 1C0A A600
Esc 011B 011B 011B 0100
Home 4700 4737 7700 9700
Page: 147
Ins 5200 5230 9200 A200
Keypad 5 4C35 8F00
Keypad * 372A 9600 3700
Keypad - 4A2D 4A2D 8E00 4A00
Keypad + 4E2B 4E2B 4E00
Keypad / 352F 352F 9500 A400
Left Arrow 4B00 4B34 7300 9B00
PgDn 5100 5133 7600 A100
PgUp 4900 4939 8400 9900
PrtSc 7200
Right Arrow 4D00 4D36 7400 9D00
SpaceBar 3920 3920 3920 3920
Tab 0F09 0F00 9400 A500
Up Arrow 4800 4838 8D00 9800
Some key combinations are not available on all systems.
The PS/2 includes many that aren't available on the
PC, XT and AT.
Page: 148
VAR()
Syntax:
Var(<expN>[,<exp>])
Pass:
<expN> (use one of the manifest constants located in
the file BUILDER.CH instead of a literal) for the
Aeolus Builder system variable to retrieve.
Optionally pass <exp> to set system variable <expN>.
Not passing <exp> will cause system variable <expN>
to be unchanged.
Returns:
The Aeolus Builder system variable requested. This can
be any data type.
Description:
Use this function to get and set the Aeolus Builder
system variables. The following list shows the
manifest constants and their associated meaning:
NETWORK logical Defines whether record locking
should be used.
XPLODE logical Defines whether to pop or explode
windows onto the screen.
WREV_CLR_ character Window Reverse color.
WGET_CLR_ character Window GET color.
WMSG_CLR_ character Window message or enhanced color.
WERR_CLR_ character Window error color.
WNDW_CLR_ character Window color.
HDR_CLR_ character Screen header border color.
HDR_MSG_ character Screen header message color.
BREV_CLR_ character Background reverse color.
BGET_CLR_ character Background GET color.
BKGD_CLR_ character Background color.
BMSG_CLR_ character Background message color.
BERR_CLR_ character Background error color.
WNDW2_CLR_ character Window "2" color.
WMSG2_CLR_ character Window "2" message color.
SHDW_CLR_ character Shadow color.
ERR_CLR_ character Error color.
MSG_CLR_ character Message line color.
HELP_CLR_ character Help color.
BRWS_CLR_ character Browse color.
BRWS_REV_ character Browse pointer color.
BRWS_HL1_ character Browse highlight one color.
BRWS_HR1_ character Browse pointer for highlight one.
BRWS_HL2_ character Browse highlight two color.
Page: 149
BRWS_HR2_ character Browse pointer for highlight two.
MENU_CLR_ character Menu color.
MENU_REV_ character Menu pointer color.
HLGT_CLR_ character Menu speed key color.
Sample:
For example, to set the color to "WNDW_CLR_" you would
write the following line of code:
SETCOLOR( Var( WNDW_CLR_ ) )
Remember that to use these manifest constants you must
have a '#Include "Builder.Ch"' pre-processor
directive at the beginning of your program.
Page: 150
VARINIT()
Syntax:
VARINIT()
Pass:
Nothing.
Returns:
Nothing
Description:
This function is intended to be used only once during
the initialization of an Aeolus Builder program. It
simply sets the Aeolus Builder system variables to
their default values.
See: VAR()
Page: 151
WAITKEY()
Syntax:
waitkey([<expN>])
Pass:
<expN> timeout seconds
Returns:
A numeric expression.
Description:
Use WAITKEY() as a substitute for the Clipper
INKEY([<expN>]) function. The difference between
the two is that WAITKEY() will react to SET KEY TO
... 's you have set and WAITKEY() will react to
mouse inputs using the BUILDER mouse routines. Not
passing the parameter or passing zero (the default)
will cause WAITKEY() to wait until a key is pressed
with no timeout.
Page: 152
WINBOTT()
Syntax:
WinBott()
Pass:
Nothing.
Returns:
The current window bottom border screen row number.
Description:
The WinBott() function is useful when positioning
display items inside Builder windows. This function
is used extensively to create the WINDOW, WINSAY,
WINGET, and WINPROMPT commands. See the Builder.ch
file for how this is used.
Page: 153
WINLEFT()
Syntax:
WinLeft()
Pass:
Nothing.
Returns:
The current window left border screen column number.
Description:
The WinLeft() function is useful when positioning
display items inside Builder windows. This function
is used extensively to create the WINDOW, WINSAY,
WINGET, and WINPROMPT commands. See the Builder.ch
file for how this is used.
Page: 154
WINPOP()
Syntax:
winpop()
Pass:
Nothing
Returns:
A logical value, true if there was something removed
from the screen.
Description:
The WINPOP() function removes the last window on the
screen that was created by the WINPUSH function.
See WINPUSH() for examples.
Page: 155
WINPUSH()
Syntax:
winpush(<expN1>,<expN2>,<expN3>,<expN4>[,<expL1>] ;
[,<expL2>][,<expL3>][,<expL4>][,<expC1>][,<expC2>])
Pass:
<expN1> top left row
<expN2> top left column
<expN3> bottom right row
<expN4> bottom right column
<expL1> save the screen area before displaying,
default true
<expL2> clear the interior of the box, default true
<expL3> display the box with a border, default true
<expL4> display the box with a shadow, default true
<expC1> border style for window. Default is Var(
WNDW_STYLE )
<expC2> Alternate window color.
Returns:
A logical value, if the window was successfully
displayed, true is returned.
Description:
The WINPUSH function saves the portion of the screen
bounded the coordinates <expN1> through <expN4> with
<expN1> and <expN2> being the upper left row and
column positions and <expN3> and <expN4> the lower
right corner positions and draws a box on the screen
in the default color.
All four of the logical expressions that can optionally
be passed have a default value of true.
If <expL1> is true the screen area bounded by the
passed screen coordinates is saved to the screen
array otherwise if set to false and it cannot be
WINPOPed.
<expL2> if set to true will clear the box interior
otherwise only the border, if any, is displayed.
The default it true.
<expL3> if set to true will display a double border on
the box.
<expL4> controls the shadow on the box, if set to true
a shadow is displayed otherwise the shadow is not
displayed.
Page: 156
<expC1> Border style to use on the window. Use the
Builder manifest constants located in the Builder.ch
header file or any two characters and the first
character will be used as the horizontal border
character and the second the vertical border. In
the beginning of the Builder.ch header file are six
manifiest constants that begin with W_, these will
tell WinPush() to use the high ASCII screen
graphics.
W_DOUBLE - Double border
W_SINGLE - Single border
W_DOUBLE_SINGLE - Double horizontal, single vertical
W_SINGLE_DOUBLE - Single horizontal, double vertical
W_3D_PLUS - 3d pulling out of screen
W_3D_MINUS - 3d pushing into screen
Note: If the system variable Var(XPLODE) is a logical
variable set to true the WINPUSH function will
explode the window onto the screen.
Sample:
**********************************************
************
*** WINPUSH/WINPOP sample code
***
** put a window on the screen saving the area so it
can be WINPOPed,
** clearing the inside of the window when displayed,
put double border
** characters on the window, and put a shadow on the
window.
WinPush( 05, 10, 17, 60 )
@ 07,12 SAY "My Window to the World."
Waitkey()
** remove window, and shadow.
WinPop()
Page: 157
WINRIGHT()
Syntax:
WinRight()
Pass:
<indent 3/4 inch> Nothing.
Returns:
The current window right border screen column number.
Description:
The WinRight() function is useful when positioning
display items inside Builder windows. This function
is used extensively to create the WINDOW, WINSAY,
WINGET, and WINPROMPT commands. See the Builder.ch
file for how this is used.
Page: 158
WINSTYLE()
Syntax:
WinStyle()
Pass:
Nothing.
Returns:
The two byte character string of the current window's
border style.
Description:
This function is useful when placing other border
characters on a window. By using the return value,
you can know what characters to use that will look
right on a window. See the Builder.ch header file,
near the beginning are six manifest constants that
begin with W_. These are the main border styles
that would be returned by a call to WinStyle().
Page: 159
WINTOP()
Syntax:
WinTop()
Pass:
Nothing.
Returns:
The current window top border screen row number.
Description:
The WinTop() function is useful when positioning
display items inside Builder windows. This function
is used extensively to create the WINDOW, WINSAY,
WINGET, and WINPROMPT commands. See the Builder.ch
file for how this is used.