Home of the original IBM PC emulator for browsers.
The following document is from the Microsoft Programmer’s Library 1.3 CD-ROM.
BASIC Language Reference
────────────────────────────────────────────────────────────────────────────
Microsoft(R) BASIC Language Reference
for IBM(R) Personal Computers and Compatibles
────────────────────────────────────────────────────────────────────────────
Information in this document is subject to change without notice and
does not represent a commitment on the part of Microsoft Corporation.
The software described in this document is furnished under a license
agreement or nondisclosure agreement. The software may be used or copied
only in accordance with the terms of the agreement. It is against the
law to copy the software on any medium except as specifically allowed in
the license or nondisclosure agreement. No part of this manual may be
reproduced or transmitted in any form or by any means, electronic or
mechanical, including photocopying and recording, for any purpose
without the express written permission of Microsoft.
Copyright 1989, Microsoft Corporation. All rights reserved.
Simultaneously published in the U.S. and Canada.
Printed and bound in the United States of America.
Microsoft, MS, MS-DOS, and CodeView are registered trademarks of
Microsoft Corporation.
Apple and Macintosh are registered trademarks of Apple Computer,
Inc.
Helvetica and Times Roman are registered trademarks of Linotype AG
and its subsidiaries.
Hercules is a registered trademark and InColor is a trademark of
Hercules Computer Technology.
IBM is a registered trademark of International Business Machines
Corporation.
Intel is a registered trademark of Intel Corporation.
Olivetti is a registered trademark of Ing. C. Olivetti.
WordStar is a registered trademark of MicroPro International
Corporation.
Document No. DB0118-700-R00-1089
Introduction
────────────────────────────────────────────────────────────────────────────
The printed documentation for Microsoft BASIC 7.0 Professional Development
System consists of three books: Getting Started, the BASIC Language
Reference, and the Programmer's Guide.
Getting Started contains detailed information on setting up and customizing
Microsoft BASIC to optimize program size and speed. It also introduces new
features of this version of Microsoft BASIC and provides a brief
introduction to the new Microsoft Advisor online Help system.
The BASIC Language Reference has these parts:
■ Part 1, "Language Reference," contains reference material and
programming examples for each BASIC function, statement, and
metacommand, organized alphabetically.
■ Part 2, "Add-On-Library Reference," contains reference material on the
SUB and FUNCTION procedures that are supported by the add-on
libraries included with Microsoft BASIC. These add-on libraries give
you date/time, financial, and format functions.
■ Part 3, "BASIC Toolbox Reference," contains reference material on the
SUB and FUNCTION procedures that are supported by the toolbox files
included with Microsoft BASIC. The toolboxes are Matrix Math,
Presentation Graphics, Font, and User Interface.
■ The appendixes include a list of keyboard scan and ASCII character
codes, a list of BASIC reserved words, a command-line tools quick
reference, reference information on error messages, and international
character sort order tables.
The Programmer's Guide contains topical information about programming
concepts and techniques and command-line tools.
Document Conventions
This manual uses the following typographic conventions:
Part 1 is a reference for each function, statement, and metacommand in the
BASIC language. Each entry is listed alphabetically and describes the action
performed, and the syntax to use. Arguments, options, and typical usage are
explained further under "Remarks." The "See Also" sections refer you to
related entries. In addition, example programs are included with the
descriptions so you can see exactly how a function or statement works.
In the beginning of Part 1 are summary tables for selected BASIC functions
and statements. Each table contains entries that perform related tasks.
Within each table, you can quickly see specific tasks you can accomplish,
the functions or statements to use, and the actions that result.
BASIC Functions and Statements
The sections in this chapter are made up of related BASIC functions and
statements that have been grouped together according to programming tasks.
Each group's functions and statements are presented in tabular form, listing
the type of task performed by each function or statement (for example,
looping or searching), and the corresponding program action that takes
place.
The following topics are summarized:
* Control-flow functions and statements
* Procedure-related statements
* Standard I/O functions and statements
* File I/O functions and statements
* ISAM File I/O functions and statements
* String-processing functions and statements
* Graphics functions and statements
* Trapping functions and statements
You can use these tables both as a reference guide to what each statement or
function does and as a way to identify related statements.
Note
Not all BASIC functions and statements are listed in these tables, only
those recommended for structured programming. For complete information on
all functions and statements, see the alphabetic entries that follow these
tables.
Control-Flow Functions and Statements
Looping
-------
FOR...NEXT
Repeats statements between FOR and NEXT a specific number of times.
EXIT FOR
Provides an alternative way to exit a FOR...NEXT loop.
DO...LOOP
Repeats statements between DO and LOOP, either until a given condition is
true (DO...LOOP UNTIL condition), or while a given condition is true
(DO...LOOP WHILE condition).
EXIT DO
Provides an alternative way to exit a DO...LOOP loop.
WHILE...WEND
Repeats statements between WHILE and WEND while a given condition is true
(similar to DO WHILE condition...LOOP).
Making decisions
----------------
IF...THEN...ELSE
END IF
Conditionally executes or branches to different statements.
SELECT CASE
END SELECT
Conditionally executes different statements.
Managing the stack
------------------
STACK Function
Returns maximum stack size that can be allocated.
STACK Statement
Sets stack to new size.
Exiting the program
-------------------
END number
SYSTEM number
STOP number
Exit the program and set error level defined by number. If number is not
present, exit the program with error level set to 0.
Procedure-Related Statements
Defining a procedure
--------------------
FUNCTION...
END FUNCTION
Marks the beginning and end, respectively, of a FUNCTION procedure.
SUB...END SUB
Marks the beginning and end, respectively, of a SUB procedure.
Calling a procedure
-------------------
CALL
Transfers control to a BASIC SUB procedure, or to a procedure written in
another programming language and compiled separately. (The CALL keyword is
optional if a DECLARE statement is used.)
Exiting from a procedure
------------------------
EXIT FUNCTION
Provides an alternative way to exit a FUNCTION procedure.
EXIT SUB
Provides an alternative way to exit a SUB procedure.
Declaring a reference to a procedure
------------------------------------
DECLARE
Declares a FUNCTION or SUB procedure and, optionally, specifies the number
and type of its parameters.
Sharing variables among modules, procedures, or programs
--------------------------------------------------------
COMMON
Shares variables among separate modules. When used with the SHARED
attribute, COMMON blocks share variables among different procedures in the
same module. When used with a blank (unnamed) COMMON block, variables pass
from current program to new program when control is transferred with the
CHAIN statement.
SHARED
When used with the COMMON, DIM, or REDIM statement at the module level (for
example, DIM SHARED), shares variables with every SUB or FUNCTION procedure
in a single module.
When used by itself within a procedure, shares variables between that
procedure and the module-level code.
Preserving variable values
--------------------------
STATIC
Forces variables to be local to a procedure or DEF FN function and preserves
the value stored in the variable if the procedure or function is exited,
then called again.
Standard I/O Functions and Statements
Printing text on the screen
---------------------------
PRINT
Outputs text to the screen. Using PRINT with no arguments creates a blank
line.
PRINT USING
Outputs formatted text to the screen.
Changing the width of the output line
-------------------------------------
WIDTH
Changes the width of the screen to either 40 columns or 80 columns. Also, on
computers with an EGA or VGA, controls the number of lines on the screen (25
or 43).
WIDTH "SCRN:"
Assigns a maximum length to lines output to the screen when used before an
OPEN "SCRN:" statement.
Getting input from the keyboard
-------------------------------
INKEY$
Reads a character from the keyboard (or a null string if no character is
waiting).
INPUT$
Reads a specified number of characters from the keyboard and stores them in
a single string variable.
INPUT
Reads input from the keyboard and stores it in a list of variables.
LINE INPUT
Reads a line of input from the keyboard and stores it in a single string
variable.
Positioning the cursor on the screen
------------------------------------
LOCATE
Moves the cursor to a specified row and column. Also sets cursor size and
turns it on and off.
SPC
Skips a specified number of spaces in printed output.
TAB
Displays printed output in a given column.
Getting information on cursor location
--------------------------------------
CSRLIN
Tells which row or line position the cursor is in.
POS(n)
Tells which column the cursor is in.
Creating a text viewport
------------------------
VIEW PRINT
Sets the top and bottom rows for displaying text output.
File I/O Functions and Statements
Creating a new file or accessing an existing file or device
-----------------------------------------------------------
OPEN
Opens a file or device for retrieving or storing records (I/O).
Closing a file or device
------------------------
CLOSE
Ends I/O to a file or device.
Storing data in a file
----------------------
PRINT #
Stores a list of variables as record fields in a previously opened file.1
PRINT # USING
Similar to PRINT #, except PRINT # USING formats the record fields.1
WRITE #
Stores a list of variables as record fields in a previously opened file.1
WIDTH #
Specifies a standard width for each record in a file.1
PUT
Stores the contents of a user-defined variable in a previously opened file.2
Retrieving data from a file
---------------------------
INPUT #
Reads fields from a record and assigns each field in the record to a program
variable.1
INPUT$
Reads a string of characters from a file.
LINE INPUT #
Reads a record and stores it in a single string variable.1
GET
Reads data from a file and assigns the data to elements of a user-defined
variable.2
Getting information about a file
--------------------------------
EOF
Tests whether all data has been read from a file.
FILEATTR
Returns the number assigned by the operating system to an open file and a
number that indicates the mode in which the file was opened (input, output,
append, binary, random, or ISAM).
LOC
Gives the current position within a file. With binary access, this is the
byte position. With sequential access, this is the byte position divided by
128. With random access, this is the record number of the last record read
or written.
LOF
Gives number of bytes in open file.
SEEK Function
Gives the location where the next I/O operation will take place. With random
access, this is the number of the next record to be read or written. With
all other kinds of file access, this is the byte position of the next byte
to be read or written.
Moving around in a file
-----------------------
SEEK Statement
Sets the byte position or record number for the next read or write operation
in an open file.
Managing disk drives, directories, and files
--------------------------------------------
CHDRIVE
Changes the current drive.
CURDIR$
Gives current directory specifica-tion for specified drive (or current drive
if no drive is specified).
DIR$
On first call, returns the first file that matches the file specification.
On successive calls (with no argument), returns remaining files matching the
file specification.
FILES
Prints a listing of the files in a specified directory.
FREEFILE
Returns next available file number.
KILL
Deletes a file from the disk.
NAME
Changes a file's name.
1 For use with sequential files.
2 For use with binary or random-access files.
ISAM File I/O Functions and Statements
Opening and closing tables and databases
----------------------------------------
OPEN database$ FOR ISAM tabletype tablename$
AS #█ filenumber%
Opens a database or creates a new database, opens a table or creates a new
table.
CLOSE
Closes a specified table.
TYPE tabletype
columnname AS tablename
{columnname AS typename}
END TYPE
Declares the type of the record that is used to build the table.
Managing the data dictionary
----------------------------
CREATEINDEX
Creates an index.
DELETEINDEX
Deletes an index.
Positioning
-----------
MOVEFIRST
Makes the first record current.
MOVELAST
Makes the last record current.
MOVENEXT
Makes the next record current.
MOVEPREVIOUS
Makes the previous record current.
SEEKEQ
SEEKGE
SEEKGT
Makes matching record current.
SETINDEX
Makes the named index the current index.
Getting information about a table
---------------------------------
BOF
Returns TRUE when the current position is beyond the first record of the
current index.
EOF
Returns TRUE when the current position is beyond the last record of the
current index.
FILEATTR
Returns information about an open ISAM table.
GETINDEX$
Returns name of the current index.
LOF
Returns the number of records in a table.
Exchanging data
---------------
INSERT
Inserts a record in a table.
RETRIEVE
Retrieves the current record.
UPDATE
Overwrites current record.
DELETE
Deletes the current record.
Transaction processing
----------------------
BEGINTRANS
Marks the beginning of a transaction.
CHECKPOINT
Saves all currently open databases to disk.
COMMITTRANS
Commits all changes since the most recent BEGINTRANS.
ROLLBACK
Rolls back data to its state at the savepoint.
ROLLBACK ALL
Rolls back state of database to beginning of current transaction.
SAVEPOINT%
Defines a savepoint and returns savepoint's reference number.
Comparing text
--------------
TEXTCOMP
Compares two strings as they would be compared by ISAM.
String-Processing Functions and Statements
Getting part of a string
------------------------
LEFT$
Returns given number of characters from the left side of a string.
RIGHT$
Returns given number of characters from the right side of a string.
LTRIM$
Returns a copy of a string with leading spaces stripped away.
RTRIM$
Returns a copy of a string with trailing spaces stripped away.
MID$ function
Returns given number of characters from anywhere in a string.
Calculating available memory space
----------------------------------
FRE(a$)
For far strings, returns the space remaining in a$'s segment. For near
strings, compacts string storage space and returns space remaining in
DGROUP.
FRE(literal string)
For far strings, returns the space remaining in the temporary string
segment. For near strings, compacts string storage space and returns space
remaining in DGROUP.
FRE(number)
Measures available storage for strings, nonstring arrays, or the stack.
Searching strings
-----------------
INSTR
Searches for a string within another string.
Converting to uppercase or lowercase letters
--------------------------------------------
LCASE$
Returns a copy of a string with all uppercase letters (A-Z) converted to
lowercase letters (a-z); leaves lowercase letters and other characters
unchanged.
UCASE$
Returns a copy of a string with all lowercase letters (a-z) converted to
uppercase letters (A-Z); leaves uppercase letters and other characters
unchanged.
Changing strings
----------------
MID$ Statement
Replaces part of a string with another string.
LSET
Left justifies a string within a fixed-length string.
RSET
Right justifies a string within a fixed-length string.
Converting between numbers and strings
--------------------------------------
STR$
Returns the string representation of the value of a numeric expression.
VAL
Returns the numeric value of a string expression.
Creating strings of repeating characters
----------------------------------------
SPACE$
Returns a string of blank characters of a specified length.
STRING$
Returns a string consisting of one repeated character.
Getting the length of a string
------------------------------
LEN
Tells how many characters are in a string.
Working with ASCII values
-------------------------
ASC
Returns the ASCII value of the given character.
CHR$
Returns the character with the given ASCII value.
Creating string pointers
------------------------
SSEG
Returns the segment of the string data.
SADD
Returns the offset of the string data.
SSEGADD
Returns a far pointer to the string data.
VARPTR
Returns the offset address of a variable or string descriptor.
VARSEG
Returns the segment address of a variable or string descriptor.
Graphics Functions and Statements
Setting screen- display characteristics
---------------------------------------
SCREEN Statement
Specifies a BASIC screen mode, which determines screen characteristics such
as graphics capability, resolution, and color-number range.
SCREEN Function
Returns a character's ASCII value or its color from a specified screen
location.
Plotting or erasing a single point
----------------------------------
PSET
Draws a pixel on the screen in the specified color, using the screen's
foreground color as default.
PRESET
Draws a pixel on the screen in the specified color, using the screen's
background color as default.
Drawing shapes
--------------
LINE
Draws a straight line or a box.
CIRCLE
Draws a circle, ellipse, arc, or pie.
DRAW
Draws an object. Combines many of the features of other BASIC graphics
statements into a graphics macro language.
Defining screen coordinates
---------------------------
VIEW
Specifies a rectangle on the screen (or viewport) as the area for graphics
output.
WINDOW
Defines the dimensions of the current viewport.
PMAP
Maps view coordinates to window coordinates, or vice versa.
POINT(number)
Returns the screen coordinates of the graphics cursor, or the color of a
specified pixel.
Using color
-----------
COLOR
Sets the default colors used in graphics output.
PALETTE
Assigns different attributes to color numbers. Works only on systems
equipped with an EGA or VGA.
POINT(x, y)
Returns the color number of a pixel whose screen coordinates are x and y.
Painting enclosed shapes
------------------------
PAINT
Fills an area on the screen with a color or pattern.
Animating
---------
GET
Copies a rectangular area on the screen by translating the image to numeric
data and storing the data in a numeric array.
PUT
Displays an image on the screen that was previously copied with GET.
PCOPY
Copies one screen page to another.
Trapping Functions and Statements
Trapping errors while a program is running
------------------------------------------
ON ERROR GOTO line
At the module level, causes a program to branch to line, where line refers
to either a line number or line label. Branching takes place whenever an
error occurs during execution.
ON LOCAL ERROR
GOTO line
At the procedure level, causes a program to branch to line, where line
refers to either a line number or line label. Branching takes place whenever
an error occurs during execution of the procedure.
ON ERROR RESUME NEXT
At the module level, causes an implicit error trap, then RESUME NEXT.
Returns the error number in ERR.
ON LOCAL ERROR RESUME NEXT
At the procedure level, causes an implicit error trap, then RESUME NEXT.
Returns the error number in ERR.
RESUME
Returns control to the program after executing an error-handling routine.
The program resumes at either the statement causing the error (RESUME), the
statement after the one causing the error (RESUME NEXT), or the line
identified by line (RESUME line)
Getting error-status data
-------------------------
ERR Function
Returns the code for an error that occurs at run time.
ERR Statement
Sets ERR to an integer.
ERL
Returns the number of the line on which an error occurred (if program has
line numbers).
ERDEV
Returns a device-specific error code for the last device (such as a printer)
for which the system detected an error.
ERDEV$
Returns the name of the last device for which the system detected an error.
Defining your own error codes
-----------------------------
ERROR
Simulates the occurrence of a BASIC error; can also be used to define an
error not trapped by BASIC.
Trapping events while a program is running
------------------------------------------
ON event GOSUB line
Causes a branch to the subroutine starting with line, where line refers
either to a line number or line label, whenever event occurs during
execution.
event ON
Enables trapping of event.
event OFF
Disables trapping of event.
event STOP
Suspends trapping of event.
EVENT ON
Enables event trapping.
EVENT OFF
Disables event trapping.
RETURN
Returns control to the program after executing an event-handling subroutine.
The program resumes at either the statement immediately following the
statement that called the subroutine (RETURN), or the line that is
identified by line (RETURN line).
ABS Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the absolute value of a numeric expression.
Syntax
ABS( numeric-expression#)
Remarks
The absolute value is the unsigned magnitude of its argument. For example,
ABS(-1) and ABS(1) are both 1.
Example
The following example finds an approximate value for a cube root. It uses
ABS to find the difference between two guesses to see if the current
guess is accurate. DEFDBL establishes the default data type for
all variables.
DEFDBL A-Z
Precision = .0000001#
CLS ' Clear the screen.
INPUT "Enter a value: ", Value ' Prompt for input.
' Make the first two guesses.
X1 = 0#: X2 = Value
' Loop until the difference between guesses is
' less than the required precision.
DO UNTIL ABS(X1 - X2) < Precision
X = (X1 + X2) / 2#
' Adjust the guesses.
IF X * X * X - Value < 0# THEN
X1 = X
ELSE
X2 = X
END IF
LOOP
PRINT "The cube root is "; X
Output
Enter a value: 27
The cube root is 2.99999997206032
Absolute Routine
────────────────────────────────────────────────────────────────────────────
Action
Transfers control to a machine-language procedure.
Syntax
CALL Absolute (« argumentlist,» integervariable%)
Remarks
The Absolute routine uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
argumentlist Arguments passed to a
machine-language procedure as
offsets (near pointers) from the
current data segment. Although
arguments are passed as offsets,
the machine-language program is
invoked with a far call.
integervariable% The offset from the current code
Argument Description
────────────────────────────────────────────────────────────────────────────
integervariable% The offset from the current code
segment, set by DEF SEG, to the
starting location of the procedure.
The argument integervariable% is
not passed to the procedure. Your
program may need to execute a DEF
SEG statement before executing
Absolute to set the code segment
for the called routine. Using a
noninteger value for
integervariable% produces
unpredictable results.
Note
The Absolute routine is provided to maintain compatibility with earlier
versions of BASIC. Mixed-language programming using the CALL and DECLARE
statements provides a simpler way to use assembly language with BASIC.
When using the Absolute routine in OS/2 protected mode, be careful not to
refer to an illegal memory address. Before it executes the Absolute
routine, BASIC attempts to get an executable-code-segment alias for the code
you wish to access. If this operation fails, BASIC generates the error
message Permission denied. A safe place to store user-written machine code
is in memory allocated for a conventional BASIC object, such as an array.
To use the Absolute routine in the QBX environment, use the QBX.QLB Quick
library.
To use the Absolute routine outside of the QBX environment, link your progra
with the QBX.LIB file.
The QBX.BI header file contains the necessary declarations for the Absolute
routine.
Basica
Assembly-language programs that are invoked from BASICA and that have string
arguments must be changed, because string descriptors are now 4 bytes long.
For a near-string descriptor, the 4 bytes are the low byte and high byte of
the string length, followed by the low byte and high byte of the string
address. Far-string descriptors also are 4 bytes long, but their structure
is proprietary. For more information on using far-string descriptors, see
Chapter 12, "Mixed-Language Programming" and Chapter 13, "Mixed-Language
Programming with Far Strings" in the Programmer's Guide.
See Also
CALL, CALLS Statements (Non-Basic)
Example
The following example uses Absolute to execute a machine-language program
stored in an array. The program indicates whether a math coprocessor is
installed.
CONST nASMBYTES = 14
DEFINT A-Z
DIM AsmProg(1 TO (nASMBYTES / 2))
' The machine-language program stored as data to read into the array.
AsmBytes:
DATA &H55 : ' PUSH BPSave base pointer.
DATA &H8B, &HEC: ' MOV BP,SP Get our own.
DATA &HCD, &H11: ' INT 11HMake the ROM-BIOS call.
DATA &H8B, &H5E, &H06: ' MOV BX,[BP+6]Get argument address.
DATA &H89, &H07: ' MOV [BX],AXSave list in argument.
DATA &H5D : ' POP BPRestore base pointer.
DATA &HCA, &H02, &H00: ' RET 2Pop argument off stack
'and make far return.
' Poke the machine-language program into the array.
P = VARPTR(AsmProg(1))' Get the starting offset of the array.
DEF SEG = VARSEG(AsmProg(1)) ' Change the segment.
FOR I = 0 TO nASMBYTES - 1
READ J
POKE (P + I), J
NEXT I
' Execute the program. The program expects a single integer argument.
CALL Absolute(X%, VARPTR(AsmProg(1)))
DEF SEG' Restore the segment.
' X% now contains bit-encoded equipment list returned by the system.
' Mask off all but the coprocessor bit (bit 2).
CoProcessor = X% AND &H2
IF CoProcessor = 2 THEN
PRINT "Math coprocessor present."
ELSE
PRINT "No math coprocessor."
END IF
ASC Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a numeric value that is the ASCII code for the first character in a
string expression.
Syntax
ASC( stringexpression$)
Remarks
If the argument stringexpression$ is null, Basic generates the run-time
error message Illegal function call.
See Also
CHR$; Appendix A, "Keyboard Scan Codes and ASCII Character Codes"
Example
The following example uses ASC to calculate a hash value -- an index
value for a table or file -- from a string:
CONST HASHTABSIZE = 101
CLS ' Clear the screen.
INPUT "Enter a name: ",Nm$ ' Prompt for input.
TmpVal = 0
FOR I=1 TO LEN(Nm$)
' Convert the string to a number by summing the values
' of individual letters.
TmpVal = TmpVal + ASC(MID$(Nm$,I,1))
NEXT I
' Divide the sum by the size of the table.
HashValue = TmpVal MOD HASHTABSIZE
PRINT "The hash value is "; HashValue
Output
Enter a name: Bafflegab
The hash value is 66
ATN Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the arctangent of a numeric expression.
Syntax
ATN( numeric-expression)
Remarks
The argument numeric-expression can be of any numeric type.
ATN (arctangent) is the inverse of TAN (tangent). ATN takes the ratio of
two sides of a right triangle ( numeric-expression) and returns the
corresponding angle. The ratio is the ratio of the lengths of the side
opposite the angle and the side adjacent to the angle.
The result is given in radians and is in the range π/2 to π/2 radians,
where π = 3.141593 and π/2 radians = 90 degrees. ATN is calculated in single
precision if numeric-expression is an integer or single-precision value. If
you use any other numeric data type, ATN is calculated in double precision.
To convert values from degrees to radians, multiply the angle (in degrees)
times π/180
(or .0174532925199433). To convert a radian value to degrees, multiply it by
180/π (or 57.2957795130824). In both cases, π ≈ 3.141593.
See Also
COS, SIN, TAN
Example
The following example first finds the tangent of PI/4 and then takes the
arctangent of the value. The result is PI/4.
CONST PI=3.141592653
PRINT ATN(TAN(PI/4.0)), PI/4.0
Output
78539816325 .78539816325
BEEP Statement
────────────────────────────────────────────────────────────────────────────
Action
Makes a sound through the speaker.
Syntax
BEEP
Remarks
The BEEP statement makes a sound through the loudspeaker. This statement
makes the same sound as the following statement:
PRINT CHR$(7)
Example
The following example uses BEEP to indicate an error in the response:
CLS ' Clear the screen.
DO
INPUT "Hear a beep (Y or N)"; Response$
R$ = UCASE$ (MID$ (Response$,1,1))
IF R$ <> "Y" OR R$ = "N" THEN EXIT DO
BEEP
LOOP
BEGINTRANS Statement
────────────────────────────────────────────────────────────────────────────
Action
Indicates the beginning of a transaction (a series of ISAM database
operations).
Syntax
BEGINTRANS
Remarks
Transactions are a way to group a series of ISAM operations so that you can
commit them
as a whole, rescind them all, or rescind operations since a designated
savepoint. Use the COMMITTRANS statement to commit a transaction. Use the
SAVEPOINT function to designate a savepoint. Use the ROLLBACK and ROLLBACK
ALL statements to rescind all or part of a transaction's operations.
If you attempt to use BEGINTRANS when there already is a transaction
pending, BASIC generates the error message Illegal function call.
Any ISAM operation that closes a table causes transactions to be committed.
For example, if a type mismatch occurs while you are opening an ISAM table,
the table is closed and a pending transaction is committed.
You may wish to code your programs so they open all tables, then perform all
transactions, then close tables. Make sure any operation that can close a
table occurs outside a transaction.
See Also
COMMITTRANS, ROLLBACK, SAVEPOINT
Example
The following example uses the DELETE statement to remove records from an
ISAM file. It creates a transaction with the BEGINTRANS and COMMITTRANS
statements, and uses SAVEPOINT and ROLLBACK to provide rollback of any or
all of the deletions.
The program uses the file called BOOKS.MDB, which SETUP copies to your disk.
DEFINT A-Z
TYPE Borrower
Cardnum AS LONG ' Card number.
TheName AS STRING * 36 ' Name.
Address AS STRING * 50 ' Address.
City AS STRING * 26 ' City.
State AS STRING * 2 ' State.
Zip AS LONG ' Zip code.
END TYPE
DIM People AS Borrower ' Record structure variable.
CONST Database = "BOOKS.MDB" ' Name of the disk file.
CONST Tablename = "Cardholders" ' Name of the table.
CONST viewbottom = 17, viewtop = 3, msgtxt = " *** Deleted: Savepoint "
DIM SavePts(viewbottom - viewtop + 1)
TableNum = FREEFILE
OPEN Database FOR ISAM Borrower Tablename AS TableNum
' Loop until user chooses to quit.
DO
VIEW PRINT
CLS : COLOR 15, 0
PRINT SPC(34); "Card Holders"
PRINT "Card#"; SPC(2); "Name"; SPC(13); "Address";
PRINT SPC(20); "City"; SPC(6); "State"; SPC(2); "Zip"
LOCATE 24, 1: PRINT "Choose a key: ";
PRINT "D - Delete this record N - Next record Q - Quit";
MOVEFIRST TableNum
VIEW PRINT viewtop TO viewbottom: COLOR 7, 0: CLS
vPos = viewtop
' Loop through a screenful of records.
DO
' For each record, display and ask user what to do with it.
RETRIEVE TableNum, People
LOCATE vPos, 1
PRINT USING ("#####"); People.Cardnum;
PRINT " "; LEFT$(People.TheName, 15); " ";
PRINT LEFT$(People.Address, 25); " ";
PRINT LEFT$(People.City, 10); " "; People.State; " ";
PRINT USING ("#####"); People.Zip
' Get keystroke from user.
validkeys$ = "DNQ"
DO
keychoice$ = UCASE$(INKEY$)
LOOP WHILE INSTR(validkeys$, keychoice$) = 0 OR keychoice$ = ""
' Process keystroke.
SELECT CASE keychoice$
CASE "D"
IF NOT inTransaction THEN
inTransaction = -1
BEGINTRANS
END IF
NumSavePts = NumSavePts + 1
SavePts(NumSavePts) = SAVEPOINT
DELETE TableNum
LOCATE vPos, 7: PRINT msgtxt; NumSavePts; SPC(79 - POS(0));
CASE "Q"
EXIT DO
CASE "N"
MOVENEXT TableNum
END SELECT
vPos = vPos + 1
LOOP UNTIL EOF(TableNum) OR vPos = viewbottom
' If user didn't delete any records, simply quit.
IF NumSavePts = 0 THEN EXIT DO
' Allow user to commit deletions, or roll back some or all of them.
VIEW PRINT: LOCATE 24, 1: PRINT "Choose a key: ";
PRINT "R - Rollback to a savepoint A - Rollback all deletions"
PRINT SPC(17); "Q - commit deletions and Quit";
validkeys$ = "RAQ"
DO
keychoice$ = UCASE$(INKEY$)
LOOP WHILE INSTR(validkeys$, keychoice$) = 0 OR keychoice$ = ""
SELECT CASE keychoice$
CASE "R"
VIEW PRINT 24 TO 25: PRINT : PRINT
DO
PRINT "Roll back to which savepoint ( 1 -"; NumSavePts; ")";
INPUT RollbackPt
LOOP UNTIL RollbackPt > 0 AND RollbackPt <= NumSavePts
ROLLBACK SavePts(RollbackPt)
NumSavePts = RollbackPt - 1
CASE "A"
NumSavePts = 0
ROLLBACK ALL
CASE "Q"
EXIT DO
END SELECT
LOOP
IF inTransaction THEN COMMITTRANS
CLOSE
END
BLOAD Statement
────────────────────────────────────────────────────────────────────────────
Action
Loads a memory-image file created by BSAVE into memory from an input file
or device.
Syntax
BLOAD filespec$«, offset%»
Remarks
The BLOAD statement allows a program or data saved as a memory-image file
to be loaded anywhere in memory. A memory-image file is a byte-for-byte copy
of what was originally in memory.
The BLOAD statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
Argument Description
────────────────────────────────────────────────────────────────────────────
filespec$ A string expression that specifies
the file or device from which to
load a memory-image file.
offset% The offset of the address where
loading is to start.
The starting address for loading is determined by the specified offset and
the most recent DEF SEG statement. If offset% is omitted, the segment
address and offset contained in the file (the address used in the BSAVE
statement) are used. Thus, the file is loaded at the address used when
saving the file.
If you supply an offset, the segment address used is the segment set by the
most recently executed DEF SEG statement. If there has been no DEF SEG
statement, the BASIC data segment (DGROUP) is used as the default.
If the offset is a long integer, or a single-precision or double-precision
number, it is converted to an integer. If the offset is a negative number
between -1 and -32,768, inclusive, it is treated as an unsigned 2-byte
offset.
Note
Programs written in earlier versions of BASIC no longer work if they use
VARPTR to access numeric arrays.
Because BLOAD does not perform an address-range check, it is possible to
load a file anywhere in memory. You must be careful not to write over BASIC
or the operating system.
Because different screen modes use memory differently, do not load graphic
images in a screen mode other than the one used when they were created.
Because BASIC program code and data items are not stored in the same
locations as they were in BASICA, do not use BLOAD with files created by
BASICA programs.
BLOAD and Expanded Memory Arrays
Do not use BLOAD to load a file into an expanded memory array. If you start
QBX with the /Ea switch, any of these arrays may be stored in expanded
memory:
■ Numeric arrays less than 16K in size.
■ Fixed-length string arrays less than 16K in size.
■ User-defined-type arrays less than 16K in size.
If you want to use BLOAD to load a file into an array, first start QBX
without the /Ea switch. (Without the /Ea switch, no arrays are stored in
expanded memory.)
For more information on using expanded memory, see "Memory Management for
QBX" in Getting Started.
BASICA
BLOAD does not support the cassette device.
See Also
BSAVE; DEF SEG; SSEG; VARPTR, VARSEG
Example
The following example uses BLOAD to retrieve and display a drawing of a
magenta cube inside a box. The BSAVE statement programming example shows
how the drawing was created and saved on disk in a file named MAGCUBE.GRH.
You must create the file MAGCUBE.GRH using the BSAVE statement programming
example before you can run this program.
DIM Cube(1 TO 675)
' Set the screen mode. The mode should be the same as the
' mode used to create the original drawing.
SCREEN 1
' Set segment to the array Cube's segment and load
' the graphic file into Cube.
DEF SEG = VARSEG(Cube(1))
BLOAD "MAGCUBE.GRH", VARPTR(Cube(1))
DEF SEG ' Restore default BASIC segment.
' Put the drawing on the screen.
PUT (80, 10), Cube
BOF Function
Action
Tests whether the current position is at the beginning of an ISAM table.
Syntax
BOF( filenumber%)
Remarks
BOF returns true (nonzero) if the current position is at the beginning of
the table. The beginning of an ISAM table is the position before the first
record according to the current index. The argument filenumber% is the
number used in the OPEN statement to open the table.
See Also
EOF, LOC, LOF, OPEN
Example
See the CREATEINDEX statement programming example, which uses the BOF
function.
BSAVE Statement
────────────────────────────────────────────────────────────────────────────
Action
Transfers the contents of an area of memory to an output file or device.
Syntax
BSAVE filespec$, offset%, length%
Remarks
The BSAVE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filespec$ A string expression that specifies
the name of the file or device on
which to save a memory-image file.
offset% The offset of the starting address
of the area in memory to be saved.
length% The number of bytes to save. This
is a numeric expression that
returns an unsigned integer
between 0 and 65,535, inclusive.-
Argument Description
────────────────────────────────────────────────────────────────────────────
The BSAVE statement allows data or programs to be saved as memory-image
files on disk. A memory-image file is a byte-for-byte copy of what is in
memory along with control information used by BLOAD to load the file.
The starting address of the area saved is determined by the offset and the
most recent DEF SEG statement.
Note
Programs written in earlier versions of BASIC no longer work if they use
VARPTR to access numeric arrays.
Because different screen modes use memory differently, do not load graphic
images in a screen mode other than the one used when they were created.
If no DEF SEG statement is executed before the BSAVE statement, the
program uses the default BASIC data segment (DGROUP). Otherwise, BSAVE
begins saving at the address specified by the offset and by the segment set
in the most recent DEF SEG statement.
If the offset is a long integer, or single- or double-precision
floating-point value, it is converted to an integer. If the offset is a
negative number between -1 and -32,768, inclusive, it is treated
as an unsigned 2-byte offset.
BSAVE and Expanded Memory Arrays
Do not use BSAVE to transfer an expanded memory array to an output file.
(If you start QBX with the /Ea switch, any of these arrays may be stored in
expanded memory:
■ Numeric arrays less than 16K in size.
■ Fixed-length string arrays less than 16K in size.
■ User-defined-type arrays less than 16K in size.
If you want to use BSAVE to transfer an array to an output file, first
start QBX without the /Ea switch. (Without the /Ea switch, no arrays are
stored in expanded memory.)
For more information on using expanded memory, see "Memory Management for
QBX" in Getting Started.
BASICA
BSAVE does not support the cassette device.
See Also
BLOAD, DEF SEG
Example
The following example draws a magenta cube inside a white box and then uses
BSAVE to store the drawing in the file MAGCUBE.GRH. The BLOAD statement
programming example shows how you can retrieve and display the drawing after
you create it.
DIM Cube(1 TO 675)
SCREEN 1
' Draw a white box.
LINE (140, 25)-(140 + 100, 125), 3, B
' Draw the outline of a magenta cube inside the box.
DRAW "C2 BM140,50 M+50,-25 M+50,25 M-50,25"
DRAW "M-50,-25 M+0,50 M+50,25 M+50,-25 M+0,-50 BM190,75 M+0,50"
' Save the drawing in the array Cube.
GET (140, 25)-(240, 125), Cube
' Set segment to the array Cube's segment and store the drawing
' in the file MAGCUBE.GRH. Note: 2700 is the number of bytes
' in Cube (4 bytes per array element * 675).
DEF SEG = VARSEG(Cube(1))
BSAVE "MAGCUBE.GRH", VARPTR(Cube(1)), 2700
DEF SEG ' Restore default BASIC segment.
CALL Statement (BASIC Procedures)
────────────────────────────────────────────────────────────────────────────
Action
Transfers control to a BASIC SUB procedure. To invoke a non-BASIC
procedure, use the CALL, CALLS statements (non-BASIC).
Syntax 1
CALL name «( argumentlist)»
Syntax 2
name «( argumentlist)»
Remarks
The CALL statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
name The name, limited to no more than
40 characters, of the BASIC SUB
procedure being called.
argumentlist The variables or constants passed
Argument Description
────────────────────────────────────────────────────────────────────────────
argumentlist The variables or constants passed
to the procedure. Arguments in the
list are separated by commas.
Arguments are passed by reference
(which means they can be changed
by the procedure).
If argumentlist includes an array argument, the array is specified by the
array name followed by empty parentheses:
DIM IntArray(1 TO 20)
.
.
.
CALL ShellSort(IntArray())
If you omit the optional CALL keyword, you must declare the procedure in a
DECLARE statement and omit the parentheses around argumentlist. For more
information, see Chapter 2, "SUB and FUNCTION Procedures" in the
Programmer's Guide.
The CALL statement passes arguments only by reference, which means that the
procedure is given the address of the argument. This allows procedures to
change the argument values.
Although the CALL statement does not pass arguments by value, you can
simulate that by enclosing the argument in parentheses. This makes the
argument an expression. (If an argument is passed by value, the procedure is
given the value of the argument.)
For example, the following statement calls a procedure and passes a single
argument:
CALL SolvePuzzle((StartValue))
Because StartValue is in parentheses, BASIC evaluates it as an expression.
The result is stored in a temporary location, and the address of the
temporary location is passed to the SUB procedure. Any change made by the
procedure SolvePuzzle is made to the temporary location only, and not to
StartValue itself.
See Also
Absolute Routine; CALL, CALLS (Non-BASIC); DECLARE (BASIC)
Example
The following example uses the CALL statement to call a SUB procedure that
prints a message on the 25th line of the display:
CLS' Clear screen.
message$ = "The quick brown fox jumped over the lazy yellow dog."
CALL PrintMessage(message$)
END
SUB PrintMessage (message$)
LOCATE 24, 1 ' Move cursor to 25th line of display.
PRINT message$;
END SUB
CALL, CALLS Statements (Non-BASIC Procedures)
────────────────────────────────────────────────────────────────────────────
Action
Transfer control to a procedure written in another language. To invoke a
BASIC procedure, use the CALL statement (BASIC).
Syntax 1
CALL name «( call-argumentlist)»
Syntax 2
name « call-argumentlist»
Syntax 3
CALLS name «( calls-argumentlist)»
Remarks
The CALL keyword is optional when you use the CALL statement. When you
omit CALL, you must declare the procedure in a DECLARE statement. When you
omit CALL, you omit the parentheses around the argument list. For more
information about invoking procedures without the CALL keyword, see Chapter
2, "SUB and FUNCTION Procedures" in the Programmer's Guide.
CALLS is the same as using CALL with a SEG before each argument: every
argument in a CALLS statement is passed as a segmented address.
The CALL and CALLS statements use the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
name The name of the non-BASIC
procedure being called.
call-argumentlist The variables, arrays, or
expressions passed to the
procedure.
calls-argumentlist The variables or expressions
CALLS passes to the procedure.
The call-argumentlist has two forms of syntax. In the first form, argument
is a variable:
««{BYVAL|SEG}»argument» «,«{BYVAL|SEG}»argument»...
If argument is an array, parentheses are required:
«argument«( )»» «, argument «( )»»...
The following list describes the parts of call-argumentlist:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
BYVAL Indicates the argument is passed
by value rather than by near
reference (the default is by
reference). BYVAL cannot be used
if the argument is an array.
SEG Passes the argument as a segmented
Part Description
────────────────────────────────────────────────────────────────────────────
SEG Passes the argument as a segmented
(far) address. SEG cannot be used
if the argument is an array.
argument A BASIC variable, array, or
expression passed to a procedure.
Use the first syntax if
argument is not an array; use the second if argument is an array. The
array is specified by the array name and a pair of parentheses. For example:
DIM IntArray(20) AS INTEGER
.
.
.
CALL ShellSort(IntArray) AS INTEGER
The argument calls-argumentlist has the following syntax, where argument
is a BASIC variable or expression:
« argument» «, argument»...
These arguments are passed by reference as far addresses, using the segment
and offset of the variable. Whole array arguments cannot be passed by calls.
The result of the BYVAL keyword differs from BASIC's pass by value:
CALL Difference (BYVAL A,(B))
For the first argument, only the value of A is passed to Difference. In
contrast, (B) is evaluated, a temporary location is created for the value,
and the address of the temporary location is passed to Difference.
You can use BASIC's pass by value for an argument, but the procedure in the
other language must accept an address (because the address of the temporary
location is passed).
Note
If the argument name refers to an assembly-language procedure, it must be a
name declared with PUBLIC (symbol).
Be careful using the SEG keyword to pass elements of arrays because BASIC
may move arrays in memory before the called routine begins execution.
Anything in an argument list that causes memory movement may create
problems. You can safely pass variables using SEG if the CALL statement's
argument list contains only simple variables, arithmetic expressions, or
arrays indexed without the use of intrinsic or defined functions.
See Also
CALL (BASIC); DECLARE (BASIC); DECLARE (Non-BASIC)
Example
See the VARPTR function programming example, which uses a CALL statement
to invoke a C function.
CCUR Function
────────────────────────────────────────────────────────────────────────────
Action
Converts a numeric expression to a currency value.
Syntax
CCUR( numeric-expression)
Remarks
The argument numeric-expression can be any numeric expression.
See Also
CDBL, CINT, CLNG, CSNG
Example
The following example passes a double-precision, floating-point value to a
FUNCTION procedure that returns the sales tax, as a currency value, for the
passed value. The returned value has four digits of precision, but it is
displayed in conventional currency value format with two places to the right
of the decimal. CCUR is used to convert from double-precision to currency
data type.
DECLARE FUNCTION GetSalesTax@ (Amount#, percent!)
' $INCLUDE: 'FORMAT.BI'
CONST percent! = 8.1
CLS ' Clear screen.
INPUT "What is the taxable currency amount"; Amount#
PRINT
USCurFmt$ = FormatC$(GetSalesTax@(Amount#, percent!), "$#,###,###,##0.00")
SetFormatCC (49) ' West Germany
WGCurFmt$ = FormatC$(GetSalesTax@(Amount#, percent!), "#.###.###.##0,00")
WGCurFmt$ = WGCurFmt$ + " DM"
PRINT "In the United States, currency is displayed with commas as"
PRINT "numerical separators and a period serves to separate whole from"
PRINT "fractional currency amounts. In some European countries, the"
PRINT "numerical separator is a period, and the comma serves to separate"
PRINT "whole from fractional currency amounts."
PRINT
PRINT "In the US, the tax on $"; Amount#; "at"; percent!; "percent is "
PRINT "displayed as "; USCurFmt$
PRINT
PRINT "In West Germany, the tax on"; Amount#; "DM at"; percent!; "percent"
PRINT "is displayed as "; WGCurFmt$
END
FUNCTION GetSalesTax@ (Amount#, percent!)
GetSalesTax@ = CCUR(Amount# * (percent! * .01))
END FUNCTION
CDBL Function
────────────────────────────────────────────────────────────────────────────
Action
Converts a numeric expression to a double-precision value.
Syntax
CDBL( numeric-expression)
Remarks
The argument numeric-expression can be any numeric expression. This
function has the same effect as assigning the numeric expression to a
double-precision variable.
The results of CDBL are no more accurate than the original expression. The
added digits of precision are not significant unless the expression is
calculated with double-precision accuracy.
See Also
CCUR, CINT, CLNG, CSNG
Example
The following example demonstrates how the precision of the argument affects
the value returned by CDBL:
X = 7/9
X# = 7/9
PRINT X
' Both X# and CDBL(X) will be accurate to only 7 decimal
' places, because 7/9 is evaluated in single precision.
PRINT X#
PRINT CDBL(X)
PRINT 7#/9#' Accurate to 15 decimal places.
Output
.7777778
.7777777910232544
.7777777910232544
.7777777777777778
CHAIN Statement
────────────────────────────────────────────────────────────────────────────
Action
Transfers control from the current program to another program.
Syntax
CHAIN filespec$
Remarks
The argument filespec$ is a string expression that represents the program
to which control is passed. It may include a path. (With DOS 2.1 or earlier
versions, you cannot use CHAIN unless filespec$ provides a complete path,
including drive. Also under DOS 2.1, if the run-time module is in the root
directory, the root directory must be listed in the PATH environment
variable.) Programs running within the QBX environment assume a .BAS
extension (if no extension is given) and cannot chain to executable files
(files with a .COM or .EXE extension). Programs running outside the BASIC
environment assume a .EXE extension and cannot chain to BASIC source files
(files with a .BAS extension).
You can pass variables between programs using the COMMON statement to set
up a blank common block. For more information on passing variables, see the
entry for the COMMON statement.
When you compile a program outside the QBX environment, the BCL70efr.LIB
object-module library does not support COMMON. There are two ways to use
COMMON with chained programs outside the environment:
■ Use the default (BRT70EFR.EXE for DOS and OS/2 real mode; BRT70EFR.DLL
for OS/2 protected mode) by compiling the programs using the option in
the Make EXE dialog box called "EXE Requiring BRT Module."
■ Use BRT70EFR.LIB by compiling from the command line without the /O
option. For more information, see Appendix C, "Command-Line Tools
Quick Reference."
Note
When programs use BRT70EFR.EXE or BRT70EFR.DLL, files are left open during
chaining unless they are explicitly closed with a CLOSE statement. The
filenames BCL70efr.LIB, BRT70EFR.EXE, and BRT70EFR.DLL assume that you
selected these compiler options when you installed BASIC: emulator
floating-point math, far strings, and real mode. If you used different
options, see Chapter 17, "About Linking and Libraries" in the Programmer's
Guide for information about other compiler options.
CHAIN is similar to RUN. The main differences are that RUN closes all
open files and does not support data blocks declared with COMMON.
BASICA
BASICA assumes the extension .BAS. The current version of BASIC assumes an
extension of either .BAS or .EXE, depending on whether the program is run
within the QBX environment or compiled and run outside the environment. If
you omit the file extension, CHAIN works the same in BASICA and in the
current version of BASIC.
The current version of BASIC does not support the all, merge, or delete
option available in BASICA, nor does it allow you to specify a line number.
Without the line-number option, execution always starts at the beginning of
the chained-to program. Thus, a chained-to program that chains back to a
carelessly written chaining program can cause an endless loop.
See Also
CALL (BASIC), Common, RUN
Example
In the following example, the COMMON statement is used to pass variables
between two chained programs. The first program reads in a series of numeric
values, stores the values in an array, then uses the CHAIN statement to
load and run the other program. The second program finds and prints the
average of the values. The first two statements initialize the variables
that are passed to PROG2.
DIM values(1 TO 50)
COMMON values(), NumValues%
' PROG2 creation section.
' The following few lines of code create the second program on the
' disk so that it can load and run with the CHAIN statement. It uses
' PRINT # statements to put the proper BASIC statements in a file.
OPEN "PROG2.BAS" FOR OUTPUT AS #1
PRINT #1, "' PROG2 for the CHAIN and COMMON statements example."
PRINT #1, "DIM X(1 TO 50)"
PRINT #1, "COMMON X(), N%"
PRINT #1, "PRINT"
PRINT #1, "IF N% > 0 THEN"
PRINT #1, " Sum% = 0"
PRINT #1, " FOR I% = 1 TO N%"
PRINT #1, " Sum% = Sum% + X(I%)"
PRINT #1, " NEXT I%"
PRINT #1, " PRINT "; CHR$(34); "The average of the values is";
PRINT #1, CHR$(34); "; Sum% / N%"
PRINT #1, "END IF"
PRINT #1, "END"
CLOSE #1
' End of PROG2 creation section.
CLS
PRINT "Enter values one per line. Type 'END' to quit."
NumValues% = 0
DO
INPUT "-> ", N$
IF I% >= 50 OR UCASE$(N$) = "END" THEN EXIT DO
NumValues% = NumValues% + 1
values(NumValues%) = VAL(N$)
LOOP
PRINT "Press any key to continue... "
DO WHILE INKEY$ = ""
LOOP
CHAIN "PROG2.BAS"
END
CHDIR Statement
────────────────────────────────────────────────────────────────────────────
Action
Changes the current default directory for the specified drive.
Syntax
CHDIR pathname$
Remarks
The argument pathname$ is a string expression identifying the directory
that is to become the default directory. The pathname$ expression must
have fewer than 64 characters. It has the following syntax:
«drive:»«\»directory«\ directory»...
The argument drive is an optional drive specification. If you omit drive,
CHDIR changes the default directory on the current drive.
CHDIR cannot be shortened to CD.
The CHDIR statement changes the default directory but not the default
drive. For example, if the default drive is C, the following statement
changes the default directory on drive D, but C remains the default drive:
CHDIR "D:\TMP"
Use CURDIR$ to return the current directory and CHDRIVE to change the
default drive.
See Also
MKDIR, RMDIR
Example
This example uses the MKDIR statement to create a subdirectory. The AddADir
procedure uses the CHDIR statement with the ON ERROR statement to check if
the subdirectory already exists. If it does not exist, the error-handling
routine traps error 76, prompts the user, and creates the directory.
DECLARE SUB AddADir (DstDir$)
CLS
AddADir "TESTDIR"
SUB AddADir (DestDir$)
ON LOCAL ERROR GOTO ErrHandler'Set up the local error handler.
CurDirName$ = CURDIR$'Preserve the name of the current directory.
CHDIR$ DestDir$'Change to DestDir$ - Error 76 if not exist.
CHDIR$ CurDirName$'Change back to original directory.
EXIT SUB
ErrHandler:
IF ERR = 76 THEN
PRINT "Directory does not exist. Create ?";
Ans$ = INPUT(1)
PRINT Ans$
IF UCASE$(Ans$) = "Y" THEN
MKDIR DestDir$'Make the directory.
PRINT DestDir$; "directory created."
RESUME NEXT
ELSE
PRINT DestDir$; "directory not created."
END IF'Return control to caller.
END IF
RESUME NEXT'Just continue.
END SUB
CHDRIVE Statement
────────────────────────────────────────────────────────────────────────────
Action
Changes the current drive.
Syntax
CHDRIVE drive$
Remarks
The argument drive$ is a string expression that specifies a new default
drive. It must correspond to an existing drive and must be in the range A to
lastdrive, where lastdrive is the maximum drive letter you set in your
CONFIG.SYS file.
If you supply a null argument ("") for drive$, the current drive does not
change. If the argument drive$ is a string, CHDRIVE uses only the first
letter. If you omit drive$, BASIC generates the error message Expected:
Expression (in QBX) or String expression required (outside of QBX).
CHDRIVE is not case sensitive. "C" is the same as "c."
See Also
CHDIR, CURDIR$
Example
The following example demonstrates use of the CHDRIVE statements. It calls
a SUB procedure that evaluates a file specification and changes the
currently logged drive if necessary.
DECLARE SUB ChangeDataDrive (filespec$)
ON ERROR RESUME NEXT
filespec$ = "A:"
ChangeDataDrive filespec$
filespec$ = "C:\DOS"
ChangeDataDrive filespec$
SUB ChangeDataDrive (filespec$)
curdrive$ = LEFT$(CURDIR$, 2) ' Get the current drive.
' Determine if there is a drive name on the filespec.
IF INSTR(1, filespec$, ":") = 2 THEN
newdrive$ = LEFT$(filespec$, 2)
ELSE
newdrive$ = curdrive$
END IF
' Ensure that the new drive is different from the
' currently logged drive.
IF newdrive$ <> curdrive$ THEN
CHDRIVE newdrive$ ' It isn't, so change it.
PRINT "Logged drive changed from "; curdrive$; " to "; newdrive$
ELSE ' It is, so don't change it.
PRINT "New drive same as logged drive. No change occurred."
END IF
END SUB
CHECKPOINT Statement
────────────────────────────────────────────────────────────────────────────
Action
Writes all open ISAM database buffers to disk in their current state.
Syntax
CHECKPOINT
See Also
ROLLBACK, SAVEPOINT
Example
See the programming example for the SEEKGT, SEEKGE, SEEKEQ statements,
which uses the CHECKPOINT statement.
CHR$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a one-character string whose ASCII code is the argument.
Syntax
CHR$( code%)
Remarks
CHR$ is commonly used to send a special character to the screen or printer.
For example, you can send a form feed (CHR$(12)) to clear the screen and
return the cursor to the home position.
CHR$ also can be used to include a double quotation mark (") in a string.
The following line adds a double-quotation-mark character to the beginning
and the end of the string:
Msg$=CHR$(34)+"Quoted string"+CHR$(34)
See Also
ASC; Appendix A, "Keyboard Scan Codes and ASCII Character Codes"
Example
The following example uses CHR$ to display graphics characters in the
extended character set and uses these characters to draw boxes on the
screen:
DEFINT A-Z
' Display two double-sided boxes.
CALL DBox(5,22,18,40)
CALL DBox(1,4,4,50)
END
' SUB procedure to display boxes.
' Parameters:
' Urow%, Ucol%: Row and column of upper-left corner.
' Lrow%, Lcol%: Row and column of lower-right corner.
CONST VERT=186, HORZ=205 ' Extended ASCII graphics characters.
CONST ULEFTC=201, URIGHTC=187, LLEFTC=200, LRIGHTC=188
SUB DBox (Urow%, Ucol%, Lrow%, Lcol%) STATIC
LOCATE Urow%, Ucol% : PRINT CHR$(ULEFTC);' Draw top of box.
LOCATE ,Ucol%+1 : PRINT STRING$(Lcol%-Ucol%,CHR$(HORZ));
LOCATE ,Lcol% : PRINT CHR$(URIGHTC);
FOR I=Urow%+1 TO Lrow%-1' Draw body of box.
LOCATE I,Ucol% : PRINT CHR$(VERT);
LOCATE ,Lcol% : PRINT CHR$(VERT);
NEXT I
LOCATE Lrow%, Ucol% : PRINT CHR$(LLEFTC);' Draw bottom of box.
LOCATE ,Ucol%+1 : PRINT STRING$(Lcol%-Ucol%,CHR$(HORZ));
LOCATE ,Lcol% : PRINT CHR$(LRIGHTC);
END SUB
CINT Function
────────────────────────────────────────────────────────────────────────────
Action
Converts a numeric expression to an integer by rounding the fractional part
of the expression.
Syntax
CINT( numeric-expression)
Remarks
If numeric-expression is not between -32,768 and 32,767, inclusive,
BASIC generates the run-time error message Overflow.
CINT differs from the FIX and INT functions, which truncate, rather than
round, the fractional part. See the example for the INT function for an
illustration of the differences among these functions.
See Also
CCUR, CDBL, CLNG, CSNG, FIX, INT
Example
The following example converts an angle in radians to an angle in degrees
and minutes:
' Set up constants for converting radians to degrees.
CONST PI=3.141593, RADTODEG=180./PI
INPUT "Angle in radians = ",Angle' Get the angle in radians.
Angle = Angle * RADTODEG' Convert radian input to degrees.
Min = Angle - INT(Angle)' Get the fractional part.
' Convert fraction to value between 0 and 60.
Min = CINT(Min * 60)
Angle = INT(Angle)' Get whole number part.
IF Min = 60 THEN' 60 minutes = 1 degree.
Angle = Angle + 1
Min = 0
END IF
PRINT "Angle equals"; Angle; "degrees"; Min; "minutes"
Output
Angle in radians = 1.5708
Angle equals 90 degrees 0 minutes
CIRCLE Statement
────────────────────────────────────────────────────────────────────────────
Action
Draws an ellipse or circle with a specified center and radius.
Syntax
CIRCLE «STEP» (x!,y!), radius!«, «color&» «, «start!» «, «end!» «, aspect!»»
Remarks
The following list describes the parts of the CIRCLE statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
STEP The STEP option specifies that
x! and y! are offsets relative to
current graphics cursor position,
enabling use of relative
coordinates.
x!, y! The screen coordinates for the
center of the circle or ellipse.
radius! The radius of the circle or
ellipse in the units of the
Part Description
────────────────────────────────────────────────────────────────────────────
ellipse in the units of the
current coordinate system, which
is determined by the most recently
executed SCREEN statement, along
with any VIEW or WINDOW
statements.
color& The attribute of the desired color.
See the entries for the COLOR and
SCREEN statements for more
information. The default color is
the foreground color.
start!, end! The start! and end! angles, in
radians, for the arc to draw. The
start! and end! arguments are
used to draw partial circles or
ellipses. The arguments may range
in value from -2π radians to 2π
Part Description
────────────────────────────────────────────────────────────────────────────
in value from -2π radians to 2π
radians, where π ≈ 3.141593. The
default value for start! is 0
radians. The default value for
end! is 2π radians.
To convert values from degrees to
radians, multiply the angle (in
degrees) by π/180 (which equals
.0174532925199433).
If start! is negative, CIRCLE
draws a radius to start! and
treats the angle as positive. If
end! is negative, CIRCLE draws a
radius to end! and treats the
angle as positive. If both start!
and end! are negative, CIRCLE
draws a radius to both start! and
Part Description
────────────────────────────────────────────────────────────────────────────
draws a radius to both start! and
end! and treats the angle as
positive.
The start! angle can be less than
the end! angle. If you specify
end! but not start!, the arc is
drawn from zero to end!; if you
specify start! but not end!, the
statement draws an arc from
start! to 2π.
aspect! The aspect ratio, or the ratio of
the y! radius to the x! radius.
The default value for aspect! is
the value required to draw a round
circle in the screen mode. This
value is calculated as follows:
Part Description
────────────────────────────────────────────────────────────────────────────
aspect! = 4 * ( ypixels/xpixels
)/3
In this formula, xpixels by
ypixels is the screen resolution.
For example, in screen mode 1,
where the resolution is 320 x 200,
the default for aspect! is 4 *
(200/320)/3, or 5/6.
If the aspect ratio is less than
one, radius! is the x! radius.
If aspect is greater than one,
radius! is equal to the y! radius.
To draw a radius to angle 0 (a horizontal line segment to the right), do not
give the angle as -0. Instead, use a very small non-zero value as
shown in the following code fragment, which draws a one-quarter wedge of a
circle.
SCREEN 2
CIRCLE (200,100),60,,-.0001,-1.57
You can omit an argument in the middle of the statement, but you must
include the argument's comma. In the following statement, color& has been
omitted:
CIRCLE STEP (150,200),94,,0.0,6.28
If you omit a trailing argument, do not include its corresponding comma in
the statement.
The CIRCLE statement updates the graphics cursor position to the center of
the ellipse or circle after drawing is complete.
You can use coordinates that are outside the screen or viewport. You can
show coordinates as absolutes, or you can use the STEP option to show the
position of the center point in relation to the previous point of reference.
For example, if the previous point of reference were (10,10), the statement
below would draw a circle with radius 75 and center offset 10 from the
current x coordinate and 5 from the current y coordinate. The circle's
center would be (20,15).
CIRCLE STEP (10,5), 75
Example
The following example first draws a circle with the upper-left quarter
missing. It then uses relative coordinates to position a second circle
within the missing quarter circle. Finally, it uses a different aspect ratio
to draw a small ellipse inside the small circle.
CONST PI=3.141593
SCREEN 2
' Draw a circle with the upper-left quarter missing.
' Use negative numbers so radii are drawn.
CIRCLE (320,100), 200,, -PI, -PI/2
' Use relative coordinates to draw a circle within the missing
' quarter.
CIRCLE STEP (-100,-42),100
' Draw a small ellipse inside the circle.
CIRCLE STEP(0,0), 100,,,, 5/25
' Display the drawing until a key is pressed.
LOCATE 25,1 : PRINT "Press any key to end.";
DO
LOOP WHILE INKEY$=""
CLEAR Statement
────────────────────────────────────────────────────────────────────────────
Action
Reinitializes all program variables, closes any open files, and optionally
sets the stack size.
Syntax
CLEAR «,, stack&»
Remarks
The CLEAR statement performs the following actions:
■ Closes all files and releases the file buffers.
■ Clears all common variables.
■ Sets numeric variables and arrays to zero.
■ Sets all string variables to null.
■ Reinitializes the stack and, optionally, changes its size.
The stack& parameter sets aside stack space for your program. BASIC
takes the amount of stack space it requires, adds the number of bytes
specified by stack&, and sets the stack size to the result.
Note
Two commas are used before stack& to keep BASIC compatible with BASICA.
BASICA included an additional argument that set the size of the data
segment. Because BASIC automatically manages the data segment, the first
parameter is no longer required.
If your program has deeply nested subroutines or procedures, or if you use
recursive procedures, you may want to use a CLEAR statement to increase the
stack size. You also may want to increase the stack size if your procedures
have a large number of arguments.
Clearing the stack destroys the return addresses placed on the stack during
a GOSUB operation. This makes it impossible to execute a RETURN statement
correctly, and BASIC generates a RETURN without GOSUB run-time error
message. If you use a CLEAR statement in a SUB or FUNCTION declaration,
BASIC generates the run-time error message Illegal function call.
BASICA
BASICA programs using CLEAR may require modification. In BASICA programs,
any DEF FN functions or data types declared with DEF type statements are
lost after a CLEAR statement. In compiled programs, this information is not
lost because these declarations are fixed at compile time.
See Also
ERASE, FRE, SETMEM, STACK Function
Example
The following statement clears all program variables and sets aside 2,000
bytes on the stack for the program:
CLEAR ,,2000
CLNG Function
────────────────────────────────────────────────────────────────────────────
Action
Converts a numeric expression to a long (4-byte) integer by rounding the
fractional part of the expression.
Syntax
CLNG( numeric-expression)
Remarks
If numeric-expression is not between -2,147,483,648 and
2,147,483,647, inclusive, BASIC generates the error message Overflow.
See Also
CCUR, CDBL, CINT, CSNG
Example
The following example shows how CLNG rounds before converting the number:
A=32767.45
B=32767.55
PRINT CLNG(A); CLNG(B)
Output
32767 32768
CLOSE Statement
────────────────────────────────────────────────────────────────────────────
Action
Concludes I/O to a file, device, or ISAM table.
Syntax
CLOSE««#»filenumber%«,«#»filenumber%»»...
Remarks
The CLOSE statement complements the OPEN statement.
The argument filenumber% is the number used in the OPEN statement to open
the file, device, or ISAM table. A CLOSE statement with no arguments closes
all open files and devices, including all open ISAM tables.
The association of a file, device, or ISAM table with filenumber% ends when
a CLOSE statement is executed. You then can reopen the file, device, or
table using the same or a different file number.
Any ISAM operation that closes a table causes transactions to be committed.
For example, if a type mismatch occurs while you are opening an ISAM table,
the table is closed and a pending transaction is committed.
You may wish to code your programs so they first open all tables, then
perform all transactions, then close tables. Make sure any operation that
can close a table occurs outside a transaction.
Using a CLOSE statement for a file or device that was opened for sequential
output writes the final buffer of output to that file or device. CLOSE
releases all buffer space associated with the closed file, device, or table.
The CLEAR, END, RESET, RUN, and SYSTEM statements, and the CHAIN
statement when used with the /O command-line option, also close all files,
devices, and tables.
Note
CLOSE commits any pending ISAM transactions.
See Also
END, OPEN, RESET, STOP
Example
See the FREEFILE function programming example, which uses the CLOSE
statement.
CLS Statement
────────────────────────────────────────────────────────────────────────────
Action
Clears various parts of the display screen.
Syntax
CLS «{ 0 | 1 | 2}»
Remarks
There are several ways to use the CLS statement, as described in the
following table:
╓┌──────────┌───────────────────────────────┌────────────────────────────────╖
Statement Condition Operations performed
────────────────────────────────────────────────────────────────────────────
CLS Graphics-screen mode no Clears default graphics
user-defined graphics viewport viewport; regenerates bottom
text line; returns cursor to
the upper-left corner of the
screen.
Graphics-screen mode Clears user-defined graphics
user-defined viewport viewport; does not regenerate
bottom text line; does not
return the cursor to the
upper-left corner of the screen.
In screen mode 0 (text mode) Clears text viewport;
regenerates bottom text line;
Statement Condition Operations performed
────────────────────────────────────────────────────────────────────────────
regenerates bottom text line;
returns the text cursor to the
upper-left corner of the screen.
CLS 0 Any screen mode, combination Clears the screen of all text
of viewports and graphics, except bottom
text line; clears graphics
viewport; regenerates bottom
text line; returns the cursor
to the upper-left corner of the
screen.
CLS 1 Graphics-screen mode with no Clears default graphics
user-defined graphics viewport viewport; does not clear text
viewport; regenerates bottom
text line; returns the cursor
to upper-left corner of the
screen.
Statement Condition Operations performed
────────────────────────────────────────────────────────────────────────────
Graphics-screen mode with Clears user-defined graphics
user-defined graphics viewport viewport; does not clear text
viewport; does not regenerate
bottom text line; does not
return the cursor to the
upper-left corner of the screen.
In screen mode 0 (text mode) Has no effect.
CLS 2 Any screen mode Clears the text viewport (even
if the user-defined text
viewport includes the bottom
line of text, it will not be
cleared); does not clear the
graphics viewport; does not
regenerate the bottom text
line; returns the cursor to
upper-left corner of the screen.
Statement Condition Operations performed
────────────────────────────────────────────────────────────────────────────
upper-left corner of the screen.
The behavior of a particular CLS statement depends on:
■ The CLS statement argument: 0, 1, 2, or none.
■ The current screen mode.
■ Whether a VIEW statement has been executed that has changed the
graphics viewport from the default of the entire screen.
■ Whether a VIEW PRINT statement has been executed that established a
user-defined viewport.
■ Whether a KEY ON statement has been executed that established the
bottom text line as a list of function-key assignments. The bottom
line on the screen may be 25, 30, 43, or 60, depending upon the
current screen mode.
The following fundamentals about the graphics and text viewports determine
how the CLS statement works:
■ Screen mode 0 has only a text viewport. All other screen modes have
both a text and graphics viewport.
■ The default graphics viewport is the entire screen.
■ The default text viewport is the entire screen, except for the bottom
line of text.
■ After a user-defined graphics viewport (or "clipping region") has been
established by execution of a VIEW statement, it is reset to the
default by execution of any of these statements: VIEW without
arguments; CLEAR; any SCREEN statement that changes the screen
resolution.
■ After a user-defined text viewport has been established by execution
of a VIEW PRINT statement, it is reset to the default by execution
of either a VIEW PRINT statement without arguments, or any
text-oriented statement, such as WIDTH, that changes the number of
text columns or text lines on the screen.
■ If the KEY ON statement has been executed and the CLS statement
regenerates the bottom screen line, the CLS statement regenerates the
function-key assignment list. If the KEY ON statement has not been
executed, the CLS statement generates a line of blank characters.
See Also
VIEW, VIEW PRINT, WINDOW
Example
The following example draws random circles in a graphics viewport and prints
to a text viewport. The graphics viewport is cleared after 30 circles have
been drawn. The program clears the text viewport after printing to it 45
times.
RANDOMIZE TIMER
SCREEN 1
' Set up a graphics viewport with a border.
VIEW (5,5)-(100,80),3,1
' Set up a text viewport.
VIEW PRINT 12 TO 24
LOCATE 25,1 : PRINT "Press any key to stop."
' Outside the text viewport.
Count=0
DO
CIRCLE (50,40),INT((35-4) * RND + 5),(Count MOD 4)
' Clear graphics viewport every 30 times.
IF (Count MOD 30)=0 THEN CLS 1
PRINT "Hello. ";
' Clear text viewport every 45 times.
IF (Count MOD 45)=0 THEN CLS 2
Count=Count+1
LOOP UNTIL INKEY$ <> ""
COLOR Statement
────────────────────────────────────────────────────────────────────────────
Action
Sets the foreground and background colors for the display.
Syntax 1
COLOR «foreground&»«, «background&»«, border&»» Screen mode 0 (text only)
Syntax 2
COLOR «background&»«, palette%» Screen mode 1
Syntax 3
COLOR «foreground&» Screen mode 4
Syntax 4
COLOR «foreground&»«, background&» Screen modes 7-10
Syntax 5
COLOR «foreground&» Screen modes 12,13
Remarks
With the COLOR statement, you can set the foreground or background colors
for the display. In screen mode 0, a border color also can be selected. In
screen mode 1, no foreground color can be selected, but one of two
three-color palettes can be selected for use with graphic statements. In
screen modes 4, 12, and 13, only the foreground color can be set.
The COLOR statement does not determine the range of available colors. The
combination of adapter, display, and screen mode determines the color range.
If you use COLOR statement arguments outside these valid ranges, BASIC
generates the error message Illegal function call. For more information, see
the entry for the SCREEN statement.
The COLOR statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
foreground& Text color attribute in screen
mode 0; text or line-drawing
display color in screen mode 4;
text and line-drawing color
attribute in screen modes
7-10, 12, and 13.
background& Color code or color attribute for
screen background.
Argument Description
────────────────────────────────────────────────────────────────────────────
screen background.
border& Color code for the area
surrounding the screen.
palette% In screen mode 1, one of two
three-color palettes: is green,
red, and brown; 1 is cyan, magenta,
and bright white.
The different versions of syntax and their effects in different screen modes
are described in the following table:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Screen mode Syntax and description
Screen mode Syntax and description
────────────────────────────────────────────────────────────────────────────
0 COLOR «foreground&»«, «
background&»«, border&»»
Modifies the current default text
foreground and background colors
and the screen border. The
foreground& color value must be an
integer expression between 0 and
31, inclusive. It determines the
foreground color in text mode --
the default color of text. Sixteen
colors can be selected with the
integers 0-15. A blinking version
of a color is specified by adding
16 to the color number. For
example, a blinking color 7 is
equal to 7 + 16, or 23.
The background& color value is an
Screen mode Syntax and description
────────────────────────────────────────────────────────────────────────────
The background& color value is an
integer expression between 0 and 7,
inclusive, and is the color of the
background for each text character.
Blinking background colors are not
supported.
The border& color, which fills
the screen area outside the text
area, is an integer expression
between 0 and 15, inclusive. Note
that the border& argument has no
effect with the following
adapters: the IBM Enhanced
Graphics Adapter (EGA), the IBM
Video Graphics Array adapter (VGA),
and the IBM Multicolor Graphics
Array adapter (MCGA).
Screen mode Syntax and description
────────────────────────────────────────────────────────────────────────────
1 COLOR «background&»«, palette%»
The background& color value must
be an integer expression between 0
and 3, inclusive.
The argument palette% is an
integer expression with an odd or
even value between 0 and 255,
inclusive. An even value makes
available one set of three default
foreground colors, and an odd
value makes available a different
default set.
The default colors for palette%
are equivalent to the following
PALETTE statements on a system
Screen mode Syntax and description
────────────────────────────────────────────────────────────────────────────
PALETTE statements on a system
equipped with an EGA:
' Definition of the even palette-number set.
COLOR ,0' In screen mode 1, an even palette
' number is equivalent to:
PALETTE 1,2 ' EGA Attribute 1 = color 2 (green)
PALETTE 2,4 ' EGA Attribute 2 = color 4 (red)
PALETTE 3,6 ' EGA Attribute 3 = color 6 (yellow)
' Definition of the odd palette-number set.
COLOR ,1' In screen mode 1, an odd palette
' number is equivalent to:
PALETTE 1,3 ' EGA Attribute 1 = color 3 (cyan)
PALETTE 2,5 ' EGA Attribute 2 = color 5 (magenta)
PALETTE 3,7 ' EGA Attribute 3 = color 7 (white)
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Screen mode Syntax and description
────────────────────────────────────────────────────────────────────────────
Note that in screen mode 1, a
COLOR statement overrides PALETTE
statements that were executed
previously.
4 COLOR «foreground&»
The screen foreground& color
value must be an integer
expression between 0 and 15,
inclusive. This expression sets
the display color associated with
color attribute 1 only. The screen
background color is fixed as black.
7-10 COLOR «foreground&»«,
background&»
The argument foreground&, the
Screen mode Syntax and description
────────────────────────────────────────────────────────────────────────────
The argument foreground&, the
line-drawing color, is a color
attribute. The argument
background&, the screen color, is
a display color.
12, 13 COLOR «foreground&»
The argument foreground&, the
line drawing color, is a color
attribute.
BASIC generates the error message Illegal function call if the COLOR
statement is used in screen modes 2, 3, or 11. Use the PALETTE statements
to set the color in screen mode 11.
The foreground can be the same color as the background, making characters
and graphics invisible. The default background color is black for all
display hardware configurations and all screen modes. This background is
produced by the default display color of 0 associated with the background
color attribute of 0.
In screen modes 12 and 13 you can set the background color by assigning a
color to attribute 0 with a PALETTE statement. For example, to make the
background color 8224 (an olive drab), you would use the following PALETTE
statement:
PALETTE 0,8224
To make the background color bright red-violet, use the following PALETTE
statement:
PALETTE 0, 4128831
In screen mode 11 you can set both the foreground and background color by
assigning a color to attribute 0 with a PALETTE statement.
With an EGA, VGA, or MCGA installed, the PALETTE statement gives you
flexibility in assigning different display colors to the color-attribute
ranges for the foreground&, background&, and border& colors. For more
information, see the PALETTE statement.
See Also
PAINT, PALETTE, SCREEN Statement
Example
The following series of examples show COLOR statements and their effects in
the various screen modes:
SCREEN 0 ' Text mode only.
' Foreground& = 1 (blue), background& = 2 (green), border& = 3 (cyan).
' EGA and VGA boards do not support the border& argument.
COLOR 1, 2, 3
CLS
LOCATE 12, 25: PRINT "Press any key to continue..."
DO : LOOP WHILE INKEY$ = ""
SCREEN 1 ' Set screen to 320 x 200 graphics.
' Background& = 1 (blue).
' Foreground& = even palette number (red, green, yellow).
COLOR 1, 0
LINE (20, 20)-(300, 180), 3, B ' Draw a brown box.
LOCATE 12, 7: PRINT "Press any key to continue..."
DO : LOOP WHILE INKEY$ = ""
' Background& = 2 (green).
' Foreground& = odd palette number (white, magenta, cyan).
COLOR 2, 1
LINE (20, 20)-(300, 180), 3, B ' Draw a bright white box.
LOCATE 12, 7: PRINT "Press any key to continue..."
DO : LOOP WHILE INKEY$ = ""
SCREEN 0 ' Set screen to text mode.
' Foreground& = 7 (white), background& = 0 (black), border& = 0
' (black).
COLOR 7, 0, 0
CLS
END
────────────────────────────────────────────────────────────────────────────
COM Statements
Action
Enable, disable, or suspend event trapping at the COM port.
Syntax
COM( n%) ON
COM( n%) OFFn%)
COM( n%) STOP
Remarks
The argument n% specifies the number of the COM (serial) port; n% can be
either 1 or 2.
COM( n%) ON enables communications-event trapping on COM port n%. If a
character arrives at a communications port after a COM( n%) ON statement,
the routine specified in the ON COM statement is executed.
COM( n%) OFF disables communications-event trapping on COM port n%. No
communications trapping takes place until another COM( n%) ON statement is
executed. Events occurring while trapping is off are ignored.
COM( n%) STOP suspends communications-event trapping on COM port n%. No
trapping takes place until a COM( n%) ON statement is executed. Events
occurring while trapping is suspended are remembered and processed when the
next COM( n%) ON statement is executed. However, remembered events are
lost if COM( n%) OFF is executed
When a communications-event trap occurs (that is, the GOSUB operation is
performed), an automatic COM( n%) STOP is executed so that recursive traps
cannot take place. The RETURN statement from the trapping routine
automatically executes a COM( n%) ON statement unless an explicit COM(
n%) OFF was performed inside the routine.
For more information, see Chapter 9, "Event Handling" in the Programmer's
Guide.
See Also
ON event
Example
The following example opens COM1 and then monitors the COM1 port for input.
It uses the ON COM statement to trap communications events.
CLS
' Set up error handling in case COM1 doesn't exist.
ON ERROR GOTO ErrHandler
OPEN "COM1:9600,N,8,1,BIN" FOR INPUT AS #1
COM(1) ON ' Turn on COM event processing.
ON COM(1) GOSUB Com1Handler' Set up COM event handling.
' Wait for a COM event to occur or a key to be pressed.
DO : LOOP WHILE INKEY$ = ""
COM(1) OFF' Turn off COM event handling.
CLS
END
Com1Handler:
PRINT A$; "Something was typed on the terminal attached to COM1."
RETURN
ErrHandler:
SELECT CASE ERR
CASE 68: PRINT "COM1 is unavailable on this computer.": END
CASE ELSE: END
END SELECT
COMMAND$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the command line used to invoke the program.
Syntax
COMMAND$
Remarks
The COMMAND$ function returns the complete command line entered after your
BASIC program name, including optional parameters. COMMAND$ removes all
leading blanks from the command line and converts all letters to uppercase
(capital letters).
The COMMAND$ function can be used in stand-alone executable files or, if
you are executing from the QBX environment, by using the /CMD command-line
option, or by selecting Modify COMMAND$ on the Run menu.
Examples
The following example breaks the command line into separate arguments and
stores them in an array. Each argument is separated from adjoining arguments
by one or more blanks or tabs on the command line.
' Default variable type is integer in this module.
DEFINT A-Z
' Declare the Comline subprogram, as well as the number and
' type of its parameters.
DECLARE SUB Comline(N, A$(),Max)
DIM A$(1 TO 15)
' Get what was typed on the command line.
CALL Comline(N,A$(),10)
' Print out each part of the command line.
PRINT "Number of arguments = ";N
PRINT "Arguments are: "
FOR I=1 TO N : PRINT A$(I) : NEXT I
' SUB procedure to get command line and split into arguments.
' Parameters: NumArgs : Number of command-line args found.
' Args$() : Array in which to return arguments.
' MaxArgs : Maximum number of arguments array can return.
SUB Comline(NumArgs,Args$,MaxArgs) STATIC
CONST TRUE=-1, FALSE=0
NumArgs=0 : In=FALSE
Cl$=COMMAND$' Get the command line using the COMMAND$ function.
L=LEN(Cl$)' Go through the command line a character at a time.
FOR I=1 TO L
C$=MID$(Cl$,I,1)
' Test for character being a blank or a tab.
IF (C$<>" " AND C$<>CHR$(9)) THEN' Neither blank nor tab.
' Test to see if you're already inside an argument.
IF NOT In THEN' You've found the start of a new argument.
' Test for too many arguments.
IF NumArgs=MaxArgs THEN EXIT FOR
NumArgs=NumArgs+1
In=TRUE
END IF
' Add the character to the current argument.
Args$(NumArgs)=Args$(NumArgs)+C$
ELSE' Found a blank or a tab.
' Set "Not in an argument" flag to FALSE.
In=FALSE
END IF
NEXT I
END SUB
The following is a sample command line and output for a stand-alone
executable file (assumes program name is arg.exe):
arg one two three four five six
Output
Number of arguments = 6
Arguments are:
ONE
TWO
THREE
FOUR
FIVE
SIX
COMMITTRANS Statement
────────────────────────────────────────────────────────────────────────────
Action
Commits all ISAM database operations since the most recent BEGINTRANS
statement.
Syntax
COMMITTRANS
Remarks
COMMITTRANS commits a pending transaction (a series of ISAM database
operations).
Transactions are a way to group a series of operations so that you can
commit them as a whole, rescind them all, or rescind operations since a
designated savepoint. Use BEGINTRANS to indicate the beginning of a
transaction. Use Savepoint to designate a savepoint. Use ROLLBACK and
ROLLBACK ALL to rescind all or part of a transaction's operations.
If you attempt to use COMMITTRANS when there is no transaction pending,
BASIC generates the error message Illegal function call.
COMMITTRANS commits only ISAM operations. It does not affect other BASIC
variables or file types.
Any ISAM operation that closes a table causes transactions to be committed.
For example, if a type mismatch occurs while you are opening an ISAM table,
the table is closed and a pending transaction is committed.
You may wish to code your programs so they first open all tables, then
perform all transactions, then close tables. Make sure any operation that
can close a table occurs outside a transaction.
See Also
BEGINTRANS, checkpoint, ROLLBACK, SAVEPOINT
Example
See the BEGINTRANS statement programming example, which uses the
COMMITTRANS statement.
COMMON Statement
────────────────────────────────────────────────────────────────────────────
Action
Defines global variables for sharing between modules or for chaining to
another program.
Syntax
COMMON «SHARED»«/blockname/» variablelist
Remarks
The following list describes the parts of the COMMON statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
SHARED An optional attribute that
indicates the variables are shared
with all SUB or FUNCTION
procedures in the module. The
SHARED attribute can eliminate the
need for a SHARED statement
inside SUB or FUNCTION
procedures.
blockname A valid BASIC identifier (up to 40
characters) that identifies a
group of variables. Use blockname
to share only specific groups of
variables. You cannot use a
type-declaration character ( %, &,
!, #, @, or $) in the
Part Description
────────────────────────────────────────────────────────────────────────────
!, #, @, or $) in the
identifier.
When blockname is used, the
COMMON block is a named COMMON
block. When blockname is omitted,
the block is a blank COMMON block.
Items in a named COMMON block are
not preserved across a chain to a
new program. See "Using Named
COMMON" and "Using COMMON with
CHAIN" later in this entry.
variablelist A list of variables to be shared
between modules or chained-to
programs. The same variable cannot
appear in more than one COMMON
statement in a module.
Part Description
────────────────────────────────────────────────────────────────────────────
The syntax of variablelist is:
variable«( )» «AS type»«, variable«( )» «AS type»»...
The following list describes the parts of variablelist:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
variable Any valid BASIC variable name. It
is either an array name followed
by ( ), or a variable name.
AS type Declares the type of the variable.
The type may be INTEGER, LONG,
Part Description
────────────────────────────────────────────────────────────────────────────
The type may be INTEGER, LONG,
SINGLE, DOUBLE, STRING (for
variable-length strings), STRING
* length (for fixed-length
strings), CURRENCY, or a
user-defined type.
Note
Older versions of BASIC required the number of dimensions to appear after
the name of a dynamic array in a COMMON statement. The number of dimensions
is no longer required, although BASIC accepts the older syntax to maintain
compatibility with earlier versions.
A COMMON statement establishes storage for variables in a special area that
allows them to be shared between modules or with other programs invoked with
a CHAIN statement.
Because COMMON statements establish global variables for an entire program,
they must appear before any executable statements. All statements are
executable, except the following:
COMMON OPTION BASE
CONST REM
DATA SHARED
DECLARE STATIC
DEFtype TYPE...END TYPE
DIM (for static arrays) All metacommands
Variables in COMMON blocks are matched by
position and type, not by name. Therefore, variable order is significant in
COMMON statements. In the following fragment, it is the order of the
variables in the COMMON statements that links the variables, not the names:
' Main program.
COMMON A, D, E
A = 5 : D = 8 : E = 10
.
.
.
' Common statement in another module.
COMMON A, E, D ' A = 5, E = 8, D = 10
.
.
.
Both static and dynamic arrays are placed in COMMON by using the array name
followed by parentheses. The dimensions for a static array must be set with
integer-constant subscripts in a DIM statement preceding the COMMON
statement. The dimensions for a dynamic array must be set in a later DIM or
REDIM statement. The elements of a dynamic array are not allocated in the
COMMON block. Only an array descriptor is placed in common. For more
information about static and dynamic arrays, see Appendix B, "Data Types,
Constants, Variables, and Arrays" in the Programmer's Guide.
The size of a common area can be different from that in another module or
chained program if a blank COMMON block has been used. When a BASIC program
shares COMMON blocks with a routine in the user library, the calling
program may not redefine the COMMON block to a larger size.
Errors caused by
mismatched COMMON statements are subtle and difficult to find. An easy way
to avoid mismatched COMMON statements is to place COMMON declarations in a
single include file and use the $INCLUDE metacommand in each module.
The following program fragments show how to use the $INCLUDE metacommand to
share a file containing COMMON statements among programs:
' This file is menu.bas.
' $INCLUDE: 'COMDEF.BI'
.
.
.
CHAIN "PROG1"
END
' This file is prog1.bas.
' $INCLUDE: 'COMDEF.BI'
.
.
.
END
' This file is COMDEF.BI.
DIM A(100),B$(200)
COMMON I,J,K,A()
COMMON A$,B$(),X,Y,Z
The next sections discuss using named COMMON blocks and using COMMON when
chaining programs.
Using Named Common
A named COMMON block provides a convenient way to group variables so that
different modules have access only to the common variables they need.
The following program
fragment, which calculates the volume and density of a rectangular prism,
uses named COMMON blocks to share different sets of data with two SUB
procedures. The SUB procedure Volume needs to share only the variables
representing the lengths of the sides (in COMMON block Sides). The SUB
procedure Density also needs variables representing the weight (in COMMON
block Weight).
' Main program.
DIM S(3)
COMMON /Sides/ S()
COMMON /Weight/ C
C=52
S(1)=3:S(2)=3:S(3)=6
CALL Volume
CALL Density
END
' SUB procedure Volume in a separate module.
DIM S(3)
COMMON SHARED /Sides/ S()
SUB Volume STATIC
Vol=S(1)*S(2)*S(3)
.
.
.
END SUB
' SUB procedure Density in a separate module.
DIM S(3)
COMMON SHARED /Sides/ S()
COMMON SHARED /Weight/ W
SUB Density STATIC
Vol=S(1)*S(2)*S(3)
Dens=W/Vol
.
.
.
END SUB
Note
Named COMMON blocks are not preserved across chained programs. Use blank
COMMON blocks to pass variables to a chained program.
Using Common with CHAIN
The COMMON statement provides the only way to pass the values of variables
directly to a chained program. To pass variables, both programs must contain
COMMON statements. Remember that variable order and type are significant,
not variable names. The order and type of variables must be the same for all
COMMON statements communicating between chaining programs.
Although the order and type of variables is critical for making sure the
right values are passed, the COMMON blocks do not have to be the same size.
If the COMMON block in the chained-to program is smaller than the COMMON
block in the chaining program, the extra COMMON variables in the chaining
program are discarded. If the size of the COMMON block in the chained-to
program is larger, then additional COMMON numeric variables are initialized
to zero. Additional string variables are initialized to null strings.
Static arrays passed in a COMMON block by the chaining program must be
declared as static in the chained-to program. Similarly, dynamic arrays
placed in common by the chaining program must be dynamic in the chained-to
program.
Note
When you compile a program with the /O option, common variables are not
preserved across the chain. To preserve values across a chain, you must
compile without the /O option (using BC) or by selecting the EXE Requiring
BRT Module option in the Make EXE File dialog box (using QBX).
See Also
CALL (BASIC), CHAIN, FUNCTION, SUB
Example
See the CHAIN statement programming example, which uses the COMMON
statement.
CONST Statement
Action
Declares symbolic constants for use in place of values.
Syntax
CONST constantname = expression , « constantname = expression»...
Remarks
The CONST statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
constantname A name that follows the same rules
as a BASIC variable. You can add a
type-declaration character ( %, &,
!, #, @, or $) to
indicate its type, but this
character is not part of the name.
expression An expression that consists of
literals (such as 1.0), other
constants, or any of the
arithmetic and logical operators
except exponentiation (^). You
also can use a single literal
string such as "Error on input".
You cannot use string
concatenation, variables,
Argument Description
────────────────────────────────────────────────────────────────────────────
concatenation, variables,
user-defined functions, or
intrinsic functions--such as
SIN or CHR$--in expressions
assigned to constants.
If you use a type-declaration character in the name, you can omit the
character when the name is used, as shown in the following example:
CONST MAXDIM% = 250
.
.
.
DIM AccountNames$(MAXDIM)
If you omit the type-declaration character, the constant is given a type
based on the expression in the CONST statement. Strings always yield a
string constant. With numeric expressions, the expression is evaluated and
the constant is given the simplest type that can represent the constant. For
example, if the expression gives a result that can be represented as an
integer, the constant is given an integer type.
Note
Names of constants are not affected by DEF type statements such as DEFINT.
A constant's type is determined either by an explicit type-declaration
character or by the type of the expression.
Constants must be
defined before they are referred to. The following example produces an error
because the constant ONE is not defined before it is used to define TWO
(constants are defined from left to right):
CONST TWO = ONE + ONE, ONE = 1
Note
You cannot use ASCII 01 and 02 in string constants if you are going to
compile to an executable program. The compiler (BC.EXE) uses ASCII 01 and 02
internally to represent End-of-Statement and End-of-Line, respectively. You
can, however, still use 1 and 2 within the QBX environment.
Constants declared in a SUB or FUNCTION procedure are local to that
procedure. A constant declared outside a procedure is defined throughout the
module. You can use constants anywhere that you would use an expression.
A common programming practice is to use a statement such as the following
(any non-zero value represents "true"):
TRUE=-1
Using constants offers several advantages over using variables for constant
values:
■ You only need define constants once for an entire module.
■ Constants cannot be inadvertently changed.
■ In stand-alone programs, using constants produces faster and often
smaller code than
variables.
■ Constants make programs easier to modify.
Example
The following example uses the CONST statement to declare symbolic
constants for the ASCII values of nonprinting characters such as tab and
line feed. Constants also make programs easier to modify. The program counts
words, lines, and characters in a text file. A word is any sequence of
nonblank characters.
DEFINT a-z
CONST BLANK = 32, ENDFILE = 26, CR = 13, LF = 10
CONST TABC = 9, YES = -1, NO = 0
CLS ' Clear screen.
' Get the filename from the command line.
FileName$=COMMAND$
IF FileName$="" THEN
INPUT "Enter input filename: ",FileName$
IF FileName$="" THEN END
END IF
OPEN FileName$ FOR INPUT AS #1
Words=0
Lines=0
Characters=0
' Set a flag to indicate you're not looking at a
' word, then get the first character from the file.
InaWord=NO
DO UNTIL EOF(1)
C=ASC(INPUT$(1,#1))
Characters=Characters+1
IF C=BLANK or C=CR or C=LF or C=TABC THEN
' If the character is a blank, carriage return,
' line feed, or tab, you're not in a word.
IF C=CR THEN Lines=Lines+1
InaWord=NO
ELSEIF InaWord=NO THEN
' The character is a printing character,
' so this is the start of a word.
InaWord=YES' Count the word and set the flag.
Words=Words+1
END IF
LOOP
PRINT Characters, Words, Lines
END
COS Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the cosine of an angle given in radians.
Syntax
COS( x)
Remarks
The argument x can be of any numeric type.
The cosine of an angle in a right triangle is the ratio between the length
of the side adjacent to the angle and the length of the hypotenuse.
COS is calculated in single precision if x is an integer or
single-precision value. If you use any other numeric data type, COS is
calculated in double precision.
To convert values from degrees to radians, multiply the angle (in degrees)
times π/180
(or .0174532925199433). To convert a radian value to degrees, multiply it by
180/π (or 57.2957795130824). In both cases, π ≈ 3.141593.
See Also
ATN, SIN, TAN
Example
The following example plots the graph of the polar equation r = nq for
values of n from 0.1-1.1. This program uses the conversion factors x =
cos(q) and y = sin(q) to change polar coordinates to Cartesian coordinates.
The figure plotted is sometimes known as the Spiral of Archimedes.
CONST PI = 3.141593
SCREEN 1 : COLOR 7' Gray background.
WINDOW (-4,-6)-(8,2) ' Define window large enough for biggest spiral.
LINE (0,0)-(2.2 * PI,0),1' Draw line from origin to the right.
' Draw 10 spirals.
FOR N = 1.1 TO .1 STEP -.1
PSET (0,0)' Plot starting point.
FOR Angle = 0 TO 2 * PI STEP .04
R = N * Angle' Polar equation for spiral.
' Convert polar coordinates to Cartesian coordinates.
X = R * COS(Angle)
Y = R * SIN(Angle)
LINE -(X,Y),1' Draw line from previous point to new point.
NEXT Angle
NEXT N
CREATEINDEX Statement
────────────────────────────────────────────────────────────────────────────
Action
Creates an index consisting of one or more columns of an ISAM table.
Syntax
CREATEINDEX «#»filenumber%, indexname$, unique%, columnname$«,
columnname$»...
Remarks
The CREATEINDEX statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the table.
indexname$ The indexname$ is the name of the
index until the index is
Argument Description
────────────────────────────────────────────────────────────────────────────
index until the index is
explicitly deleted. It follows the
ISAM naming conventions (details
are provided later in this entry).
unique% A non-zero value for unique%
indicates the index is
unique--no two indexed values
can be the same. A value of zero
for unique% means the indexed
values need not be unique.
columnname$ Names the column or columns to be
indexed. The name follows the ISAM
naming conventions. If more than
one column name is given,
CREATEINDEX defines an index based
on the combination of their values.
The argument columnname$ must
Argument Description
────────────────────────────────────────────────────────────────────────────
The argument columnname$ must
appear in the TYPE statement used
when the table was created.
When you initially open a table, the current index is the null index. The
null index represents the order in which records were added to the file.
Once an index has been created, it can be used any number of times until it
is deleted from the database.
Use SETINDEX to make an index the current index and impose its order on the
presentation of records in a table.
Note
Columns that are arrays, user-defined types, or strings longer than 255
characters cannot be indexed.
ISAM names use the following conventions:
■ They have no more than 30 characters.
■ They use only alphanumeric characters (A-Z, a-z, 0-9).
■ They begin with an alphabetic character.
■ They include no BASIC special characters.
See Also
DELETEINDEX, GETINDEX$, SETINDEX
Example
This example uses the CREATEINDEX, SETINDEX and DELETEINDEX statements to
index an ISAM file in several ways. It displays records from the file using
the GETINDEX$ and BOF functions and the MOVEFIRST, MOVELAST, MOVENEXT,
and MOVEPREVIOUS statements.
The program uses a file called BOOKS.MDB, the sample ISAM file that SETUP
copies to your disk.
DEFINT A-Z
TYPE BookRec
IDNum AS DOUBLE ' Unique ID number for each book.
Title AS STRING * 50 ' Book's title.
Publisher AS STRING * 50 ' Book's publisher.
Author AS STRING * 36 ' Book's author.
Price AS CURRENCY ' Book's price.
END TYPE
DIM Library AS BookRec ' Record structure variable.
DIM msgtxt AS STRING
CONST Database = "BOOKS.MDB" ' Name of the disk file.
CONST TableName = "BooksStock" ' Name of the table.
tablenum = FREEFILE ' File number.
OPEN Database FOR ISAM BookRec TableName AS tablenum
CREATEINDEX tablenum, "A", 0, "Author"
CREATEINDEX tablenum, "I", 1, "IDnum"
CREATEINDEX tablenum, "T", 0, "Title"
CREATEINDEX tablenum, "C", 0, "Price"
' Display static instructions.
CLS : LOCATE 13, 30
PRINT "Choose a key:"
PRINT SPC(9); "Move to:"; TAB(49); "Order by: X"
PRINT : PRINT SPC(9); "F - First record"; TAB(49); "A - Author"
PRINT : PRINT SPC(9); "L - Last record"; TAB(49); "I - ID Number"
PRINT : PRINT SPC(9); "N - Next record"; TAB(49); "T - Title"
PRINT : PRINT SPC(9); "P - Previous record"; TAB(49); "C - Cost"
PRINT : PRINT SPC(9); "Q - Quit"; TAB(49); "X - No order"
LOCATE 3, 1: PRINT TAB(37); "Books"
PRINT STRING$(80, "-");
VIEW PRINT 5 TO 10 ' Set viewport for displaying records.age.
MOVEFIRST tablenum
DO
' Display current record.
CLS
RETRIEVE tablenum, Library
PRINT "Author: "; Library.Author;
PRINT TAB(49); "ID #"; Library.IDNum
PRINT "Title: "; Library.Title
PRINT "Publisher: "; Library.Publisher
PRINT "Cost: "; Library.Price
PRINT SPC(30); msgtxt
PRINT STRING$(64, "-");
IF GETINDEX$(tablenum) = "" THEN
PRINT STRING$(15, "-");
ELSE
PRINT "Index in use: "; GETINDEX$(tablenum);
END IF
' Get keystroke from user.
validkeys$ = "FLNPQATICX"
DO
Keychoice$ = UCASE$(INKEY$)
LOOP WHILE INSTR(validkeys$, Keychoice$) = 0 OR Keychoice$ = ""
msgtxt = ""
' Move to appropriate record, or change indexes.
SELECT CASE Keychoice$
CASE "F"
MOVEFIRST tablenum
CASE "L"
MOVELAST tablenum
CASE "N"
MOVENEXT tablenum
IF EOF(tablenum) THEN
MOVELAST tablenum
BEEP: msgtxt = "** At last record **"
END IF
CASE "P"
MOVEPREVIOUS tablenum
IF BOF(tablenum) THEN
MOVEFIRST tablenum
BEEP: msgtxt = "** At first record **"
END IF
CASE "Q"
EXIT DO
CASE ELSE 'User chose an index.
VIEW PRINT
LOCATE 13, 59: PRINT Keychoice$;
VIEW PRINT 5 TO 10
IF Keychoice$ = "X" THEN Keychoice$ = ""
SETINDEX tablenum, Keychoice$
MOVEFIRST tablenum
END SELECT
LOOP
' User wants to quit, so reset viewport, delete indexes and close files.
VIEW PRINT
DELETEINDEX tablenum, "A"
DELETEINDEX tablenum, "I"
DELETEINDEX tablenum, "T"
DELETEINDEX tablenum, "C"
CLOSE
END
CSNG Function
────────────────────────────────────────────────────────────────────────────
Action
Converts a numeric expression to a single-precision value.
Syntax
CSNG( numeric-expression)
Remarks
The CSNG function has the same effect as assigning numeric-expression to a
single-precision variable.
CSNG rounds the value, if necessary, before converting it.
See Also
CCUR, CDBL, CINT, CLNG
Example
The following example shows how CSNG rounds before converting the value:
A#=975.3421115#
B#=975.3421555#
PRINT A#; CSNG(A#); B#; CSNG(B#)
Output
975.3421115 975.3421 975.3421555 975.3422
CSRLIN Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the current line (row) position of the cursor.
Syntax
CSRLIN
Remarks
To return the current column position, use the POS function.
See Also
LOCATE, POS
Example
The following example uses a SUB procedure that prints a message on the
screen without disturbing the current cursor position:
' Move cursor to center of screen, then print message.
' Cursor returned to center of screen.
LOCATE 12,40
CALL MsgNoMove("A message not to be missed.",9,35)
INPUT "Enter anything to end: ",A$
' Print a message without disturbing current cursor position.
SUB MsgNoMove (Msg$,Row%,Col%) STATIC
CurRow%=CSRLIN ' Save the current line.
CurCol%=POS(0) ' Save the current column.
' Print the message at the given position.
LOCATE Row%,Col% : PRINT Msg$;
' Move the cursor back to original position.
LOCATE CurRow%, CurCol%
END SUB
CURDIR$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the path currently in use for the specified drive.
Syntax
CURDIR$«( drive$)»
Remarks
The argument drive$ is a string expression that specifies a drive.
The argument drive$ must be in the range A to lastdrive, where lastdrive
is the maximum drive letter you set in your CONFIG.SYS file.
If no drive is specified or if drive$ is a null string, CURDIR$ returns
the path for the currently selected drive. This is similar to using the
CHDIR command at the system prompt without specifying a path.
BASIC generates an error if the first character in drive$ lies outside the
range A to lastdrive, unless you are working in a networked environment.
BASIC also generates an error if the first character in drive$ corresponds
to a drive that does not exist, or if the first character of drive$ is not
a letter.
CURDIR$ is not case sensitive. "C" is the same as "c."
See Also
CHDIR, CHDRIVE, DIR$
Example
See the example for the CHDRIVE statement, which uses the CURDIR$
function.
CVI, CVL, CVS, CVD, and CVC Functions
────────────────────────────────────────────────────────────────────────────
Action
Converts strings containing numeric values to numbers.
Syntax
CVI( 2-byte-string)
CVL( 4-byte-string)
CVS( 4-byte-string)
CVD( 8-byte-string)
CVC( 8-byte-string)
Remarks
CVI, CVL, CVS, CVD, and CVC are used with a FIELD statement to read
numbers from a random-access file. These functions take strings defined in
the FIELD statement and convert them to a value of the corresponding
numeric type. The functions are the inverse of MKI$, MKL$, MKS$, MKD$,
and MKC$.
The following table describes these string conversion functions:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Function Description
────────────────────────────────────────────────────────────────────────────
CVSMBF Converts 4-byte-string containing
a Microsoft-Binary-format number
to a single-precision IEEE-format
number.
CVDMBF Converts 8-byte-string containing
a Microsoft-Binary-format number
to a double-precision IEEE-format
number.
DATA Statement
────────────────────────────────────────────────────────────────────────────
Action
Stores the numeric and string constants used by a program's READ
statements.
Syntax
DATA constant«, constant»...
Remarks
The constant arguments can be any valid numeric or string constant.
Note
You cannot use ASCII 01 and 02 in data strings if you are going to compile
to an executable program. The compiler (BC.EXE) uses ASCII 01 and 02
internally to represent End-of-Statement and End-of-Line respectively. You
can, however, still use 1 and 2 within the QBX environment.
Names of symbolic constants (defined in a CONST statement) that appear in
DATA statements are interpreted as strings, rather than as names of
constants. For example, in the following program fragment, the second data
item is a string, PI, and not the value 3.141593:
CONST PI=3.141593
.
.
.
DATA 2.20, PI,45,7
.
.
.
A DATA statement can contain as many constants as will fit on a line. The
constants are separated by commas. You can use any number of DATA
statements.
Note
If a string constant contains commas, colons, or leading or trailing spaces,
enclose the string in double quotation marks.
Null data items (indicated by a missing value) can appear in a data list as
shown below:
DATA 1,2,,4,5
When a null item is read into a numeric variable, the variable has the value
0. When a null item is read into a string variable, the variable has the
null string value ("").
When working in the QBX environment, DATA statements can be entered only in
the module-level code. BASIC moves all DATA statements not in the
module-level code to the module-level code when it reads a source file.
READ statements can appear anywhere in the program.
DATA statements are used in the order in which they appear in the source
file. You may think of the items in several DATA statements as one
continuous list of items, regardless of how many items are in a statement or
where the statement appears in the program.
You can reread DATA statements by using the RESTORE statement.
REM statements that appear at the end of DATA statements must be preceded
by a colon. Without a colon, BASIC interprets trailing REM statements as
string data.
See Also
READ, RESTORE
Examples
The first example displays the current date by converting the date returned
by the DATE$ function:
' Use VAL to find the month from the string returned by DATE$.
C$ = DATE$
FOR I% = 1 TO VAL(C$)
READ Month$
NEXT
DATA January, February, March, April, May, June, July
DATA August, September, October, November, December
' Get the day.
Day$ = MID$(C$, 4, 2)
IF LEFT$(Day$, 1) = "0" THEN Day$ = RIGHT$(Day$, 1)
' Get the year.
Year$ = RIGHT$(C$, 4)
PRINT "Today is "; Month$; " "; Day$; ", "; Year$
Output
Today is September 21, 1989
The following example shows how null data items are handled:
DATA abc,,def
DATA 1,,2
READ A$, B$, C$ ' B$ = ""
PRINT A$, B$, C$
PRINT
READ A, B, C ' B = 0
PRINT A, B, C
Output
abc def
1 0 2
DATE$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string containing the current date.
Syntax
DATE$
Remarks
The DATE$ function returns a 10-character string in the form mm-dd-yyyy,
where mm is the month (01-12), dd is the day (01-31), and
yyyy is the year (1980-2099).
See Also
DATE$ Statement
Example
Note that the DATE$ function in the following example prints a zero in
front of the month:
PRINT DATE$
Output
04-21-1989
DATE$ Statement
────────────────────────────────────────────────────────────────────────────
Action
Sets the current date in your computer's system.
Syntax
DATE$ = stringexpression$
Remarks
The DATE$ statement is the complement of the DATE$ function.
If you use the DATE$ statement to set the date, the change remains in
effect until you change it again or reboot your computer.
The stringexpression$ must have one of the following forms, where mm
(01-12) and dd (01-31) are the month and day, and yy or yyyy
(1980-2099) is the year:
mm-dd-yy
mm-dd-yyyy
mm/dd/yy
mm/dd/yyyy
See Also
DATE$ Function , TIME$ Statement
Example
The following example prompts you to supply the month, date, and year, then
resets the system date on your computer. Note that if you change the system
date, any files you create or revise will be stamped with the new date.
PRINT "Enter the date below (default year is 1989)."
INPUT " Month: ",Month$
INPUT " Date: ",Day$
INPUT " Year: ",Year$
IF Year$ = "" THEN Year$ = "89"
DATE$ = Month$ + "/" + Day$ + "/" + Year$
DECLARE Statement (BASIC Procedures)
────────────────────────────────────────────────────────────────────────────
Action
Declares references to BASIC procedures and invokes argument type checking.
Syntax
DECLARE { FUNCTION | SUB} name «(« parameterlist»)»
Remarks
The DECLARE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
name The name that will be used to
invoke the procedure. The argument
name is limited to 40 characters.
FUNCTION procedure names can end
in one of the type-declaration
characters ( %, &, !, #, @, %
Argument Description
────────────────────────────────────────────────────────────────────────────
characters ( %, &, !, #, @, %
or $) to indicate the type
of value returned.
parameterlist A list of parameters that
indicates the number and type of
arguments to be used to call the
procedure. Syntax is shown below.
Only the number and type of the
arguments are significant.
For calls within BASIC, the DECLARE statement is required only if you call
SUB procedures without the CALL keyword, or if you invoke a FUNCTION
procedure defined in another module. For more information about invoking
procedures without the CALL keyword, see Chapter 2, "SUB and FUNCTION
Procedures" in the Programmer's Guide.
A DECLARE statement also causes the compiler to check the number and type
of arguments used to invoke the procedure. QBX automatically generates
DECLARE statements when you save your program while working in the
environment. The DECLARE statement can appear only in module-level code
(not in a SUB or FUNCTION procedure) and affects the entire module.
The parameterlist serves as a prototype for checking the number and type of
the arguments in SUB and FUNCTION procedure calls. It has the following
syntax:
variable«AS type»«, variable «AS type»»...
The argument variable is any
valid BASIC variable name. If the variable is an array, it can be followed
by the number of dimensions in parentheses, as in this fragment:
DECLARE SUB DisplayText (A(2) AS STRING)
DIM Text$(100,5)
.
.
.
CALL DisplayText(Text$())
The number of dimensions is optional.
The type is either INTEGER, LONG, SINGLE, DOUBLE, CURRENCY, STRING,
or a user-defined type. Again, only the number and types of arguments are
significant.
Note
You cannot have fixed-length strings in DECLARE statements, because only
variable-length strings can be passed to SUB and FUNCTION procedures.
Fixed-length strings can appear in an argument list but are converted to
variable-length strings before being passed.
A variable's type also can be indicated by including an explicit type
character ( %, &, !, #, @, or $) or by relying on the default type.
The form of the parameter list determines whether or not argument checking
is done, as shown in the following list:
DECLARE SUB First
You can omit the parentheses only if the SUB or FUNCTION procedure is
separately compiled. No argument checking is done.
DECLARE SUB First ()
First has no parameters. If you use arguments in a call to First, BASIC
generates an error. An empty parameter list indicates that the SUB or
FUNCTION procedure has no parameters and that argument checking should be
done.
DECLARE SUB First (X AS LONG)
First has one long-integer parameter. The number and type of the arguments
in each call or invocation are checked when the parameter list appears in
the DECLARE statement.
DECLARE also can be used to declare references to
procedures written in other programming languages, such as C. See the entry
for the DECLARE statement (Non-BASIC).
See Also
CALL (BASIC), DECLARE (Non-BASIC), FUNCTION, SUB
Example
In this program, use of the DECLARE statement allows a SUB procedure to be
invoked without using the CALL keyword:
' Generate 20 random numbers, store them in an array, and sort.
DECLARE SUB Sort (A() AS INTEGER, N AS INTEGER)
DIM Array1(1 TO 20) AS INTEGER
DIM I AS INTEGER
' Generate 20 random numbers.
RANDOMIZE TIMER
CLS
FOR I% = 1 TO 20
Array1(I%) = INT(RND * 100)
NEXT I%
' Sort the array, calling Sort without the CALL keyword.
' Notice the absence of parentheses around the arguments in
' the call to Sort.
Sort Array1(), 20
' Print the sorted array.
FOR I% = 1 TO 20
PRINT Array1(I%)
NEXT I%
END
' Sort subroutine.
SUB Sort (A%(), N%)
FOR I% = 1 TO N% - 1
FOR J% = I% + 1 TO N%
IF A%(I%) > A%(J%) THEN SWAP A%(I%), A%(J%)
NEXT J%
NEXT I%
END SUB
DECLARE Statement (Non-BASIC Procedures)
────────────────────────────────────────────────────────────────────────────
Action
Declares calling sequences for external procedures written in other
languages.
Syntax
DECLARE FUNCTION name «CDECL» «ALIAS "aliasname"» «(«parameterlist»)»
DECLARE SUB name «CDECL» «ALIAS "aliasname"» «(«parameterlist»)»
Remarks
The following list describes the parts of the DECLARE statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
FUNCTION Indicates that the external
procedure returns a value and can
be used in an expression.
SUB Indicates that the external
procedure is invoked in the same
way as a BASIC SUB procedure.
name The name used in the BASIC program
to invoke the procedure. Names can
Part Description
────────────────────────────────────────────────────────────────────────────
to invoke the procedure. Names can
have up to 40 characters.
FUNCTION procedure names can
include an explicit type character
( %, &, !, #, @, or $)
indicating the type of value the
procedure returns.
CDECL Indicates that the procedure uses
the C-language argument order and
naming conventions. CDECL passes
the arguments from right to left,
rather than using the BASIC
convention of left to right.,
CDECL also affects the name used
in searches of object files and
libraries. If there is no ALIAS
clause in the DECLARE statement,
Part Description
────────────────────────────────────────────────────────────────────────────
clause in the DECLARE statement,
the type-declaration character is
removed from the name of the
procedure, and an underscore is
added to the beginning. This
becomes the name used when
searching libraries and external
files. If CDECL is used with
ALIAS, aliasname is used as is.
ALIAS Indicates that the procedure being
called has another name in the
.OBJ or library file..
aliasname The name the procedure has in the
file or library.
parameterlist The parameters to be passed to the
invoked procedure.
Part Description
────────────────────────────────────────────────────────────────────────────
invoked procedure.
The argument parameterlist has the following syntax:
«{BYVAL|SEG}» variable «AS type» «, «{BYVAL|SEG}» variable «AS type»»...
The following list describes the parts of parameterlist:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
BYVAL Indicates the parameter is passed
by value, not reference. Reference
is the default. BYVAL can be used
only with INTEGER, LONG, SINGLE,
DOUBLE, and CURRENCY types.
Part Description
────────────────────────────────────────────────────────────────────────────
DOUBLE, and CURRENCY types.
When BYVAL appears in front of a
parameter, the actual argument is
converted to the type indicated in
the DECLARE statement before
being passed.
SEG Indicates the parameter is passed
as a segmented address (far
address).
variable A valid BASIC variable name. Only
the variable's type is significant.
If the variable is an array, it
can be followed by the number of
dimensions in parentheses (to
maintain compatibility with older
versions of BASIC). For example:
Part Description
────────────────────────────────────────────────────────────────────────────
versions of BASIC). For example:
DECLARE SUB EigenValue (A(2) AS
DOUBLE)
AS type Indicates the variable's type. The
argument type can be INTEGER,
LONG, SINGLE, DOUBLE, STRING,
CURRENCY, ANY, or a user-defined
type. You also can indicate the
variable's type by including an
explicit type character ( %, &,
!, #, @, or $) in the
variable name or by relying on the
default type.
When declaring external procedures
written in other languages, you
can use the ANY keyword in the
Part Description
────────────────────────────────────────────────────────────────────────────
can use the ANY keyword in the
AS clause. ANY overrides type
checking for that argument. You
cannot use ANY with arguments
passed by value.
When neither BYVAL nor SEG is used, arguments are passed as near addresses
(offsets).
This form of the DECLARE statement lets you refer to procedures written in
other languages. The DECLARE statement also causes the compiler to check
the number and type of arguments used to invoke the procedure. A DECLARE
statement can appear only in module-level code and affects the entire source
file.
The form of the parameter list determines whether or not argument type
checking is done, as described in the following declarations:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
Declaration Meaning
────────────────────────────────────────────────────────────────────────────
DECLARE SUB First CDECL No argument checking is done when
there is no parameter list.
DECLARE SUB First CDECL () First has no parameters. If you use
arguments in a call to First, BASIC
generates an error. Empty
parentheses indicate that the SUB
or FUNCTION procedure has no
parameters and that argument
checking should be done.
DECLARE SUB First CDECL (X AS LONG) First takes one long-integer
argument. When a parameter list
appears, the number and type of
arguments are checked each
invocation.
Declaration Meaning
────────────────────────────────────────────────────────────────────────────
invocation.
A procedure in a DECLARE statement can be invoked without the CALL
keyword.
Note
You cannot have fixed-length strings in DECLARE statements because only
variable-length strings can be passed to SUB and FUNCTION procedures.
Fixed-length strings can appear in an argument list but are converted to
variable-length strings before being passed.
Be careful when using the SEG keyword to pass arrays, because BASIC may
move variables in memory before the called routine begins execution.
Anything in a CALL statement's argument list that causes memory movement
may create problems. You can safely pass variables using SEG if the CALL
statement's argument list contains only simple variables, arithmetic
expressions, or arrays indexed without the use of intrinsic or user-defined
functions.
See Also
CALL, CALLS Statements (Non-BASIC); DECLARE (BASIC)
Example
The following example shows a BASIC program that calls a short C function.
The C program is compiled separately and stored in a Quick library or
explicitly linked to form the .EXE file.
DEFINT A-Z
DECLARE FUNCTION addone CDECL (BYVAL n AS INTEGER)
INPUT x
y = addone(x)
PRINT "x and y are "; x; y
END
The following function uses C argument passing and takes a single integer
argument passed by value.
/* C function addone. Returns one more than its integer argument. */
int far addone(int n)
{
return(n+1);
}
DEF FN Statement
────────────────────────────────────────────────────────────────────────────
Action
Defines and names a function.
Syntax 1
DEF FNname«(parameterlist)» = expression
Syntax 2
DEF FNname«(parameterlist)»
« statementblock»
FNname = expression
« statementblock»
« EXIT DEF»
« statementblock»
END DEF
Remarks
The DEF FN statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
name A legal variable name, which is
always prefixed with FN (for
example: FNShort). The name
(including the FN prefix) can be
up to 40 characters long and can
include an explicit
type-declaration character to
indicate the type of value
returned. Names that are the same
except for the type-declaration
character are distinct names. For
example, the following are names
of three different DEF FN
functions:
Argument Description
────────────────────────────────────────────────────────────────────────────
FNString$
FNString%
FNString#
To return a value from a function
defined by DEF FN, assign the
value to the full function name:
FNString$ = "No answer."
parameterlist A list of variable names,
separated by commas. The syntax is
explained below. When the function
is called, BASIC assigns the value
of each argument to its
corresponding parameter. Function
arguments are passed by value.
Functions defined by DEF FN do
Argument Description
────────────────────────────────────────────────────────────────────────────
Functions defined by DEF FN do
not accept arrays, records, or
fixed-length strings as arguments.
expression In both versions of syntax,
expression is evaluated and the
result is the function's value. In
Syntax 1, expression is the
entire body of the function and is
limited to one logical line.
When no expression is assigned to
the name, the default return
values are 0 for a numeric DEF
FN function, and the null string
("") for a string DEF FN function.
The argument parameterlist has the following syntax:
variable « AS type» «, variable « AS type»»...
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
variable Any valid BASIC variable name.
AS type The argument type is INTEGER,
LONG, SINGLE, DOUBLE, CURRENCY,
or STRING. You also can indicate
a variable's type by including a
type-declaration character ( %, &,
!, #, @, or $) in the
name.
Note
The FUNCTION procedure offers greater flexibility and control than the DEF
FN statement. For more information, see the FUNCTION entry in this book and
Chapter 2, "SUB and FUNCTION Procedures" in the Programmer's Guide.
DEF FN must define a function before the function is used. If you call a
DEF FN function before it is defined, BASIC generates the error message
Function not defined. DEF FN function definitions cannot appear inside
other DEF FN definitions. In addition, functions defined by DEF FN cannot
be recursive.
The EXIT DEF statement causes an immediate exit from the executing DEF FN
function. Program execution continues where the DEF FN function was
invoked.
DEF FN functions can be used only in the module in which they are defined.
A function defined by DEF FN can share variables with the module-level
code. Variables not in parameterlist are global--their values are
shared with the module-level code. To keep a variable value local to a
function definition, declare it in a STATIC statement.
DEF FN can return either numeric or string values. DEF FN returns a string
value if name is a string-variable name, and a numeric value if name is a
numeric-variable name. If you assign a numeric value to a string function
name or assign a string value to a numeric function name, BASIC generates
the error message Type mismatch.
If the function is numeric, DEF FN name returns a value with the precision
specified by name. For example, if name specifies a double-precision
variable, then the value returned by DEF FN name is double precision,
regardless of the precision of expression.
Because BASIC may
rearrange arithmetic expressions for greater efficiency, avoid using
functions defined by DEF FN that change program variables in expressions
that may be reordered. The following example may give unpredictable results:
DEF FNShort
I=10
FNShort=1
END DEF
I=1 : PRINT FNShort + I + I
If BASIC reorders the expression so FNShort is called after calculating
(I+I) , the result is 3 rather than 21. You usually can avoid this problem
by isolating the DEF FN function call:
I = 1 : X = FNShort : PRINT X + I + I
Embedding I/O operations in DEF FN-defined functions used in I/O
statements, or embedding graphics operations in DEF FN-defined functions in
graphics statements, may cause similar problems.
See Also
FUNCTION, STATIC
Example
The following program uses a function defined by DEF FN to calculate the
factorial of a number (for example, the factorial of 3 is 3 times 2 times
1):
DEF FNFactorial# (X%)
STATIC Tmp#, I%
Tmp# = 1
FOR I% = 2 TO X%
Tmp# = Tmp# * I%
NEXT I%
FNFactorial# = Tmp#
END DEF
INPUT "Enter an integer: ", Num%
PRINT : PRINT Num%; "factorial is"; FNFactorial#(Num%)
DEFtype Statements
────────────────────────────────────────────────────────────────────────────
Action
Set the default data type for variables, DEF FN functions, and FUNCTION
procedures.
Syntax
DEFINT letterrange «, letterrange»...
DEFLNG letterrange«, letterrange»...
DEFSNG letterrange«, letterrange»...
DEFDBL letterrange«, letterrange»...
DEFCUR letterrange«, letterrange»...
DEFSTR letterrange «, letterrange»...
Remarks
The letterrange argument has the form:
letter1 «- letter2»
The arguments letter1 and letter2 are any of the uppercase or lowercase
letters of the alphabet. Names beginning with the letters in letterrange
have the type specified by the last three letters of the statement: integer
( INT), long integer ( LNG), single precision ( SNG), double precision (
DBL), currency ( CUR), or string ( STR). For example, in the following
program fragment, Message is a string variable:
DEFSTR A-Q
.
.
.
Message="Out of stack space."
The case of the letters in letterrange is not significant. These three
statements are equivalent:
DEFINT I-N
DEFINT i-n
DEFINT i-N
A type-declaration character ( %, &, !, #, @, or $) always takes
precedence over a DEF type statement. DEF type statements do not affect
record elements.
Note
I%, I&, I!, I#, I@, and I$ all are distinct variables, and each may hold a
different value.
BASICA
BASICA handles default data types differently. BASICA scans each statement
before executing it. If the statement contains a variable without an
explicit type (indicated by %, &, !, #, @, or $), the interpreter uses
the current default type.
In contrast, BASIC scans the text once only and after a variable appears in
a program line, its type cannot be changed.
Example
See the ABS function programming example, which uses the DEFDBL statement.
DEF SEG Statement
────────────────────────────────────────────────────────────────────────────
Action
Sets the current segment address for a subsequent PEEK function, BLOAD,
BSAVE, Absolute routine, or POKE statement.
Syntax
DEF SEG «= address»
Remarks
For Absolute, BLOAD, BSAVE, PEEK, and POKE, address is used as the
segment. The argument address is a numeric expression with an unsigned
integer value between 0 and 65,535, inclusive. If you use a value outside
this range, BASIC generates the error message Illegal function call. The
previous segment is retained if an error occurs. If address is omitted,
DGROUP is used.
DEF SEG remains in effect until changed. To reset the current segment to
the default data segment (DGROUP), use DEF SEG without any argument.
Be sure to separate DEF and SEG with a space. Otherwise, BASIC interprets
the statement to mean "assign a value to the variable DEFSEG."
To set the current segment address to the address of data stored in far
memory, you can use DEF SEG with the SSEG or VARSEG functions ( SSEG
returns the current segment address of a string; VARSEG returns the current
segment address of numeric data). For example, this statement sets the
current address for a far string named a$ :
DEF SEG = SSEG(a$)
When using DEF SEG in OS/2 protected mode, any DEF SEG statement must
refer only to a valid selector. The DEF SEG statement itself does not
generate any memory references using the selector, nor does it attempt to
validate the selector. If a misdirected DEF SEG statement causes your
program to refer to an illegal memory address, the operating system may
generate a protection exception, or BASIC may generate the error message
Permission denied. The default DEF SEG segment always constitutes a valid
memory reference. Use caution when altering this reference in protected
mode.
DEF SEG and Expanded Memory Arrays
Do not use DEF SEG to set the segment of
an expanded memory array. If you start QBX with the /Ea switch, any of these
arrays may be stored in expanded memory:
■ Numeric arrays less than 16K in size.
■ Fixed-length string arrays less than 16K in size.
■ User-defined-type arrays less than 16K in size.
If you want to use DEF SEG to set the segment of an array, first start QBX
without the /Ea switch. (Without the /Ea switch, no arrays are stored in
expanded memory.)
For more information on using expanded memory, see "Memory Management for
QBX" in Getting Started.
BASICA
In this version of BASIC, the CALL and CALLS statements do not use the
segment address set by DEF SEG.
See Also
SADD; SSEG; VARPTR, VARSEG
Example
The following example uses DEF SEG, PEEK, and POKE to turn the Caps Lock
key on and off.
This program contains hardware-specific instructions. It works correctly on
IBM PC, XT, and AT computers.
DECLARE SUB CapsOn ()
DECLARE SUB CapsOff ()
DECLARE SUB PrntMsg (R%, C%, M$)
CLS
CapsOn
PrntMsg 24, 1, "<Caps Lock On>"
LOCATE 12, 10
LINE INPUT "Enter a string (all characters are caps): ", S$
CapsOff
PrntMsg 24, 1, " "
PrntMsg 25, 1, "Press any key to continue..."
DO WHILE INKEY$ = "": LOOP
CLS
END
SUB CapsOff STATIC' Turn the Caps Lock key off.
DEF SEG = 0' Set segment to low memory.
POKE &H417, PEEK(&H417) AND &HBF' Turn off bit 6 of &H0417.
DEF SEG ' Restore segment.
END SUB
SUB CapsOn STATIC' Turn Caps Lock on.
DEF SEG = 0' Set segment to low memory.
POKE &H417, PEEK(&H417) OR &H40' Turn on bit 6 of &H0417.
DEF SEG ' Restore segment.
END SUB
SUB PrntMsg (Row%, Col%, Message$) STATIC
' Print message at Row%, Col% without changing cursor.
CurRow% = CSRLIN: CurCol% = POS(0)' Save cursor position.
LOCATE Row%, Col%: PRINT Message$;
' Restore cursor.
LOCATE CurRow%, CurCol%
END SUB
DELETE Statement
────────────────────────────────────────────────────────────────────────────
Action
Removes the current record from an ISAM table.
Syntax
DELETE «#» filenumber%
Remarks
The argument filenumber% is the number used in the OPEN statement to open
the table.
If the record you delete is the last record according to the table's current
index, the current position is at the end of the table and there is no
current record. When you delete any other record in the table, the record
following the deleted record becomes current. The record preceding the
deleted record remains the previous record.
See Also
DELETEINDEX, DELETETABLE, INSERT
Example
See the BEGINTRANS statement programming example, which uses the DELETE
statement.
DELETEINDEX Statement
────────────────────────────────────────────────────────────────────────────
Action
Permanently removes an index from an ISAM database.
Syntax
DELETEINDEX «#» filenumber%, indexname$
Remarks
The DELETEINDEX statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number of the open ISAM table
that was used in the OPEN
statement.
indexname$ The name used in the CREATEINDEX
statement to create the index.
See Also
CREATEINDEX, GETINDEX$, SETINDEX
Example
See the CREATEINDEX statement programming example, which uses the
DELETEINDEX statement.
DELETETABLE Statement
────────────────────────────────────────────────────────────────────────────
Action
Removes a table and deletes any indexes based on the table from an ISAM
database.
Syntax
DELETETABLE database$, tablename$
Remarks
The DELETETABLE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
database$ A database filename or path. The
argument database$ specifies an
optional device, followed by a
filename or path conforming to the
DOS naming conventions. The
database$ specification must be
the name of an ISAM file.
tablename$ The name used in the OPEN
statement to open the table.
Argument Description
────────────────────────────────────────────────────────────────────────────
statement to open the table.
If the specified file is not an ISAM database file, BASIC generates the
error message Bad file mode.
Warning
Use DELETETABLE with caution. DELETETABLE permanently removes the
specified table from the database.
See Also
CLOSE, DELETE, DELETEINDEX, OPEN
Example
See the programming example for the SEEKGT, SEEKGE, and SEEKEQ
statements, which uses the DELETETABLE statement.
DIM Statement
────────────────────────────────────────────────────────────────────────────
Action
Declares a variable and allocates storage space.
Syntax
DIM «SHARED» variable«(subscripts)» «AS type» «, variable«(subscripts)» «AS
type»»...
Remarks
The following list describes the parts of the DIM statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
SHARED The optional SHARED attribute
allows all procedures in a module
to share arrays and simple
variables. This differs from the
SHARED statement, which affects
only variables within a single
SUB or FUNCTION procedure.
variable A BASIC variable name.
subscripts The dimensions of the array.
Multiple dimensions can be
declared. The subscript syntax is
Part Description
────────────────────────────────────────────────────────────────────────────
declared. The subscript syntax is
described below.
AS type Declares the type of the variable.
The type may be INTEGER, LONG,
SINGLE, DOUBLE, STRING (for
variable-length strings), STRING
* length (for fixed-length
strings), CURRENCY, or a
user-defined type.
The argument subscript in the DIM statement has the following form:
« lower% TO» upper% «,« lower% TO» upper%»...
The TO keyword provides a way to indicate both the lower and the upper
bounds of an array's subscripts. The following statements are equivalent (if
there is no OPTION BASE statement):
DIM A(8,3)
DIM A(0 TO 8, 0 TO 3)
DIM A(8,0 TO 3)
Subscripts can be negative. TO can be used to specify any range of
subscripts between -32,768 and 32,767, inclusive:
DIM A(-4 TO 10)
DIM B(-99 TO -5,-3 TO 0)
If you use an implicitly dimensioned array (that is, any array that has not
been declared with the DIM statement), the maximum value of each subscript
in the array is 10. If you use a subscript that is greater than the
specified maximum and if run-time error checking is in effect, BASIC
generates the error message Subscript out of range.
Note
Run-time error checking is in effect when:
■ You run a program from the QBX environment.
■ You have created an .EXE file in the QBX environment and you have
selected the Run-Time Error Checking option in the Make EXE File
dialog box.
■ You have compiled your program with BC using the /D option to select
run-time error checking.
The DIM statement initializes all elements of numeric arrays to zero and
all the elements of string arrays to null strings. The fields of record
variables are initialized to zero, including fixed-string fields. The
maximum number of dimensions allowed in a DIM statement is 60.
If you try to declare a dimension for an array variable with a DIM
statement after you have referred to the array, BASIC generates the error
message Array already dimensioned. It is good programming practice to put
the required DIM statements at the beginning of a program, outside of any
loops.
Static and Dynamic Arrays
How you declare an array also determines whether it
is static (allocated when the program is translated) or dynamic (allocated
when the program is run):
╓┌───────────────────────────────────────────────────────────────┌───────────╖
How array is declared Allocation
────────────────────────────────────────────────────────────────────────────
Declared first in a COMMON statement Dynamic
Implicitly dimensioned arrays Static
Dimensioned with numeric constants or CONST statement Static
constants
Dimensioned with variables as subscripts Dynamic
The following list shows examples of different DIM statements and results:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Statement Result
Statement Result
────────────────────────────────────────────────────────────────────────────
DIM A(0 TO 9) The array A is allocated as a
static array if $DYNAMIC is not
in effect.
DIM A(MAXDIM) If MAXDIM is defined in a CONST
statement, A is a static array. If
MAXDIM is a variable, the array is
a dynamic array and is allocated
only when the program reaches the
DIM statement.
For more information about static and dynamic arrays, see Appendix B, "Data
Types, Constants, Variables, and Arrays" in the Programmer's Guide.
Note
If the array size exceeds 64K, if the array is not dynamic, and if the /AH
option was not used, BASIC may generate the error message Subscript out of
range or Array too big. Reduce the size of the array or make the array
dynamic and use the /AH command-line option.
Type Declarations
In addition to declaring the dimensions of an array, the
DIM statement also can be used to declare the type of a variable. For
example, the following statement declares the variable to be an integer,
even though there is no type-declaration character or DEFINT statement:
DIM NumberOfBytes AS INTEGER
The DIM statement provides a way to declare specific variables to be
records. In the following example, the variable TopCard is declared as a
record variable:
TYPE Card
Suit AS STRING * 9
Value AS INTEGER
END TYPE
DIM TopCard AS Card
You also can declare arrays of records:
TYPE Card
Suit AS STRING * 9
Value AS INTEGER
END TYPE
DIM Deck(1 TO 52) AS Card
Note
BASIC now supports the CURRENCY data type (type suffix @). This can be
used in the AS type clause of the DIM statement. Also, BASIC now supports
static arrays in user-defined types.
BASICA
BASICA executes a DIM statement when it encounters the statement in the
program. The array is allocated only when the statement is executed, so all
arrays in BASICA are dynamic.
See Also
ERASE, OPTION BASE, REDIM
Example
The following example finds and prints the maximum and minimum of a set of
values:
' Declare the dimensions for an array to hold the values.
CONST MAXDIM=20
DIM A(1 TO MAXDIM)
' Use DIM to set up two integer variables. Other variables are SINGLE.
DIM NumValues AS INTEGER, I AS INTEGER
' Get the values.
NumValues=0
PRINT "Enter values one per line. Type END to end."
DO
INPUT A$
IF UCASE$(A$)="END" OR NumValues>=MAXDIM THEN EXIT DO
NumValues=NumValues+1
A(NumValues)=VAL(A$)
LOOP
' Find the maximum and minimum values.
IF NumValues>0 THEN
Max=A(1)
Min=A(1)
FOR I=1 TO NumValues
IF A(I)>Max THEN Max=A(I)
IF A(I)<Min THEN Min=A(I)
NEXT I
PRINT "The maximum is ";Max;" The minimum is ";Min
ELSE
PRINT "Too few values."
END IF
Output
Enter values one per line. Type END to end.
? 23.2
? 11.3
? 1.6
? end
The maximum is 23.2 The minimum is 1.6
DIR$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a filename that matches the specified pattern.
Syntax
DIR$«( filespec$)»
Remarks
The argument filespec$ is a string expression that specifies a filename or
path.
The path and filename can include a drive and DOS wildcard characters.
BASIC generates the error message Illegal function call if you don't specify
filespec$ when you first call DIR$.
DIR$ returns the first filename that matches filespec$. To retrieve
additional filenames that match the filespec$ pattern, call DIR$ again
with no argument. When no filenames match, DIR$ returns a null string.
You do not have to retrieve all of the filenames that match a given
filespec$ before calling DIR$ again with a new filespec$.
Because filenames are retrieved in no particular order, you may want to
store filenames in a dynamic array and sort the array.
DIR$ is not case sensitive. "C" is the same as "c."
See Also
CURDIR$
Example
The following example demonstrates use of the DIR$ function:
DECLARE FUNCTION GetFileCount& (filespec$)
filespec$ = "*.*"
count = GetFileCount(filespec$)
PRINT count; "files match the file specification."
' Function that returns number of files that match file specification.
FUNCTION GetFileCount& (filespec$)
DIM FileCount AS LONG
IF LEN(DIR$(filespec$)) = 0 THEN ' Ensure filespec$ is valid.
FileCount& = 0
ELSE
FileCount = 1
DO WHILE LEN(DIR$) > 0
FileCount& = FileCount& + 1
LOOP
END IF
GetFileCount = FileCount&
END FUNCTION
DO...LOOP Statement
────────────────────────────────────────────────────────────────────────────
Action
Repeats a block of statements while a condition is true or until a condition
becomes true.
Syntax 1
DO «{ WHILE | UNTIL} condition»
« statementblock»
« EXIT DO»
« statementblock»
LOOP
Syntax 2
DO
« statementblock»
« EXIT DO»
« statementblock»
LOOP «{ WHILE | UNTIL} condition»
Remarks
The argument condition is a numeric expression that BASIC evaluates as true
(nonzero) or false (zero).
The program lines between the DO and LOOP statements will be repeated as
long as condition is true.
You can use a DO... LOOP statement instead of a WHILE... WEND statement.
The DO... LOOP is more versatile because it can test for a condition at the
beginning or at the end of a loop.
Examples
The following examples show how placement of the condition affects the
number of times the block of statements is executed:
' Test at the beginning of the loop. Because I is not less than 10,
' the body of the loop (the statement block) is never executed.
I = 10
PRINT "Example 1:": PRINT
PRINT "Value of I at beginning of loop is "; I
DO WHILE I < 10
I = I + 1
LOOP
PRINT "Value of I at end of loop is "; I
' Test at the end of the loop, so the statement block executes
' at least once.
I = 10
PRINT : PRINT : PRINT "Example 2:": PRINT
DO
PRINT "Value of I at beginning of loop is "; I
I = I + 1
LOOP WHILE I < 10
PRINT "Value of I at end of loop is "; I
The following sort program tests at the end of the loop because the entire
array must be examined at least once to see if it is in order. The program
illustrates testing at the end of a loop:
CONST NOEXCH = -1' Set up a value to indicate no exchanges.
DIM Exes(12)
DIM I AS INTEGER
' Load the array and mix it up.
FOR I = 1 TO 12 STEP 2
Exes(I) = 13 - I
Exes(I + 1) = 0 + I
NEXT I
Limit = 12
PRINT
PRINT "This is the list of numbers to sort in ascending order:"
PRINT
FOR I = 1 TO 12
PRINT USING " ### "; Exes(I);
NEXT I
PRINT
' In the following DO...LOOP, INKEY$ is tested at the bottom of
' the loop. When the user presses a key, INKEY$ is no longer a
' null string and the loop terminates, continuing program execution.
PRINT : PRINT "Press any key to continue."
DO
LOOP WHILE INKEY$ = ""
DO
Exchange = NOEXCH
FOR I = 1 TO Limit - 1 ' Make one pass over the array.
IF Exes(I) > Exes(I + 1) THEN
SWAP Exes(I), Exes(I + 1) ' Exchange array elements.
Exchange = I ' Record location of most
END IF ' recent exchange.
NEXT I
Limit = Exchange ' Sort on next pass only to where
' last exchange was done.
LOOP UNTIL Exchange = NOEXCH ' Sort until no elements are
' exchanged.
PRINT : PRINT "Sorting is completed. This is the sorted list:": PRINT
FOR I = 1 TO 12
PRINT USING " ### "; Exes(I);
NEXT I
END
DRAW Statement
────────────────────────────────────────────────────────────────────────────
Action
Draws an object described by a string of drawing commands.
Syntax
DRAW stringexpression$
Remarks
The argument stringexpression$ contains one or more drawing commands. The
drawing commands combine many of the capabilities of the other graphics
statements (such as LINE and COLOR) into a graphics macro language, as
described below.
There are three types of drawing commands:
■ Line-drawing and cursor-movement commands.
■ Rotation, color, and scale-factor commands.
■ The substring command.
Cursor-Movement Commands
The following prefix commands can precede any of the movement commands:
╓┌────────────┌──────────────────────────────────────────────────────────────╖
Prefix Description
────────────────────────────────────────────────────────────────────────────
B Move, but do not plot any points.
N Plot, but return to original position when done.
The following commands specify movement in terms of units. The default unit
size is one pixel. Unit size can be modified by the S command, which sets
the scale factor (see "Rotation, Color, and Scale-Factor Commands" later in
this entry). If no unit argument is supplied, the graphics cursor is moved
one unit.
Each of the cursor-movement commands initiate movement from the current
graphics position, which is usually the coordinate of the last graphics
point plotted with a DRAW macro-language command or another graphics
command (such as LINE or PSET). The current position defaults to the
center of the screen when a program begins execution. The cursor-movement
commands have the following effects:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Command Effects
────────────────────────────────────────────────────────────────────────────
U « n» Move up n units.
D « n» Move down n units.
L « n» Move left n units.
R « n» Move right n units.
E « n» Move diagonally up and right n
units.
F « n» Move diagonally down and right n
units.
G « n» Move diagonally down and left n
units.
H « n» Move diagonally up and left n
Command Effects
────────────────────────────────────────────────────────────────────────────
H « n» Move diagonally up and left n
units. .
M «{ +| -}» x, y Move absolute or relative:
If x is preceded by a plus ( +)
or minus ( -), the movement is
relative to the current point;
that is, x and y are added to
(or subtracted from) the
coordinates of the current
graphics position and movement is
to that point.
If no sign precedes x, the
movement is absolute. Movement is
from the current cursor position
to the point with coordinates x,
y.
Command Effects
────────────────────────────────────────────────────────────────────────────
y.
Rotation, Color, and Scale-Factor Commands
The following commands let you change the appearance of a drawing by
rotating it, changing colors, or scaling it:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Command Description
────────────────────────────────────────────────────────────────────────────
A n Set angle rotation. The value of
n may range from 0 to 3, where 0
is 0, 1 is 90, 2 is 180, and 3 is
270. Figures rotated 90 or 270
are scaled so they appear the same
size on a monitor screen with a
4:3 aspect ratio.
TA n Turn an angle of n degrees. The
Command Description
────────────────────────────────────────────────────────────────────────────
TA n Turn an angle of n degrees. The
value of n must be between -360
and 360. If n is positive,
rotation is counterclockwise; if
n is negative, rotation is
clockwise. The following example
uses TA to draw spokes:
SCREEN 1
FOR D = 0 TO 360 STEP 10
DRAW "TA=" + VARPTR$(D) + "NU50"
NEXT D
C n Set the drawing (foreground) color
to n. See the COLOR, PALETTE,
and SCREEN statements for
discussion of valid colors,
numbers, and attributes.
Command Description
────────────────────────────────────────────────────────────────────────────
P p, b The value p is the paint color
for the figure's interior, while
b is the paint color for the
figure's border. See the PAINT
statement for more information
about painting an area with a
graphic pattern.
S n Set scale factor n, which can
range from 0 to 255, inclusive.
Increase or decrease length of
moves. The default for n is 4,
which causes no scaling. The scale
factor multiplied by
movement-command arguments
(divided by 4) gives the actual
distance moved.
Command Description
────────────────────────────────────────────────────────────────────────────
X stringexpression$ Execute substring. This command
allows you to execute a second
substring from a DRAW command
string. You can have one string
expression execute another, which
executes a third, and so on.
Numeric arguments to macro
commands within stringexpression$
can be constants or variable names.
BASIC requires the following
syntax:
"X" + VARPTR$(stringexpression)
BASICA
Some DRAW statements that are allowable in BASICA programs require
modification when used with the BASIC compiler. Specifically, the compiler
requires the VARPTR$ form for variables. One example is this
BASICA statement (in which ANGLE is a variable):
DRAW "TA = Angle"
For the BASIC compiler, you would change that to:
DRAW "TA =" + VARPTR$(Angle)
The compiler does not support the BASICA X stringexpression$ command.
However, you can execute a substring by appending the character form of the
address to X. For example, the following two statements are equivalent. The
first statement works when within the environment and when using the
compiler, while the second works only within the QBX environment.
DRAW "X" + VARPTR$(A$)
DRAW "XA$"
See Also
PALETTE, SCREEN Statement, VARPTR$
Examples
The first example draws the outline of a triangle in magenta and paints the
interior cyan:
SCREEN 1
DRAW "C2" ' Set color to magenta.
DRAW "F60 L120 E60" ' Draw a triangle.
DRAW "BD30" ' Move down into the triangle.
DRAW "P1,2" ' Paint interior.
The next example shows how to use the M macro command with absolute and
relative movement, and with string- and numeric-variable arguments:
SCREEN 2
PRINT "Press any key to continue..."
' Absolute movement.
DRAW "M 50,80"
DRAW "M 80,50"
LOCATE 2, 30: PRINT "Absolute movement"
DO : LOOP WHILE INKEY$ = ""
' Relative movement.
DRAW "M+40,-20"
DRAW "M-40,-20"
DRAW "M-40,+20"
DRAW "M+40,+20"
LOCATE 3, 30: PRINT "Relative movement"
DO : LOOP WHILE INKEY$ = ""
' Using a string variable.
X$ = "400": Y$ = "190"
DRAW "M" + X$ + "," + Y$
LOCATE 4, 30: PRINT "String variable"
DO : LOOP WHILE INKEY$ = ""
' Using numeric variables (note the two "=" signs).
A = 300: B = 120
DRAW "M=" + VARPTR$(A) + ",=" + VARPTR$(B)
LOCATE 5, 30: PRINT "Numeric variables"
This program draws a clock on the screen using the TIME$ unction:
@AS@%' Declare procedure.
DECLARE SUB Face (Min$)
' Select 640 x 200 pixel high-resolution graphics screen.
SCREEN 2
DO
CLS
Min$ = MID$(TIME$, 4, 2)' Get string containing minutes value.
Face Min$' Draw clock face.
' Wait until minute changes or a key is pressed.
DO
' Print time at top of screen.
LOCATE 2, 37
PRINT TIME$
Test$ = INKEY$' Test for a key press.
LOOP WHILE Min$ = MID$(TIME$, 4, 2) AND Test$ = ""
LOOP WHILE Test$ = ""' End program when a key is pressed.
END
SUB Face (Min$) STATIC' Draw the clock face.
LOCATE 23, 30
PRINT "Press any key to end"
CIRCLE (320, 100), 175
' Convert strings to numbers.
Hr = VAL(TIME$)
Min = VAL(Min$)
' Convert numbers to angles.
Little = 360 - (30 * Hr + Min / 2)
Big = 360 - (6 * Min)
' Draw the hands.
DRAW "TA=" + VARPTR$(Little) + "NU40"
DRAW "TA=" + VARPTR$(Big) + "NU70"
END SUB
END Statement
────────────────────────────────────────────────────────────────────────────
Action
Stops a BASIC program, procedure, or block.
Syntax 1
END «{ DEF | FUNCTION | IF | SELECT | SUB | TYPE}»
Syntax 2
END « n%»
Remarks
There are a number of ways to use the END statement, as described in the
following list:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Statement Description
────────────────────────────────────────────────────────────────────────────
END DEF Ends a multiline DEF FN function
definition. You must use END DEF
with a multiline DEF FN.
END FUNCTION Ends a FUNCTION procedure
definition. You must use END
FUNCTION with FUNCTION.
END IF Ends a block IF... THEN... ELSE
statement. You must use END IF
with block IF... THEN... ELSE.
END SELECT Ends a SELECT CASE block. You
Statement Description
────────────────────────────────────────────────────────────────────────────
END SELECT Ends a SELECT CASE block. You
must use END SELECT with a
SELECT CASE statement.
END SUB Ends a BASIC SUB procedure. You
must use END SUB with SUB.
END TYPE Ends a user-defined type
definition ( TYPE statement). You
must use END TYPE with TYPE.
n% Ends a program and returns the
value n% to the operating system
(if n% is omitted, the value of
n% is set to 0). END is not
required at the end of a program.
In Syntax 2, n% accepts a range
of integers from -32768 through
32767, inclusive.
Statement Description
────────────────────────────────────────────────────────────────────────────
32767, inclusive.
The value n% can be used by DOS
or OS/2 batch files or by
non-BASIC programs. Untrapped
errors and fatal errors set the
value of n% to -1.
By itself, the END statement stops program execution and closes all files.
In a stand-alone program, END returns control to the operating system. In
the QBX environment, END returns to that environment. You can place an END
statement anywhere in the program to terminate execution.
See Also
DEF FN, FUNCTION, IF... THEN... ELSE, SELECT CASE, STOP, SUB,
SYSTEM, TYPE
Example
See the on error statement programming example, which uses the END
statement.
ENVIRON$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns an environment string from the DOS or OS/2 environment-string table.
Syntax 1
ENVIRON$ ( environmentstring$)
Syntax 2
ENVIRON$ ( n%)
Remarks
The ENVIRON$ function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
environmentstring$ A string constant or variable that
contains the name of an
environment variable. The name of
the environment variable must be
uppercase. For example, ENVIRON$
("PATH") returns the path
Argument Description
────────────────────────────────────────────────────────────────────────────
("PATH") returns the path
environment variable; ENVIRON$
("path") returns a null string.
n% a numeric expression that
indicates that the nth string
from the environment string table
should be returned.
If you specify an environment-string name, but it cannot be found in the envi
Otherwise, ENVIRON$ returns the text following the equal sign in the environ
If you specify a numeric argument ( n%), the nth string in the environment-s
In this case, the string includes all of the text, including environmentstri
If the nth string does not exist, ENVIRON$ returns a null string. The argum
See Also
ENVIRON Statement
Example
See the ENVIRON statement programming example, which uses the
ENVIRON$ function.
ENVIRON Statement
────────────────────────────────────────────────────────────────────────────
Action
Modifies or adds a parameter in the DOS or OS/2 environment-string table.
Syntax
ENVIRON stringexpression$
Remarks
The argument stringexpression$ is a string constant or variable that
contains the name of the environment variable, such as PATH or PROMPT. It
can have the form parameterID= text, or parameterID text. Everything to
the left of the equal sign or space is assumed to be a parameter, and
everything to the right, text.
The argument parameterID must contain all uppercase letters. For example:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
This statement: Has this effect:
────────────────────────────────────────────────────────────────────────────
This statement: Has this effect:
────────────────────────────────────────────────────────────────────────────
ENVIRON "PATH=C:\SALES" Changes the path.
ENVIRON "path=C:\SALES" Does not change the path. (It
creates a new environment
parameter not usable by the
operating system.)
If parameterID did not previously exist in the environment-string table, it
is appended to the end of the table. If parameterID exists in the table
when the ENVIRON statement is executed, it is deleted and the new
parameterID value is appended to the end of the table.
The text string is the new parameter text. If the text is a null string ("")
or a semicolon (";"), the existing parameter is removed from the
environment-string table and the remaining body of the table is compressed.
DOS or OS/2 discards the environment-string table modified by this function
when your program ends. The environment-string table is then the same as it
was before your program ran.
Note
You cannot increase the size of the environment-string table when using the
ENVIRON statement. This means that before you can add a new environment
variable or increase the size of an existing environment variable you must
first delete or decrease the size of existing environment variable(s).
You can use this statement to change the PATH parameter for a "child"
process (a program or command started by a SHELL statement) or to pass
parameters to a child process by creating a new environment variable.
BASIC generates the error message Out of memory when no more space can be
allocated to the environment-string table. The amount of free space in the
table usually is quite small.
See Also
ENVIRON$, SHELL Function
Example
The following example uses the ENVIRON$ function to get a copy of the
current DOS path variable. The path variable is then changed using the
ENVIRON statement. The contents of the environment-string table are then
displayed using the ENVIRON$ function.
DEFINT A-Z
' Initialize variables.
Path$ = "PATH="
I% = 1
' Store the old PATH.
OldPath$ = ENVIRON$("PATH")
ENVIRON "PATH=C:\BIN;C:\DOS;C:\BUSINESS\ACCOUNTING\RECEIVABLES\MAY"
' Display the entire environment-string table.
PRINT "Your current environment settings are:"
PRINT
DO WHILE ENVIRON$(I%) <> ""
PRINT ENVIRON$(I%)
I% = I% + 1
LOOP
' Change the PATH back to original.
ENVIRON Path$ + OldPath$
' Verify the change.
PRINT
PRINT "Your PATH has been restored to:"
PRINT
PRINT ENVIRON$("PATH")
EOF Function
────────────────────────────────────────────────────────────────────────────
Action
For an ISAM table, tests whether the current position is at the end of a
table. For a non-ISAM file, tests for the end-of-file condition.
Syntax
EOF( filenumber%)
Remarks
The argument filenumber% is the number used in the OPEN statement to open
the file or ISAM table.
The EOF function returns true (nonzero) if the end of a non-ISAM file has
been reached or if the current position in an ISAM table is at the end of
the table. The end of an ISAM table is the position immediately following
the last record according to the current index. Use the EOF function with
sequential files to test for the end of a file. This helps you avoid the
Input past end of file error message.
When used with random-access or binary files, EOF returns true if the last
executed GET statement was unable to read an entire record.
When you use EOF with a communications device, the definition of the
end-of-file condition depends on the mode (ASCII or binary) in which you
opened the device. In ASCII mode, EOF is false until you receive Ctrl+Z,
after which it remains true until you close the device. In binary mode, EOF
is true when the input queue is empty ( LOC( filenumber%)=0), where
filenumber% is the number of the device. It becomes false when the input
queue is not empty.
Note
EOF cannot be used with the BASIC devices SCRN, KYBD, CONS, LPT n, or PIPE.
See Also
BOF, LOC, LOF, OPEN
Example
See the INPUT# statement programming example, which uses the EOF function.
ERASE Statement
────────────────────────────────────────────────────────────────────────────
Action
Reinitializes the elements of static arrays; deallocates dynamic arrays.
Syntax
ERASE arrayname «, arrayname»...
Remarks
The arrayname arguments are the names of arrays to erase. It is important
to know if this array is static or dynamic. ERASE sets the elements of an
array as follows:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
If type of array is: ERASE sets array elements to:
────────────────────────────────────────────────────────────────────────────
Numeric static array Zeros.
String static array Null strings ("").
Array of records Zeros [mdash] all elements of each
record, including fixed-string
elements.
Using ERASE on a dynamic array frees the memory used by the array. Before
your program can refer to the dynamic array again, it must redeclare the
array's dimensions with a DIM or REDIM statement. If you redeclare the
array's dimensions with a DIM statement without first erasing it, BASIC
generates the run-time error message Array already dimensioned. The ERASE
statement is not required when dimensions are redeclared with REDIM.
See Also
CLEAR, DIM, REDIM
Example
The following example shows the use of ERASE with the $DYNAMIC and
$STATIC metacommands:
REM $DYNAMIC
DIM A(100, 100)
' Deallocate array A.
ERASE A
' Redeclare dimensions for array A.
REDIM A(5, 5)
REM $STATIC
DIM B(50, 50)
' Set all elements of B equal to zero. (B still has the dimensions
' assigned by DIM.)
ERASE B
ERDEV, ERDEV$ Functions
────────────────────────────────────────────────────────────────────────────
Action
Provide device-specific status information after an error.
Syntax
ERDEV
ERDEV$
Remarks
ERDEV is an integer function that returns an error code from the last
device that generated a critical error. ERDEV$ is a string function that
returns the name of the device that generated the error. Because ERDEV and
ERDEV$ return meaningful information only after an error, they usually are
used in error-handling routines specified by an ON ERROR statement.
ERDEV$ contains the 8-byte character device name if the error is on a
character device, such as a printer, or the 2-byte block name (A:, B:, etc.)
if the device is not a character device. It contains the 3-byte block name
(COM) if the communications port experiences a timeout.
ERDEV is set by the critical error handler (interrupt 24H) when DOS detects
a critical DOS call error. It also is set by a timeout error on the
communications port and indicates which option in the OPEN COM statement
(CD, CS, or DS) is experiencing the timeout.
ERDEV returns an integer value that contains information about the error.
For block and character device errors, the low byte of ERDEV contains the
DOS error code. For block devices only, the high byte contains
device-attribute information.
For COM timeout errors, ERDEV returns a value corresponding to the source
of the timeout. For more information, see the entry for the OPEN COM
statement.
Assuming an ERDEV return value of x, the following program lines generate
the DOS error code (low byte) and device attribute information (high byte).
DosErrCode = x AND &HFF' Low byte of ERDEV.
DevAttr = (x AND &HFF00) \ 256 ' High byte of ERDEV.
For more information about device-attribute words, see the Microsoft MS-DOS
Programmer's Reference, or books such as The Peter Norton Guide to the
IBM PC or Advanced MS-DOS.
Use ERDEV only in DOS.
Example
The following example prints the values of ERDEV and ERDEV$ after the
program generates an error attempting to open a file:
DEFINT A-Z
ON ERROR GOTO ErrorHandler' Indicate first line of error handler.
OPEN "A:JUNK.DAT" FOR INPUT AS #1' Attempt to open the file.
END
ErrorHandler:
PRINT "ERDEV value is "; ERDEV
PRINT "Device name is "; ERDEV$
ON ERROR GOTO 0
Output
Running the program with drive A unlatched produces the following output (2 i
ERDEV value is 2
Device name is A:
ERR, ERL Functions
────────────────────────────────────────────────────────────────────────────
Action
Return error status.
Syntax
ERR
ERL
Remarks
After an error, the ERR function returns an integer that is the run-time
code for the error. The ERL function returns an integer that is the line
number where the error occurred, or the closest line number before the line
where the error occurred. Because ERR and ERL return mean-ingful values
only after an error, they usually are used in error-handling routines to
determine the error and the corrective action.
The value returned by the ERR function can be directly set by using the
ERR statement. Both the values returned by ERR and ERL can be set
indirectly with the ERROR statement.
The ERL function returns only the line number, not line labels, located at
or before the line producing the error. If your program has no line numbers,
or there is no line number in the program before the point where the error
occurred, ERL returns 0.
ERL values differ between programs compiled with BC and those run under
QBX. In programs compiled with BC, ERL is set to the last numbered line in
the source file preceding the line where the error occurred. When QBX
detects an error in a procedure, it looks for a line number only within the
immediate procedure. If the procedure doesn't contain a numbered line, QBX
returns 0 for ERL.
You can make your programs run identically with both BC and QBX by always
including a line number at the beginning of a procedure where an error might
occur.
See Also
ERROR; ON ERROR; RESUME; Table 4.1, "Run-Time Error Codes"
Example
See the ON ERROR statement programming example, which uses the ERR
function.
ERR Statement
────────────────────────────────────────────────────────────────────────────
Action
Sets ERR to a specific value.
Syntax
ERR = n%
Remarks
The argument n% is an integer expression with a value between 1 and 255,
inclusive, that specifies a run-time error code, or 0.
When running an application program, BASIC uses ERR to record whether or
not a run-time error has occurred and what the error was. When a program
starts running, ERR is 0; when and if a run-time error occurs, BASIC sets
ERR to the error code for that error.
You may want to use the ERR statement to set ERR to a non-zero value to
communicate error information between procedures. For example, you might use
one of the run-time codes not used by BASIC as an application-specific error
code. See Table 4.1, "Run-Time Error Codes," for a list of the run-time
error codes that BASIC uses; they are a subset of the integers between 1 and
255, inclusive.
Besides the ERR statement, the following BASIC statements set ERR whenever
they execute:
■ Any form of the RESUME statement sets ERR to 0.
■ EXIT SUB, EXIT FUNCTION, or EXIT DEF sets ERR to 0 if executed
within a procedure-level error handler.
■ All uses of the ON ERROR or ON LOCAL ERROR statements syntax set
ERR to 0.
■ The ERROR statement can be used to set ERR to any value as part of
simulating any run-time error.
See Also
ERR, ERL; ERROR; Table 4.1, "Run-Time Error Codes"
Example
See the ON ERROR statement programming example, which uses the ERR
statement.
ERROR Statement
────────────────────────────────────────────────────────────────────────────
Action
Simulates the occurrence of a BASIC error or a user-defined error.
Syntax
ERROR integerexpression%
Remarks
The argument integerexpression% represents the error code. It must be
between 1 and 255, inclusive. If integerexpression% is an error code
already used by BASIC, the ERROR statement simulates the occurrence of that
error.
To define your own error code, use a value that is greater than any used by
the standard BASIC error codes. (Start at 255 and work down to avoid
compromising compatibility with future Microsoft BASIC error codes.) In
general, the error codes used by BASIC are between 1 and 100 (although not
all these are used).
If an error statement is executed when no error-handling routine is enabled,
BASIC generates an error message and stops program execution. If the ERROR
statement specified an error code that is not used by BASIC, the message
Unprintable error is generated.
See Also
ERR, ERL; ON ERROR; RESUME
Example
See the ON ERROR statement programming example, which uses the ERROR
statement.
EVENT Statements
────────────────────────────────────────────────────────────────────────────
Action
Enable or disable trapping of events.
Syntax
EVENT ON
EVENT OFF
Remarks
EVENT ON enables trapping of events until BASIC encounters the next EVENT
OFF statement.
EVENT OFF disables trapping of events until BASIC encounters the next
EVENT ON statement.
The EVENT statements affect compiled code generation. When EVENT OFF is in
effect, the compiler will not generate any event-checking code between
statements. EVENT OFF is equivalent to compiling a program without /V or
/W. EVENT OFF can be used to create small and fast code that still supports
event trapping.
If your program contains event-handling statements and you are compiling
from the BC command line, use the BC /W or /V option. (The /W option checks
for events at every label or line number; the /V option checks at every
statement.) If you do not use these options and your program contains event
traps, BASIC generates the error message ON event without /V or /W on
command line.
EVENT OFF and EVENT ON can be used to bracket sections of code where
events do not need to be detected and trapped, and fast performance is
required. Events still could be detected and tracked if a subroutine using
EVENT ON were called from a section of EVENT OFF code.
If an event occurs while EVENT OFF is in effect, this event still is
remembered and then is handled as soon as an EVENT ON block is entered.
See Also
ON event
Example
See the STRIG statements programming example, which uses the EVENT
statements.
EXIT Statement
────────────────────────────────────────────────────────────────────────────
Action
Exits a DEF FN function, a DO... LOOP or FOR... NEXT loop, or a FUNCTION
or SUB procedure.
Syntax
EXIT { DEF | DO | FOR | FUNCTION | SUB}
Remarks
There are a number of ways to use the EXIT statement, as described in the
following list:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Statement Description
────────────────────────────────────────────────────────────────────────────
EXIT DEF Causes an immediate exit from the
executing DEF FN function.
Program execution continues where
the DEF FN function was invoked.
EXIT DO Provides an alternative exit from
a DO... LOOP statement. Can be
used only inside a DO... LOOP
statement; EXIT DO transfers
control to the statement following
the LOOP statement. When used
within nested DO... LOOP
statements, transfers out of the
immediately enclosing loop.
EXIT FOR Provides another way to exit a
FOR... NEXT loop. May appear only
in a FOR... NEXT loop; transfers
control to the statement following
Statement Description
────────────────────────────────────────────────────────────────────────────
control to the statement following
the NEXT statement. When used
within nested FOR... NEXT loops,
transfers out of the immediately
enclosing loop.
EXIT FUNCTION Causes an immediate exit from a
FUNCTION procedure. Program
execution continues where the
procedure was invoked. Can be used
only in a FUNCTION procedure.
EXIT SUB Immediately exits a SUB procedure.
Program execution continues with
the statement after the CALL
statement. Can be used only in a
SUB procedure.
None of the EXIT statements defines the end of the structure in which it is
used. EXIT statements provide only an alternative exit from the structure.
See Also
DEF FN, DO... LOOP, FOR... NEXT, FUNCTION, SUB
Example
The following example demonstrates the use of a variety of EXIT statements.
A loop is continuously executed until a key is pressed. Once a key is
pressed, the next EXIT statement that executes will cause the program to
end.
DECLARE SUB ExitDemo ()
CLS
DO
PRINT : PRINT "Entering/Re-entering ExitDemo"
ExitDemo
SLEEP 1
LOOP WHILE INKEY$ = ""
PRINT "Exiting EXIT statement programming example."
END
SUB ExitDemo
DO
FOR I% = 1 TO 1000
Num% = INT(RND * 100)
SELECT CASE Num%
CASE 7
PRINT "Exiting FOR...NEXT loop in ExitDemo SUB"
EXIT FOR
CASE 29
PRINT "Exiting DO...LOOP in ExitDemo SUB"
EXIT DO
CASE 54
PRINT "Exiting ExitDemo SUB"
EXIT SUB
CASE ELSE
END SELECT
NEXT I%
LOOP
END SUB
EXP Function
────────────────────────────────────────────────────────────────────────────
Action
Calculates the exponential function.
Syntax
EXP( x)
Remarks
The EXP function returns e (the base of natural logarithms) to the power
of x.
The exponent x must be less than or equal to 88.02969 when you are using
single-precision values and less than or equal to 709.782712893 when you are
using double-precision values. If you use a value of x that isn't within
those limits, BASIC generates the error message Overflow.
EXP is calculated in single precision if x is an integer or
single-precision value. If you use any other numeric data type, EXP is
calculated in double precision.
See Also
LOG
Example
The following example uses the EXP function to calculate the growth of a
bacterial colony over a 15-day period. The program prompts you for an
initial population and the rate of growth.
CLS ' Clear screen.
INPUT "Initial bacterial population"; Colony0
INPUT "Growth rate per day as a percentage of population"; Rate
R = Rate / 100 : Form$ = "## ###,###,###,###"
PRINT : PRINT "Day Population"
FOR T = 0 TO 15 STEP 5
PRINT USING Form$; T, Colony0 * EXP(R * T)
NEXT
Output
Initial bacterial population? 10000
Growth rate per day as a percentage of population? 10
Day Population
0 10,000
5 16,487
10 27,183
15 44,817
FIELD Statement
────────────────────────────────────────────────────────────────────────────
Action
Allocates space for variables in a random-access file buffer.
Syntax
FIELD «#» filenumber%, fieldwidth% ASstringvariable$ «, fieldwidth%
ASstringvariable$»...
Remarks
The FIELD statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file.
fieldwidth% The number of characters in a
field.
stringvariable$ The string variable that contains
the data read from a record, or
data that is used in an assignment
when information is written to a
record.
The total number of bytes that you allocate in a FIELD statement must not
exceed the record length you specified when opening the file. Otherwise,
BASIC generates an error message that reads FIELD overflow. (The default
record length is 128 bytes.)
Any number of FIELD statements can be executed for the same file. All
FIELD statements that have been executed remain in effect at the same time.
All field definitions for a file are removed when the file is closed; that
is, all strings defined as fields associated with the file are set to null.
Note
Do not use a variable name defined as a field in an INPUT or assignment
statement if you want the variable to remain a field. Once a variable name
is a field, it points to the correct place in the random-access file buffer.
If a subsequent INPUT or assignment statement with that variable name is
executed, the variable's pointer no longer refers to the random-access
record buffer, but to string space.
BASIC's record variables and extended OPEN statement syntax provide a more
convenient way to use random-access files. See Chapter 3, "File and Device
I/O" in the Programmer's Guide for an extended discussion of using record
variables for file I/O.
BASICA
When a random-access file is closed with a CLOSE or RESET statement in a
compiled program, all variables that are fields associated with that file
are reset to null strings. When a random-access file is closed in a BASICA
program, variables that are fields retain the last value assigned to them by
a GET statement.
See Also
GET (File I/O), LSET, PUT (File I/O), RSET
Example
The example below illustrates a random-access file buffer with multiple
definitions.
In the first FIELD statement, the 67-byte buffer is broken up into five
separate variables for name, address, city, state, and zip code. In the
second FIELD statement, the same buffer is assigned entirely to one
variable, Plist$.
The remainder of this example checks to see if Zip$, which contains the zip
code, falls within a certain range; if it does, the complete address string
is printed.
TYPE Buffer
FuName AS STRING * 25
Addr AS STRING * 25
City AS STRING * 10
State AS STRING * 2
Zip AS STRING * 5
END TYPE
DIM RecBuffer AS Buffer
' This part of the program creates a random-access file for use by the
' second part of the program, which demonstrates the FIELD statement.
OPEN "MAILLIST.DAT" FOR RANDOM AS #1 LEN = LEN(RecBuffer)
CLS
RESTORE
READ FuName$, Addr$, City$, State$, Zip$
I = 0
DO WHILE UCASE$(FuName$) <> "END"
I = I + 1
RecBuffer.FuName = FuName$
RecBuffer.Addr = Addr$
RecBuffer.City = City$
RecBuffer.State = State$
RecBuffer.Zip = Zip$
PUT #1, I, RecBuffer
READ FuName$, Addr$, City$, State$, Zip$
IF FuName$ = "END" THEN EXIT DO
LOOP
CLOSE #1
DATA "Bob Hartzell","1200 Liberty St.","Bow","WA","98232"
DATA "Alice Provan","123 B St.","Bellevue","WA","98005"
DATA "Alex Landow","14900 123rd","Bothell","WA","98011"
DATA "Walt Riley","33 Minnow Lake Road","Lyman","WA","98263"
DATA "Georgette Gump","400 15th W.","Bellevue","WA","98007"
DATA "END",0,0,0,0,0
' Define field and record lengths with constants.
CONST FU = 25, AD = 25, CT = 10, ST = 2, ZP = 5
CONST RECLEN = FU + AD + CT + ST + ZP
OPEN "MAILLIST.DAT" FOR RANDOM AS #1 LEN = RECLEN
FIELD #1, FU AS FuName$, AD AS Addr$, CT AS City$, ST AS State$, ZP AS Zip$
FIELD #1, RECLEN AS Plist$
GET #1, 1
' Read the file, looking for zip codes in the range 98000 to 98015.
DO WHILE NOT EOF(1)
Zcheck$ = Zip$
IF (Zcheck$ >= "98000" AND Zcheck$ <= "98015") THEN
Info$ = Plist$
PRINT LEFT$(Info$, 25)
PRINT MID$(Info$, 26, 25)
PRINT RIGHT$(Info$, 17)
PRINT
END IF
GET #1
LOOP
CLOSE #1
FILEATTR Function
────────────────────────────────────────────────────────────────────────────
Action
Returns information about an open file or ISAM table.
Syntax
FILEATTR( filenumber%, attribute%)
Remarks
FILEATTR returns information about an open file or ISAM table, such as the
DOS file handle and whether the file was opened for input, output, random,
append, or ISAM binary mode.
The FILEATTR function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file or ISAM
table. You can use a numeric
expression as long as BASIC
evaluates it to the number of an
open file, device, or ISAM table.
Argument Description
────────────────────────────────────────────────────────────────────────────
attribute% Indicates the type of information
to return about the file or table.
When attribute% is 1, FILEATTR
returns a value indicating the
file's mode (see below). When
attribute% is 2 and filenumber%
indicates a file, FILEATTR
returns the DOS handle for the
file. When attribute% is 2 and
filenumber% indicates an ISAM
table, FILEATTR returns 0.
The following table lists the return values and corresponding file modes
when attribute% is 1:
╓┌────────────────────────────┌──────────────────────────────────────────────╖
Return value Mode
────────────────────────────────────────────────────────────────────────────
1 Input
2 Output
4 Random access
8 Append
32 Binary
64 ISAM
See Also
OPEN (File I/O)
Example
The following example opens a file and displays its DOS file handle and
mode:
OPEN "tempfile.dat" FOR APPEND AS #1
PRINT "Handle: "; FILEATTR(1,2); " Mode: "; FILEATTR(1,1)
Output
Handle: 5 Mode: 8
FILES Statement
────────────────────────────────────────────────────────────────────────────
Action
Prints the names of files residing on the specified disk.
Syntax
FILES «filespec$»
Remarks
The argument filespec$ is a string variable or constant that includes
either a filename or a path, and an optional device name.
If no argument is specified, the FILES statement lists all the files in the
current directory. You can use the DOS wildcard characters -- question
marks ( ?) or asterisks (*). A question mark matches any single character in
the filename or extension. An asterisk matches one or more characters
starting at that position.
If you use filespec$ without an explicit path, the current directory is the
default.
Examples
The statements below illustrate the use of FILES.
Note that execution halts if you try to run this example without a disk in
drive B or if the specified files cannot be found.
FILES' Show all files on the current directory.
FILES "*.BAS" ' Show all files with the extension .BAS.
FILES "B:*.*" ' Show all files in current directory of drive B.
FILES "B:" ' Equivalent to "B:*.*".
FILES "TEST?.BAS" ' Show all five-letter files whose names start
' with "TEST" and end with the .BAS extension.
FILES "SALES\"' If SALES is a directory, this statement
' displays all files in SALES.
FIX Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the truncated integer part of a numeric expression.
Syntax
FIX( x#)
Remarks
The argument x# is a numeric expression. FIX( x#) is equivalent to SGN(
x#)*INT(ABS( x#)) . The difference between FIX and INT is that for
negative x#, FIX returns the first negative integer greater than x#,
while INT returns the first negative integer less than x#.
See Also
CINT, INT
Example
The following statements illustrate the differences between INT and FIX:
PRINT INT(-99.8)
PRINT FIX(-99.8)
PRINT INT(-99.2)
PRINT FIX(-99.2)
Output
-100
-99
-100
-99
FOR...NEXT Statement
────────────────────────────────────────────────────────────────────────────
Action
Repeats a group of instructions a specified number of times.
Syntax
FOR counter = start TO end «STEP increment»
« statementblock»
« EXIT FOR»
« statementblock»
NEXT «counter «, counter»...»
Remarks
The FOR statement takes the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
counter A numeric variable used as the
loop counter. The variable cannot
be an array element or a record
element.
start The initial value of the counter.
end The final value of the counter.
increment The amount the counter is changed
each time through the loop. If you
do not specify STEP, increment
defaults to one.
A FOR... NEXT loop executes only if start and end are consistent with
increment. If end is greater than start, increment must be positive. If
end is less than start, increment must be negative. BASIC checks this at
run time by comparing the sign of ( end - start) with the sign of
step. If both have the same sign, the FOR... NEXT loop is entered. If not,
the entire loop is skipped.
Within the FOR... NEXT loop, the program lines following the FOR statement
are executed until the NEXT statement is encountered. Then counter is
changed by the amount specified by STEP, and compared with the final value,
end.
If start and end have the same value, the loop executes once, regardless
of the value of STEP. Otherwise, STEP value controls the loop as follows:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
STEP value Loop execution
────────────────────────────────────────────────────────────────────────────
Positive If counter is less than or equal
to end, control returns to the
statement after the FOR statement
and the process repeats. If
counter is greater than end, the
loop is exited; execution
STEP value Loop execution
────────────────────────────────────────────────────────────────────────────
loop is exited; execution
continues with the statement
following the NEXT statement.
Negative The loop repeats until counter is
less than end.
Zero The loop repeats indefinitely.
Avoid changing the
value of counter within the loop. Changing the loop counter is poor
programming practice; it can make the program more difficult to read and
debug.
You can nest FOR... NEXT loops; that is, you can place a FOR... NEXT loop
within another FOR... NEXT loop. To ensure that nested loops work properly,
give each loop a unique variable name as its counter. The NEXT statement
for the inside loop must appear before the NEXT statement for the outside
loop. The following construction is correct:
FOR I = 1 TO 10
FOR J = 1 TO 10
FOR K = 1 TO 10
.
.
.
NEXT K
NEXT J
NEXT I
A NEXT statement with the form NEXT K, J, I is equivalent to the following
sequence of statements:
NEXT K
NEXT J
NEXT I
The EXIT FOR statement is a convenient alternative exit from FOR... NEXT
loops. See the entry for EXIT.
Note
If you omit the variable in a NEXT statement, the NEXT statement matches
the most recent FOR statement. If a NEXT statement is encountered before
its corresponding FOR statement, BASIC generates the error message NEXT
without FOR.
BASICA
Unlike BASICA, BASIC supports double-precision control values ( start, end,
and counter) in its FOR...NEXT loops. However, if the control values fall
within the range for integers, you should use integer control values for
maximum speed.
Example
The following example prints the first 11 columns of Pascal's Triangle, in
which each number is the sum of the number immediately above it and the
number immediately below it in the preceding column:
DEFINT A-Z
CLS ' Clear screen.
CONST MAXCOL = 11
DIM A(MAXCOL, MAXCOL)
PRINT "Pascal's Triangle"
FOR M = 1 TO MAXCOL
A(M, 1) = 1: A(M, M) = 1' Top and bottom of each column is 1.
NEXT
FOR M = 3 TO MAXCOL
FOR N = 2 TO M - 1
A(M, N) = A(M - 1, N - 1) + A(M - 1, N)
NEXT
NEXT
Startrow = 13 ' Go to the middle of the screen.
FOR M = 1 TO MAXCOL
Col = 6 * M
Row = Startrow
FOR N = 1 TO M
LOCATE Row, Col: PRINT A(M, N)
Row = Row + 2' Go down 2 rows to print next number.
NEXT
PRINT
Startrow = Startrow - 1' Next column starts 1 row above
NEXT' preceding column.
Output
Pascal's Triangle
1
1
1 10
1 9
1 8 45
1 7 36
1 6 28 120
1 5 21 84
1 4 15 56 210
1 3 10 35 126
1 2 6 20 70 252
1 3 10 35 126
1 4 15 56 210
1 5 21 84
1 6 28 120
1 7 36
1 8 45
1 9
1 10
1
1
FRE Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a value representing the amount of available memory, depending upon
a given argument.
Syntax 1
FRE( numeric- expression%)
Syntax 2
FRE( stringexpression$)
Remarks
The argument for FRE can be either a string or numeric expression . The
argument stringexpression$ can be a string literal or a string variable.
The values returned for the different types of arguments depend on whether
you are using near strings or far strings, as described in the following
table:
╓┌──────────────────────┌─────────────────────────┌──────────────────────────╖
Function Value returned if using Value returned if using
near strings far strings
────────────────────────────────────────────────────────────────────────────
FRE(a$) Remaining space inDGROUP Remaining space in a$'s
(in bytes) segment (in bytes)
FRE("string literal") Remaining space inDGROUP Remaining space for
(in bytes) temporary strings (in
bytes)
FRE(0) Remaining space in Error message: Illegal
DGROUP (in bytes) function call
FRE(-1) For DOS, remaining space For DOS, remaining space
(in bytes) in far (in bytes) in far memory;
memory; for OS/2, long for OS/2, long integer
integer 2147483647 2147483647
FRE(-2) Remaining stack space Remaining stack space (in
(in bytes) bytes)
Function Value returned if using Value returned if using
near strings far strings
────────────────────────────────────────────────────────────────────────────
(in bytes) bytes)
FRE(-3) Remaining space in Remaining space in
expanded memory (in expanded memory (in
kilobytes) kilobytes)
FRE(any other no.) Error message: Illegal Error message: Illegal
function call function call
FRE(-2) returns the amount of stack space that was never used by the
program. For example, suppose a program uses a lot of stack space in a
recursive procedure and then returns to the main level to execute a FRE(-2).
The value returned will be the amount of stack space that was never used by
the program. Any space used by the recursive procedure is considered "used"
So FRE(-2) enables you to find out at the completion of your program what
the worst-case stack usage was for that program.
Using FRE(-3) and Expanded Memory
If expanded memory is not available, FRE(-3) generates the error message
Feature unavailable.
If you start QBX without the /E: n switch, you will be using all of the
expanded memory available on your computer. If you start QBX with the /E: n
switch, you can limit the amount of expanded memory available to your
program. For example, if your computer has 5 megabytes of expanded memory
but you want to use only 4 megabytes of expanded memory, you would start QBX
with this command line:
QBX /E:4096
If you have specified 4 megabytes of expanded memory as shown above, and
then you use 2 megabytes of expanded memory in your program, FRE(-3) will
return 2048.
If you are using BC to run a program with expanded memory overlays, the
value returned by FRE(-3) is based on the total amount of expanded memory
available. (When using overlays, you cannot limit the amount of expanded
memory used by your program.)
For more information on using expanded memory, see "Memory Management for
QBX" in Getting Started.
Note
FRE(-2) returns meaningful values only when a program is executing. Values
returned by FRE(-2) are not accurate when the function is called from the
Immediate window, during program tracing, or when monitoring a variable.
Example
The following example demonstrates use of the FRE function to report the
availability of memory resources. It also uses the STACK function to
allocate stack space.
DECLARE SUB MakeSubString ()
DECLARE SUB Printit (A$)
DECLARE SUB Recursive (n!)
PRINT "Remaining space to begin with is:"
CALL Printit(A$)
String1$ = STRING$(32767, 90)' Create a 32K string.
PRINT " The remaining space after creating a 32K far string is:"
CALL Printit(String1$)
MakeSubString ' Make a substring and give report.
PRINT "The remaining space after returning from a SUB is:"
CALL Printit(String2$)
n = 50 ' Do 50 recursive calls to a SUB procedure.
CALL Recursive(n)
STACK (2048)
PRINT "After allocating 2K for the stack, the space is:"
CALL Printit(A$)
n = 50 ' Do another 50 recursive calls to a SUB procedure.
CALL Recursive(n)
'Dimension a 1001-element dynamic array in EMS.
REDIM A%(999)
PRINT "After dimensioning a 1000-element integer array, the space is:"
CALL Printit(A$)
PRINT "After dimensioning a second 1000-element integer array:"
CALL Printit(A$)
PRINT "Stack reset to default value: "; STACK
SUB MakeSubString
SHARED String1$
String2$ = STRING$(32767, 90)
PRINT "The space remaining after creating a 32K sub string is:"
CALL Printit(String1$)
END SUB
SUB Printit (A$)
PRINT : PRINT "Far Memory"; TAB(15); "Stack"; TAB(25);
PRINT "String Segment";TAB(45);"Temporary Segment";TAB(65);"EMS Memory"
PRINT FRE(-1); TAB(15); FRE(-2); TAB(25); FRE(A$); TAB(45); FRE("")
PRINT TAB(65); FRE(-3); "K"
END SUB
SUB Recursive (n)
SHARED String1$
n = n - 1
IF n = 0 THEN
PRINT "The remaining space after 50 recursive calls is:"
CALL Printit(String1$)
EXIT SUB
ELSE
CALL Recursive(n)
END IF
END SUB
FREEFILE Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the next valid unused file number.
Syntax
FREEFILE
Remarks
Use FREEFILE when you need to supply a file number and you want to ensure
that the file number is not already in use.
See Also
OPEN (File I/O)
Example
The following example uses FREEFILE to obtain the next available file
number for opening a sequential file. OPEN, CLOSE, and KILL also are
used.
DIM Filenum AS INTEGER
CLS
INPUT "Enter filename: ", filename$
Filenum% = FREEFILE
OPEN filename$ FOR OUTPUT AS Filenum%
PRINT
PRINT UCASE$(filename$); " opened for output as File #"; Filenum%
' Put something out to the file.
PRINT #Filenum%, "The quick brown fox jumped over the lazy dog."
' Close the file just opened.
CLOSE Filenum%
Filenum% = FREEFILE
OPEN filename$ FOR INPUT AS Filenum%
PRINT : PRINT UCASE$(filename$); " has been reopened for input."
LINE INPUT #Filenum%, L$
PRINT : PRINT "The contents of the file are:"; L$
CLOSE Filenum%
' Remove the file from disk.
KILL filename$
FUNCTION Statement
────────────────────────────────────────────────────────────────────────────
Action
Declares the name, the parameters, and the return type of a FUNCTION
procedure.
Syntax
FUNCTION name «( parameterlist») « STATIC»
« statementblock»
« name = expression»
« statementblock»
« EXIT FUNCTION»
« statementblock»
END FUNCTION
Remarks
The following list describes the parts of the FUNCTION statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
name The name of the function.
FUNCTION procedure names follow
the same rules as are used for
naming BASIC variables and can
include a type-declaration
character (%, &, !, #, @,
or $). Note that the type of the
name determines the data type the
function returns. For example, to
create a function that returns a
Part Description
────────────────────────────────────────────────────────────────────────────
create a function that returns a
string, you would include a dollar
sign in the name or give it a name
defined as a string name by a
DEFSTR statement.
parameterlist The list of variables,
representing parameters, that will
be passed to the function
procedure when it is called.
Multiple variables are separated
by commas. Parameters are passed
by reference, so any change to a
parameter's value inside the
function changes its value in the
calling program.
STATIC Indicates that the function's
local variables are to be saved
Part Description
────────────────────────────────────────────────────────────────────────────
local variables are to be saved
between calls. Without STATIC,
the local variables are allocated
each time the function is invoked,
and the variables' values are lost
when the function returns to the
calling program. The STATIC
attribute does not affect
variables that are used in a
FUNCTION procedure but declared
outside the procedure in DIM or
COMMON statements using the
SHARED statement.
expression The return value of the function.
A FUNCTION procedure returns a
value by assigning a value to the
function name. If no value is
assigned to the FUNCTION name,
Part Description
────────────────────────────────────────────────────────────────────────────
assigned to the FUNCTION name,
the procedure returns a default
value: a numeric function returns
zero, and a string function
returns the null string ("").
EXIT FUNCTION Causes an immediate exit from a
FUNCTION procedure. Program
execution continues where the
procedure was invoked. For more
information, see the entry for the
EXIT statement.
The argument parameterlist has the following syntax:
variable «()» « AS type» «, variable«()» « AS type»»...
The following list describes the parts of parameterlist :
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
variable A BASIC variable name. Previous
versions of BASIC required the
number of dimensions in
parentheses after an array name.
In the current version of BASIC,
the number of dimensions is not
required.
AS type The type of the variable: INTEGER,
LONG, SINGLE, DOUBLE, STRING,
CURRENCY, or a user-defined type.
You cannot use a fixed-length
string, or an array of
fixed-length strings, as a
parameter. However, you can use a
simple fixed-length string as an
argument in a CALL statement;
Argument Description
────────────────────────────────────────────────────────────────────────────
argument in a CALL statement;
BASIC converts a simple
fixed-length string argument to a
variable-length string argument
before passing the string to a
FUNCTION procedure.
Earlier versions of BASIC required the number of dimensions in parentheses
after an array name. The number of dimensions is no longer required. Only
the parentheses are required to indicate the parameter is an array. For
example, the following statement indicates that both Keywords$ and
KeywordTypes are arrays:
FUNCTION ParseLine(Keywords$(),KeywordTypes())
A FUNCTION procedure is like a SUB procedure: it can accept parameters,
perform a series of statements, and change the values of its parameters.
Unlike a SUB procedure, a FUNCTION procedure is used in an expression in
the same manner as a BASIC intrinsic function.
Like SUB procedures, FUNCTION procedures use local variables. Any variable
referred to within the body of the function is local to the FUNCTION
procedure unless one of the following conditions is true:
■ The variable is declared within the function as a shared
variable with a SHARED statement.
■ The variable appears in a DIM or COMMON statement with the
SHARED attribute at the module level.
To return a value from a function, assign the value to the function name.
For example, in a function named BinarySearch, you might assign the value of
the constant FALSE to the name to indicate the value was not found:
FUNCTION BinarySearch(...)
CONST FALSE=0
.
.
.
' Value not found. Return a value of FALSE.
IF Lower>Upper THEN
BinarySearch=FALSE
EXIT FUNCTION
END IF
.
.
.
END FUNCTION
Using the STATIC attribute increases execution speed slightly. STATIC
usually is not used with recursive FUNCTION procedures.
Note
Avoid using I/O statements in a FUNCTION procedure called from an I/O
statement; they can cause unpredictable results. Also, because BASIC may
rearrange arithmetic expressions to attain greater efficiency, avoid using
FUNCTION procedures that change program variables in arithmetic expressions.
FUNCTION procedures are recursive -- they can call themselves to
perform a given task. See the example for more information.
See Also
DECLARE (BASIC), DEF FN, STATIC Statement, SUB
Example
The following example uses a recursive FUNCTION procedure (a procedure that
calls itself) to find, and return as an integer, the length of a string:
DECLARE FUNCTION StrgLng% (X$).
INPUT "Enter a string: "; InString$
PRINT "The string length is"; StrgLng%(InString$)
FUNCTION StrgLng% (X$)
IF X$ = "" THEN
StrLng% = 0 ' The length of a null string is zero.
ELSE
StrgLng% = 1 + StrgLng%(MID$(X$, 2)) ' Make a recursive call.
END IF
END FUNCTION
GET Statement (File I/O)
────────────────────────────────────────────────────────────────────────────
Action
Reads from a disk file into a random-access buffer or variable.
Syntax
GET «#» filenumber%«,« recordnumber%» «, variable»»
Remarks
Do not use GET on ISAM files.
The GET statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file.
recordnumber% For random-access files, the
number of the record to be read.
For binary-mode files, the byte
position where reading starts. The
first record or byte position in a
file is 1. If you omit
Argument Description
────────────────────────────────────────────────────────────────────────────
file is 1. If you omit
recordnumber%, the next record or
byte (the one after the last GET
or PUT statement, or the one
pointed to by the last SEEK) is
read into the buffer. The largest
possible record number is 2to31 -1,
or 2,147,483,647.
variable The variable used to receive input
from the file. If you specify a
variable, you do not need to use
CVI, CVL, CVS, CVD, or CVC to
convert record fields to numbers.
You cannot use a FIELD statement
with the file if you use the
variable argument.
For random-access files, you can
Argument Description
────────────────────────────────────────────────────────────────────────────
For random-access files, you can
use any variable as long as the
length of the variable is less
than or equal to the length of the
record. Usually, a record variable
defined to match the fields in a
data record is used.
For binary-mode files, you can use
any variable. The GET statement
reads as many bytes as there are
in the variable.
When you use a variable-length
string variable, the statement
reads as many bytes as there are
characters in the string's value.
For example, the following two
statements read 10 bytes from file
Argument Description
────────────────────────────────────────────────────────────────────────────
statements read 10 bytes from file
number 1:
VarStrings$=STRING$ (10, " ")
GET #1,,VarString$
See the examples for more
information about using variables
rather than FIELD statements for
random-access files.
A record cannot be longer than 32,767 bytes.
You can omit recordnumber%, variable, or both. If you omit recordnumber%
but include a variable, you must still include the commas:
GET #4,,FileBuffer
If you omit both arguments, do not include the commas:
GET #4
GET and PUT statements allow fixed-length input and output for BASIC
communication files. Use GET carefully, because if there is a communication
failure, GET waits indefinitely.
Note
When you use GET with the FIELD statement, you can use INPUT # or LINE
INPUT # after a GET statement to read characters from the random-access
file buffer. You can use the EOF function after a GET statement to see if
the GET operation went beyond the end of the file.
See Also
CVI, CVL, CVS, CVD, CVC; LSET; MKI$, MKL$, MKS$, MKD$, MKC$; OPEN
(File I/O); PUT (File I/O)
Example
The following example creates a random-access test file that contains five
names and corresponding test scores. It then displays the contents of the
file using the GET statement.
' Define record fields.
TYPE TestRecord
NameField AS STRING * 20
ScoreField AS SINGLE
END TYPE
' Define a variable of the user type.
DIM Rec AS TestRecord
DIM I AS LONG
' This part of the program creates a random-access file to be used by
' the second part of the program, which demonstrates the GET statement.
OPEN "TESTDAT2.DAT" FOR RANDOM AS #1 LEN = LEN(Rec)
CLS
RESTORE
READ NameField$, ScoreField
I = 0
DO WHILE NameField$ <> "END"
I = I + 1
Rec.NameField = NameField$
Rec.ScoreField = ScoreField
PUT #1, I, Rec
READ NameField$, ScoreField
LOOP
CLOSE #1
DATA "John Simmons", 100
DATA "Allie Simpson", 95
DATA "Tom Tucker", 72
DATA "Walt Wagner", 90
DATA "Mel Zucker", 92
DATA "END", 0
' Open the test data file.
DIM FileBuffer AS TestRecord
DIM Max AS LONG
OPEN "TESTDAT2.DAT" FOR RANDOM AS #1 LEN = LEN(FileBuffer)
'Calculate number of records in the file.
Max = LOF(1) \ LEN(FileBuffer)
' Read and print contents of each record.
FOR I = 1 TO Max
GET #1, I, FileBuffer
PRINT FileBuffer.NameField, FileBuffer.ScoreField
NEXT I
CLOSE #1
' Remove file from disk.
KILL "TESTDAT2.DAT"
END
GET Statement (Graphics)
────────────────────────────────────────────────────────────────────────────
Action
Stores graphic images from the screen.
Syntax
GET STEP( x1!, y1!) - STEP( x2!, y2!), arrayname(
indexes%)
Remarks
The list below describes the parts of the GET statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
( x1!, y1!),( x2!, y2!) Coordinates that mark a
Part Description
────────────────────────────────────────────────────────────────────────────
( x1!, y1!),( x2!, y2!) Coordinates that mark a
rectangular area on the screen; an
image within this rectangle will
be stored. The x1!, y1!, x2!,
and y2! are numeric expressions.
The coordinates ( x1!, y1!) and (
x2!, y2!) are the coordinates of
diagonally opposite corners of the
rectangle.
STEP Keyword indicating that
coordinates are relative to the
most recently plotted point. For
example, if the last point plotted
were (10,10), the actual
coordinates referred to by STEP
(5,10) would be (5+10,10+10) or
(15,20). If the second coordinate
pair in a GET statement has a
Part Description
────────────────────────────────────────────────────────────────────────────
pair in a GET statement has a
STEP argument, it is relative to
the first coordinate pair in the
statement.
arrayname Name assigned to the array that
holds the image. This array can be
of any numeric type; its
dimensions must be large enough to
hold the entire image.
indexes% Numeric constants or variables
indicating the element of the
array where the saved image starts.
The GET statement transfers a screen image into the array specified by
arrayname. The PUT statement, associated with GET, transfers the image
stored in the array onto the screen.
The following formula gives the required size of the array in bytes:
size = 4 + INT((( x2! - x1! + 1) * ( bits-per-pixel-per-plane) +
7)/8) * planes * (( y2! - y1!) + 1)
The bits-per-pixel-per-plane and planes values depend on the screen mode
set by the SCREEN statement. The following table shows the number of
bits-per-pixel-per-plane and the number of planes for each screen mode:
╓┌────────────────────────┌─────────────────────────┌────────────────────────╖
Screen mode Bits per pixel per plane Planes
────────────────────────────────────────────────────────────────────────────
1 2 1
2 1 1
7 1 4
8 1 4
9 (64K of EGA memory) 1 2
9 (> 64K of EGA memory) 1 4
Screen mode Bits per pixel per plane Planes
────────────────────────────────────────────────────────────────────────────
9 (> 64K of EGA memory) 1 4
10 1 2
11 1 1
12 1 4
13 8 1
The bytes per element of an array are as follows:
■ Two bytes for an integer array element.
■ Four bytes for a long-integer array element.
■ Four bytes for a single-precision array element.
■ Eight bytes for a double-precision array element.
■ Eight bytes for a currency array element.
For example, suppose you wanted to use the GET statement to store an image
in high resolution (SCREEN 2). If the coordinates of the upper-left corner
of the image are (0,0), and the coordinates of the lower-right corner are
(32,32), then the required size of the array in bytes is 4 + INT((33 * 1 +
7)/8) * 1 * (33), or 169. This means an integer array with 85 elements would
be large enough to hold the image.
Unless the array type is integer or long, the contents of an array after a
GET operation appear meaningless when inspected directly. Examining or
manipulating noninteger arrays containing graphics images may cause run-time
errors.
GET and PUT statements operating on the same image should be executed in
matching screen modes. These modes can be either the same screen mode or any
screen modes with the same values for planes and bits-per-pixel-per-plane.
One of the most useful things that can be done with GET and PUT statements
is animation. See Chapter 5, "Graphics" in the Programmer's Guide for a
discussion of animation.
See Also
PUT (Graphics)
Example
See the BSAVE statement programming example, which uses the GET statement.
GETINDEX$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the name of the current index for an ISAM table.
Syntax
GETINDEX$ ( filenumber%)
Remarks
The filenumber% is the number used in the OPEN statement to open the
table.
GETINDEX$ takes the number of an open ISAM table and returns the name of
the current index. If the current index is the null index , the value
returned is a null string.
See Also
CREATEINDEX, DELETEINDEX, OPEN (File I/O), SETINDEX
Example
See the CREATEINDEX statement programming example, which uses the
GETINDEX$ function.
GOSUB...RETURN Statements
────────────────────────────────────────────────────────────────────────────
Action
Branch to, and return from, a subroutine.
Syntax
GOSUB { linelabel1 | linenumber1}
.
.
.
RETURN «{ linelabel2 | linenumber2}»
Remarks
The GOSUB... RETURN statements use the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
linelabel1, linenumber1 The line label or line number that
is the first line of the
subroutine.
linelabel2, linenumber2 The line label or line number
where the subroutine returns.
Note
BASIC's SUB and FUNCTION procedures provide a better-structured
alternative to GOSUB... RETURN subroutines.
In addition to RETURN with no argument, BASIC supports RETURN with a line
label or line number. This allows a return from a subroutine to the
statement having the specified line label or number, instead of returning to
the statement after the GOSUB statement. Use this line-specific type of
return with care.
You can call a subroutine any number of times in a program. You also can
call a subroutine from within another subroutine. How deeply you can nest
subroutines is limited only by the available stack space (you can increase
the stack space with the CLEAR statement). Subroutines that call themselves
(recursive subroutines) can easily run out of stack space. RETURN with a
line label or line number can return control to a statement in the
module-level code only, not in procedure-level code. See the example
program.
A subroutine can contain more than one RETURN statement. A simple RETURN
statement (without the linelabel2, linenumber2 option) in a subroutine
makes BASIC branch back to the statement following the most recent GOSUB
statement.
Subroutines can appear anywhere in the program, but it is good programming
practice to make them readily distinguishable from the main program. To
prevent inadvertent entry into a subroutine, precede it with a STOP, END,
or GOTO statement that directs program control around the subroutine.
Note
The preceding discussion of subroutines applies only to the targets of
GOSUB statements, not procedures delimited by SUB statements. For
information on entering and exiting SUB procedures, see the entry for the
CALL statement (BASIC procedures).
See Also
RETURN, SUB
Example
The following example shows the use of the GOSUB and RETURN statements.
Note the END statement before the module-level subroutine. If it is not
present, the PrintMessage subroutine will be executed after the return to
Label1. BASIC will generate the error message RETURN without GOSUB.
CLS
GOSUB PrintMessage
PRINT "This message is in module-level code"
GOSUB Sub1
PRINT "This line in module-level code should be skipped."
Label1:
PRINT "This message is back in module-level code"
END
PrintMessage:
PRINT "This program uses the GOSUB and RETURN statements."
PRINT
RETURN
Sub1:
PRINT "This message is in Sub1."
GOSUB Sub2
PRINT "This line in Sub1 should be skipped."
Label2:
PRINT "This message is back in Sub1."
RETURN Label1
Sub2:
PRINT "This message is in Sub2."
RETURN Label2 ' Cannot return from here to module-level
' code-only to SUB1.
GOTO Statement
────────────────────────────────────────────────────────────────────────────
Action
Branches unconditionally to the specified line.
Syntax
GOTO { linelabel | linenumber}
Remarks
The argument linelabel or linenumber indicates the line to execute next.
This line must be at the same level of the program. The GOTO statement
provides a means for branching unconditionally to another line ( linelabel
or linenumber). A GOTO statement can branch only to another statement at
the same level within a program. You cannot use GOTO to enter or exit a
SUB or FUNCTION procedure or multiline DEF FN function. You can, however,
use GOTO to control program flow within any of these program structures.
It is good programming practice to use structured control statements ( DO...
LOOP, FOR... NEXT, IF... THEN... ELSE, SELECT CASE) instead of GOTO
statements, because a program with many GOTO statements can be difficult to
read and debug.
Example
The following example calculates the area of a circle. The program uses the
GOTO statement to repeat the operation.
CLS ' Clear screen.
PRINT "Input 0 to end."
Start:
INPUT R
IF R = 0 THEN
END
ELSE
A = 3.14 * R ^ 2
PRINT "Area ="; A
END IF
GOTO Start
Output
Input 0 to end.
? 5
Area = 78.5
? 0
HEX$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string that represents the hexadecimal value of the decimal
argument.
Syntax
HEX$( numeric-expression&)
Remarks
The argument numeric-expression&, which has a decimal value, is rounded to
an integer or, if it is outside the integer range, a long integer, before
the HEX$ function evaluates it.
See Also
OCT$
Example
The following example displays the hexadecimal value of a decimal number:
CLS ' Clear screen.
INPUT X
A$ = HEX$(X)
PRINT X; "decimal is "; A$; " hexadecimal."
Output
? 32
32 decimal is 20 hexadecimal.
IF...THEN...ELSE Statement
────────────────────────────────────────────────────────────────────────────
Action
Allows conditional execution, based on the evaluation of a Boolean
expression.
Syntax 1
IF condition THEN thenpart « ELSE elsepart»
Syntax 2
IF condition1 THEN
« statementblock-1»
« ELSEIF condition2 THEN
« statementblock-2»»
« ELSE
« statementblock-n»»
END IF
Remarks
Single-Line IF...THEN...ELSE
The single-line form of the statement (Syntax 1) is best used for short,
straightforward tests where only one action is taken.
The single-line form is never required. Any program using single-line IF...
THEN... ELSE statements can be written using block form.
The following list describes the parts of the single-line form:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
condition Any expression that BASIC
evaluates as true (nonzero) or
false (zero).
thenpart, elsepart The statements or branches
performed when condition is true
( thenpart) or false ( elsepart).
Part Description
────────────────────────────────────────────────────────────────────────────
( thenpart) or false ( elsepart).
Both parts have the same syntax,
which is described below.
The thenpart and the elsepart fields both have the following syntax:
{ statements | « GOTO» linenumber | GOTO linelabel }
The following list describes the parts of the thenpart and elsepart
syntax:
╓┌───────────────┌───────────────────────────────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
statements One or more BASIC statements, separated by colons.
linenumber A valid BASIC program line number.
linelabel A valid BASIC program line label.
Note that GOTO is optional with a line number, but is required with a line
label.
The thenpart is executed if condition is true; if condition is false,
elsepart is executed. If the ELSE clause is not present, control passes to
the next statement in the program.
You can have multiple statements with a condition, but they must be on the
same line and separated by colons, as in the following statement:
IF A > 10 THEN A=A+1:B=B+A:LOCATE 10,22:PRINT B,A
Block IF...THEN...ELSE
The block form (Syntax 2) provides several advantages:
■ The block form provides more structure and flexibility than the
single-line form by allowing conditional branches across several
lines.
■ With the block form, more complex conditions can be tested.
■ The block form lets you use longer statements and structures
within the THEN... ELSE portion of the statement.
■ The block form allows your program's structure to be guided by
logic rather than by how many statements fit on a line.
Programs that use block IF... THEN... ELSE are usually easier to read,
maintain, and debug.
The following list describes the parts of the block IF... THEN... ELSE:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
condition1, condition2 Any expression that BASIC evaluates
as true (nonzero) or false (zero).
statementblock-1, statementblock-2 One or more BASIC statements on one
, statementblock-n or more lines.
In executing a block IF, BASIC tests condition1, the first Boolean
expression. If the Boolean expression is true (nonzero), the statements
following THEN are executed. If the first Boolean expression is false
(zero), BASIC begins evaluating each ELSEIF condition in turn. When BASIC
finds a true condition, the statements following the associated THEN are
executed. If none of the ELSEIF conditions is true, the statements
following the ELSE are executed. After the statements following a THEN or
ELSE are executed, the program continues with the statement following the
END IF.
The ELSE and ELSEIF blocks are both optional. You can have as many ELSEIF
clauses as you would like in a block IF. Any of the statement blocks can
contain nested block IF statements.
BASIC looks at what appears after the THEN keyword to determine whether or
not an IF statement is a block IF. If anything other than a comment
appears after THEN, the statement is treated as a single-line IF
statement.
A block IF statement
must be the first statement on a line. The ELSE, ELSEIF, and END IF parts
of the statement can have only a line number or line label in front of them.
The block must end with an END IF statement.
For more information, see Chapter 1, "Control-Flow Structures" in the
Programmer's Guide.
See Also
SELECT CASE
Examples
The following examples show the use of single-line and block IF... THEN...
ELSE statements.
Here is the single-line form:
CLS ' Clear screen.
DO
INPUT "Enter a number greater than 0 and less than 10,000:", X
IF X >= 0 AND X < 10000 THEN EXIT DO ELSE PRINT X; "out of range"
LOOP
IF X<10 THEN Y=1 ELSE IF X<100 THEN Y=2 ELSE IF X<1000 THEN Y=3 ELSE Y=4
PRINT "The number has"; Y; "digits"
Here is the block form, which is easier to read and more powerful:
CLS ' Clear screen.
DO
INPUT "Enter a number greater than 0 and less than 100,000:", X
IF X >= 0 AND X < 100000 THEN
EXIT DO
ELSE
PRINT X; "out of range"
END IF
LOOP
IF X < 10 THEN
Y = 1
ELSEIF X < 100 THEN
Y = 2
ELSEIF X < 1000 THEN
Y = 3
ELSEIF X < 10000 THEN
Y = 4
ELSE
Y = 5
END IF
PRINT "The number has"; Y; "digits"
$INCLUDE Metacommand
────────────────────────────────────────────────────────────────────────────
Action
Instructs the compiler to include statements from another file.
Syntax 1
REM $INCLUDE: 'filespec'
Syntax 2
' $INCLUDE: 'filespec'
Remarks
The argument filespec is the name of a BASIC program file, which can
include a path. Use single quotation marks around filespec. The metacommand
$INCLUDE instructs the compiler to:
■ 1. Temporarily switch from processing one file.
■ 2. Read program statements from the BASIC file named in filespec.
■ 3. Return to processing the original file when the end of the included
file is reached.
Because compilation begins with the line immediately following the line in
which $INCLUDE occurred, $INCLUDE should be the last statement on the
line. For example:
DEFINT I-N ' $INCLUDE: 'COMMON.BAS'
When you are running a program from the QBX environment, included files must
not contain SUB or FUNCTION statements. When you are compiling a program
from the BC command line, included files can contain SUB or FUNCTION
statements. Included files created with BASICA must be saved with the , A
option. Included files created with QBX must be in a text (not binary)
format.
Example
See the DateSerial# function programming example, which uses the $INCLUDE
metacommand. The DateSerial# entry is in Part 2, "Add-On-Library
Reference."
INKEY$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a character from the keyboard or some other standard input device.
Syntax
INKEY$
Remarks
The INKEY$ function returns a 1- or 2-byte string that contains a character
read from the standard input device, which usually is the keyboard. A null
string is returned if there is no character to return. A one-character
string contains the actual character read from the standard input device,
while a two-character string indicates an extended code, the first character
of which is hexadecimal 00. For a complete list of these codes, see Appendix
A, "Keyboard Scan Codes and ASCII Character Codes."
The character returned by the INKEY$ function is never displayed on the
screen; instead, all characters are passed through to the program except for
these key combinations:
╓┌─────────────┌──────────────────────────────┌──────────────────────────────╖
Character Running under QBX Stand-alone .EXE file
────────────────────────────────────────────────────────────────────────────
Ctrl+Break Halts program execution. Halts program execution if
compiled with the /D option;
otherwise, passed through to
program.,
Ctrl+NumLock Causes program execution to Same as running under QBX if
pause until a key is pressed; compiled with the /D option;
Character Running under QBX Stand-alone .EXE file
────────────────────────────────────────────────────────────────────────────
pause until a key is pressed; compiled with the /D option;
then the next key pressed is otherwise, it is ignored (the
passed through to the program. program does not pause and no
keystroke is passed).
Shift+PrtSc Prints the screen contents. Prints the screen contents.
Ctrl+Alt+Del Reboots the system. Reboots the system.
If you have assigned a string to a function key using the KEY statement and
you press that function key when INKEY$ is waiting for a keystroke, INKEY$
passes the string to the program. Enabled keystroke trapping takes
precedence over the INKEY$ function.
When you use INKEY$ with ISAM programs, BASIC performs implicit CHECKPOINT
operations to minimize data loss in the event of a power failure. The
CHECKPOINT is performed if INKEY$ fails to successfully retrieve a
character after 65,535 calls, and 20 seconds has expired. A CHECKPOINT
writes open database buffers to disk.
Example
The following example shows a common use of INKEY$. The program pauses
until the user presses a key:
PRINT "Press any key to continue..."
DO
LOOP WHILE INKEY$=""
INP Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the byte read from a hardware I/O port.
Syntax
INP( port)
Remarks
The INP function complements the OUT statement, which sends a byte to a
hardware I/O port.
The argument port identifies the hardware I/O port from which to read the
byte. It must be a numeric expression with an integer value between 0 and
65,535, inclusive.
The INP function and the OUT statement give a BASIC program direct control
over the system hardware through the I/O ports. INP and OUT must be used
carefully because they directly manipulate the system hardware.
Note
The INP function is not available in OS/2 protected mode.
See Also
OUT, WAIT
Example
See the OUT statement programming example, which uses the INP function.
INPUT$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string of characters read from the specified file.
Syntax
INPUT$( n , # filenumber% )
Remarks
The INPUT$ statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
n The number of characters (bytes)
to read from the file.
filenumber% The number that was used in the
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number that was used in the
OPEN statement to open the file.
If the file is opened for random access, the argument n must be less than
or equal to the record length set by the LEN clause in the OPEN statement
(or less than or equal to 128 if the record length is not set). If the given
file is opened for binary or sequential access, n must be less than or
equal to 32,767.
If filenumber% is omitted, the characters are read from the standard input
device. (If input has not been redirected, the keyboard is the standard
input device.)
You can use the DOS redirection symbols (<, >, or >>) or the pipe symbol ( |
) to redefine the standard input or standard output for an executable file
created with BASIC. (See your operating-system manual for a complete
discussion of redirection and pipes.)
Unlike the INPUT # statement, INPUT$ returns all characters it reads.
Example
The following example uses I NPUT$ to read one character at a time from a
file. The input character is converted to standard printable ASCII, if
necessary, and displayed on the screen.
' ASCII codes for tab and line feed.
DEFINT A-Z
CONST HTAB = 9, LFEED = 10
CLS ' Clear screen.
INPUT "Display which file"; Filename$
OPEN Filename$ FOR INPUT AS #1
DO WHILE NOT EOF(1)
' Input a single character from the file.
S$ = INPUT$(1, #1)
' Convert the character to an integer and turn off the high bit
' so WordStar files can be displayed.
C = ASC(S$) AND &H7F
' Is it a printable character?
IF (C >= 32 AND C <= 126) OR C = HTAB OR C = LFEED THEN PRINT CHR$(C);
LOOP
END
INPUT Statement
────────────────────────────────────────────────────────────────────────────
Action
Allows input from the keyboard during program execution.
Syntax
INPUT ; " promptstring"{;|,} variablelist
Remarks
The following list describes the parts of the INPUT statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
; Determines screen location of the
Part Description
────────────────────────────────────────────────────────────────────────────
; Determines screen location of the
text cursor after the program user
enters the last character of input.
A semicolon immediately after
INPUT keeps the cursor at the next
character position. Otherwise, the
cursor skips to the next line.
promptstring A literal string that will be
displayed on the screen before the
program user enters data items
into the data input field.
; Prints a question mark at the end
of promptstring.
, Prints promptstring without a
question mark.
Part Description
────────────────────────────────────────────────────────────────────────────
variablelist An ordered list of variables that
will hold the data items as they
are entered.
The INPUT statement causes a running program to pause and wait for the user
to enter data from the keyboard.
The number and type of data items required from the user is determined by
the structure of variablelist. The variables in variablelist can be made
up of one or more variable names, each separated from the next by a comma.
Each name may refer to:
■ A simple numeric variable.
■ A simple string variable.
■ A numeric or string array element.
■ A record element.
The number of entered data items must be the same as the number of variables
in the list. The type of each entered data item must agree with the type of
the variable. If either of these rules is violated, the program will display
the prompt Redo from start and no assignment of input values will be made.
The INPUT statement determines the number of entered data items in a list
as follows: The first character encountered after a comma that is not a
space, carriage return, or line feed is assumed to be the start of a new
item. If this first character is a quotation mark ("), the item is typed as
string data and will consist of all characters between the first quotation
mark and the second. Not all strings have to start with a quotation mark,
however. If the first character of the string is not a quotation mark, it
terminates on a comma, carriage return, or line feed.
Input stored in a record must be entered as single elements. For example:
TYPE Demograph
FullName AS STRING * 25
Age AS INTEGER
END TYPE
DIM Person AS Demograph
INPUT "Enter name and age: "; Person.FullName, Person.Age
You may want to instruct the user on how it is possible to edit a line of
input before pressing the Enter key to submit the line to the program. The
following list describes the key combinations that allow you to move the
cursor, delete text, and insert text on the input line:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Keystrokes Edit function
────────────────────────────────────────────────────────────────────────────
Ctrl+M or Enter Store input line.
Ctrl+H or Backspace Delete the character to the left
of the cursor, unless the cursor
is at the beginning of the input,
in which case it deletes the
character at the cursor.
Ctrl+\ or Right Arrow Move cursor one character to the
right.
Ctrl+] or Left Arrow Move cursor one character to the
left..
Ctrl+F or Ctrl+Right Arrow Move cursor one word to the right.
Ctrl+B or Ctrl+Left Arrow Move cursor one word to the left.
Ctrl+K or Home Move cursor to beginning of input
Keystrokes Edit function
────────────────────────────────────────────────────────────────────────────
Ctrl+K or Home Move cursor to beginning of input
line.
Ctrl+N or End Move cursor to end of input line.
Ctrl+R or Ins Toggle insert mode on and off.
Ctrl+I or Tab Tab right and insert (insert mode
on), or tab right and overwrite
(insert mode off).
Del Delete the character at the cursor.
Ctrl+E or Ctrl+End Delete to the end of the line.
Ctrl+U or Esc Delete entire line, regardless of
cursor position.
Ctrl+T Toggle function key label display
Keystrokes Edit function
────────────────────────────────────────────────────────────────────────────
Ctrl+T Toggle function key label display
on and off at bottom of screen.
Ctrl+C or Ctrl+Break Terminate input (exit compiled
program).
When you use INPUT with ISAM programs, BASIC performs a CHECKPOINT
operation every 20 seconds during an INPUT polling loop. A CHECKPOINT
writes open database buffers to disk.
If the user can be limited to using the Enter and Backspace keys for
editing, you can reduce the size of the .EXE file by linking with the stub
file NOEDIT.OBJ.
If the user will be entering decimal integers only, you can save between
1.6K and 11K in the size of a non-stand-alone .EXE file by linking with the
stub file NOFLTIN.OBJ. This places the following restrictions on user input:
■ Decimal numbers only (no leading &H, &O, or & base specifiers).
■ No trailing type specifiers ( %, &, !, #, @, or $).
■ No decimal point, E, or D (for example 1.E2 cannot be used instead of
the integer 100).
See Also
INKEY$
Example
This example calculates the area of a circle from its radius. The program
uses the INPUT statement to allow the user to supply values of the
variable.
CLS
PI = 3.141593: R = -1
DO WHILE R
PRINT "Enter radius (or 0 to quit)."
INPUT ; "If radius = ", R
IF R > 0 THEN
A = PI * R ^ 2
PRINT ", the area of the circle ="; A
END IF
PRINT
LOOP
Output
Enter radius (or 0 to quit).
If radius = 3, the area of the circle = 28.27434
Enter radius (or 0 to quit).
If radius = 4, the area of the circle = 50.26549
Enter radius (or 0 to quit).
If radius = 0
INPUT # Statement
────────────────────────────────────────────────────────────────────────────
Action
Reads data items from a sequential device or file and assigns them to
variables.
Syntax
INPUT # filenumber%, variablelist
Remarks
The argument filenumber% is the number used in the OPEN statement to open
the file. The argument variablelist contains the names of the variables
that are assigned values read from the file.
The data items in the file should appear just as they would if you were
entering data in response to an INPUT statement. Separate numbers with a
space, carriage return, line feed, or comma. Separate strings with a
carriage return or line feed (leading spaces are ignored). The end-of-file
character will end either a numeric or string entry.
See Also
INPUT$ Function, INPUT Statement
Example
This example reads a series of test scores from a sequential file. It then
calculates and displays the average score.
DEFINT A-Z
DIM Total AS LONG
' Create the required input file.
OPEN "class.dat" FOR OUTPUT AS #1
PRINT #1, 98, 84, 63, 89, 100
CLOSE #1
' Open the file just created.
OPEN "class.dat" FOR INPUT AS #1
DO WHILE NOT EOF(1)'Do until end-of-file is reached.
Count = Count + 1
INPUT #1, Score'Get a score from file #1.
Total = Total + Score
PRINT Count; Score
LOOP
PRINT "Total students:"; Count; " Average score:"; Total / Count
Output
1 98
2 84
3 63
4 89
5 100
Total students: 5 Average score: 86.8
INSERT Statement
────────────────────────────────────────────────────────────────────────────
Action
Adds a new record to an ISAM table.
Syntax
INSERT # filenumber%, recordvariable
Remarks
The INSERT statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the table.
recordvariable The record you wish to insert. It
is a variable of the user-defined
type corresponding to the table.
INSERT places the contents of recordvariable in the table, and updates the
table's indexes to include the new record. Insert has no effect on the
current position.
BASIC removes trailing spaces from strings used in an insert.
See Also
DELETE, OPEN (File I/O), RETRIEVE
Example
See the programming example for the SEEKGT, SEEKGE, and SEEKEQ
statements, which uses the INSERT statement.
INSTR Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the character position of the first occurrence of a string in
another string.
Syntax
INSTR( start%, stringexpression1$, stringexpression2$)
Remarks
The INSTR function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
start% An optional offset that sets the
position for starting the search;
start% must be between 1 and
32,767, inclusive. If start% is
Argument Description
────────────────────────────────────────────────────────────────────────────
32,767, inclusive. If start% is
not given, the INSTR function
begins the search at the first
character of stringexpression1$.
stringexpression1$ The string being searched.
stringexpression2$ The string to look for.
The arguments stringexpression1$ and stringexpression2$ can be string
variables, string expressions, or string literals. The value returned by
INSTR depends on these conditions:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
Condition Value returned
Condition Value returned
────────────────────────────────────────────────────────────────────────────
stringexpression2$ found in The position at which the match is
stringexpression1$ found
start% greater than length of 0
stringexpression1$
stringexpression1$ is a null string 0
stringexpression2$ cannot be found 0
stringexpression2$ is a null string start% (if given); otherwise, 1
Use the LEN function to find the length of stringexpression1$.
See Also
LEN
Example
The following example uses INSTR and UCASE$ to determine a person's gender
from a courtesy title (Mr., Mrs., or Ms.):
CLS ' Clear screen.
DO
INPUT "Enter name with courtesy title (Mr., Mrs., or Ms.): ", Nm$
LOOP UNTIL LEN(Nm$) >= 3
Nm$ = UCASE$(Nm$) ' Convert lowercase letters to uppercase.
' Look for MS, MRS, or MR to set Sex$.
IF INSTR(Nm$, "MS") > 0 OR INSTR(Nm$, "MRS") > 0 THEN
Sex$ = "F"
ELSEIF INSTR(Nm$, "MR") > 0 THEN
Sex$ = "M"
ELSE
' Can't determine gender, query user.
DO
INPUT "Enter sex (M/F): ", Sex$
Sex$ = UCASE$(Sex$)
LOOP WHILE Sex$ <> "M" AND Sex$ <> "F"
END IF
PRINT "Sex is "; Sex$
Output
Enter name: Ms. Elspeth Brandtkeep
Sex is F
Enter name: Dr. Richard Science
Enter sex (M/F): M
Sex is M
INT Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the largest integer less than or equal to a numeric expression.
Syntax
INT( numeric-expression)
Remarks
The INT function removes the fractional part of its argument.
See Also
CINT, FIX
Example
The following example compares output from INT, CINT, and FIX, the three
functions that convert numeric data to integers:
CLS ' Clear screen.
PRINT " N","INT(N)","CINT(N)","FIX(N)" : PRINT
FOR I% = 1 TO 6
READ N
PRINT N, INT(N), CINT(N), FIX(N)
NEXT
DATA 99.3, 99.5, 99.7, -99.3, -99.5, -99.7
Output
N INT(N) CINT(N) FIX(N)
99.3 99 99 99
99.5 99 100 99
99.7 99 100 99
-99.3 -100 -99 -99
-99.5 -100 -100 -99
-99.7 -100 -100 -99
Interrupt, InterruptX Routines
────────────────────────────────────────────────────────────────────────────
Action
Allow BASIC programs to perform DOS system calls.
Syntax
CALL Interrupt ( interruptnum%, inregs, outregs)
CALL InterruptX ( interruptnum%, inregs, outregs)
Remarks
The Interrupt routines use the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
interruptnum% A DOS interrupt number that is an
integer between 0 and 255.
inregs The register values before the
interrupt is performed; inregs is
declared as type RegType or
RegTypeX. The user-defined types
RegType and RegTypeX are described
below.
outregs The register values after the
interrupt is performed; outregs
Argument Description
────────────────────────────────────────────────────────────────────────────
interrupt is performed; outregs
is declared as type RegType or
RegTypeX. The user-defined types
RegType and RegTypeX are described
below.
The following statement defines RegTypeX:
TYPE RegTypeX
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
DS AS INTEGER
ES AS INTEGER
END TYPE
The following statement defines RegType (the DS and ES registers are not
included):
TYPE RegType
AX AS INTEGER
BX AS INTEGER
CX AS INTEGER
DX AS INTEGER
BP AS INTEGER
SI AS INTEGER
DI AS INTEGER
FLAGS AS INTEGER
END TYPE
Each element of the type corresponds to a CPU element.
InterruptX uses the values in the DS and ES registers. To use the current
values of these registers, set the record elements to -1.
The Interrupt and InterruptX routines replace the INT86 and INT86X
routines used in earlier versions of BASIC. They provide a more convenient
way for BASIC programs to use DOS interrupts and services.
To use Interrupt or InterruptX in the QBX environment, use the QBX.QLB
Quick library. To use Interrupt or InterruptX outside of the QBX
environment, link your program with the QBX.LIB file.
The QBX.BI header file contains the necessary declarations for Interrupt
and InterruptX .
Note
The Interrupt and InterruptX routines are not available in OS/2 protected
mode. For OS/2 protected mode, replace Interrupt with the equivalent OS/2
function invocations. For more information about doing OS/2 calls from
BASIC, see Chapter 14, "OS/2 Programming" in the Programmer's Guide.
Example
The following example uses Interrupt to determine the current drive and the
amount of free space remaining on the drive.
To use Interrupt, you must load the Quick library QBX.QLB using the /L
option when you begin QBX. You also must include the QBX.BI header file as
shown below:
' $INCLUDE: 'QBX.BI'
DIM regs AS RegType' Define registers.
' Get current drive info.
regs.ax = &H1900
CALL Interrupt(&H21, regs, regs)
' Convert drive info to readable form.
Drive$ = CHR$((regs.ax AND &HFF) + 65) + ":"
' Get disk's free space.
regs.ax = &H3600
regs.dx = ASC(UCASE$(Drive$)) - 64
CALL Interrupt(&H21, regs, regs)
' Decipher the results.
SectorsInCluster = regs.ax
BytesInSector = regs.cx
IF regs.dx >= 0 THEN
ClustersInDrive = regs.dx
ELSE
ClustersInDrive = regs.dx + 65536
END IF
IF regs.bx >= 0 THEN
ClustersAvailable = regs.bx
ELSE
ClustersAvailable = regx.bx + 65536
END IF
Freespace = ClustersAvailable * SectorsInCluster * BytesInSector
' Report results.
CLS
PRINT "Drive "; Drive$; " has a total of";
PRINT USING "###,###,###"; Freespace;
PRINT " bytes remaining free."
IOCTL$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns current status information from a device driver.
Syntax
IOCTL$(# filenumber%)
Remarks
The argument filenumber% is the BASIC file number used to open the device.
The IOCTL$ function is most frequently used to test whether an IOCTL
statement succeeded or failed, or to obtain current status information.
You can use IOCTL$ to ask a communications device to return the current
baud rate, information on the last error, logical line width, and so on. The
exact information returned depends on the specific device driver. See the
device driver documentation to find out what status information the device
driver can send.
The IOCTL$ function works only if all of the following conditions are met:
■ The device driver is installed.
■ The device driver states that it processes IOCTL strings. See
the documentation for the driver.
■ BASIC performed an OPEN operation on a file on that device, and
the file is still open.
Most standard DOS device drivers do not process IOCTL strings, and you must
determine whether the specific driver accepts the command. If the driver
does not process IOCTL strings, BASIC generates the error message Illegal
function call.
Note
BASIC devices (LPT n, COM n, SCRN, CONS, PIPE) and DOS block devices (A
through Z) do not support IOCTL.
The IOCTL statement is not available in OS/2 protected mode. However, you
can achieve the same effect by directly invoking the DosDevIOCtl OS/2
functions.
See Also
IOCTL Statement
Example
The following example shows how to communicate with a device driver using a
hypothetical device driver named ENGINE. The IOCTL statement sets the data
mode in the driver and the IOCTL$ function tests the data mode.
OPEN "\DEV\ENGINE" FOR OUTPUT AS #1
IOCTL #1, "RAW"' Tells the device that the data is raw.
' If the character driver "ENGINE" responds "false" from the raw data
' mode in the IOCTL statement, then the file is closed.
IF IOCTL$(1) = "0" THEN CLOSE 1
IOCTL Statement
────────────────────────────────────────────────────────────────────────────
Action
Transmits a control data string to a device driver.
Syntax
IOCTL # filenumber%, string$
Remarks
The IOCTL statement uses the following arguments:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The BASIC file number used to open the device.
string$ The command sent to the device.
Commands are specific to the device driver. See the documentation for the
device driver for a description of the valid IOCTL commands. An IOCTL
control data string can be up to 32,767 bytes long.
The IOCTL statement works only if all of the following conditions are met:
■ The device driver is installed.
■ The device driver states that it processes IOCTL strings. See
the documentation for the driver. You also can test for IOCTL
support through DOS function &H44 by using interrupt &H21 and
the INTERRUPT routine. For more information about interrupt
&H21, function &H44, see see the Microsoft MS-DOS Programmer's
Reference, or books such as Advanced MS-DOS or The Peter
Norton Guide to the IBM PC.
■ BASIC performed an OPEN operation on a file on that device, and
the file is still open.
Most standard DOS device drivers do not process IOCTL strings, and you must
determine whether the specific driver accepts the command. If the driver
does not process IOCTL strings, BASIC generates the error message Illegal
function call.
Note
BASIC devices (LPT n, COM n, SCRN, CONS, PIPE) and DOS block devices (A
through Z) do not support IOCTL.
The IOCTL statement is not available in OS/2 protected mode. However, you
can achieve the same effect by directly invoking the DosDevIOCtl OS/2
function.
See Also
IOCTL$ Function
Example
See the IOCTL$ function programming example, which shows how the IOCTL
statement and the IOCTL$ function are used with a device driver.
KEY Statements (Assignment)
────────────────────────────────────────────────────────────────────────────
Action
Assign soft-key string values to function keys, then display the values and
enable or disable the function-key display line.
Syntax
KEY n%, stringexpression$
KEY ON
KEY OFF
KEY LIST
Remarks
The argument n% is a number representing the function key. The values for
n% are 1 to 10 for the function keys, and 30 and 31 for function keys F11
and F12 on 101-key keyboards. The stringexpression$ is a string of up to 15
characters that is returned when the function key is pressed. If the
stringexpression$ is longer than 15 characters, the extra characters are
ignored.
The KEY statements allows you to designate special "soft-key" functions --
strings that are returned when function keys are pressed.
Assigning a null string to a soft key disables the function key as a soft
key.
If the function key number is not in the correct range, BASIC generates the
error message Illegal function call, and the previous key string expression
is retained.
You can display soft keys with the KEY ON, KEY OFF, and KEY LIST
statements:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Statement Action
────────────────────────────────────────────────────────────────────────────
KEY ON Displays the first six characters
of the soft-key string values on
the bottom line of the screen.
KEY OFF Erases the soft-key display from
the bottom line, making that line
available for program use. It does
not disable the function keys.
KEY LIST Displays all soft-key values on
the screen, with all 15 characters
Statement Action
────────────────────────────────────────────────────────────────────────────
the screen, with all 15 characters
of each key displayed.
If a soft key is pressed, the effect is the same as if the user typed the
string associated with the soft key. INPUT$, INPUT, and INKEY$ all can be
used to read the string produced by pressing the soft key.
See Also
ON event; Appendix A, "Keyboard Scan Codes and ASCII Character Codes"
Examples
The following examples show how to assign values to soft keys. First is an
example of assigning and disabling a soft key. KEY LIST displays key values
after KEY 4 has been assigned and again after it has been disabled.
KEY 4, "MENU" + CHR$(13) ' Assigns to soft key 4 the string
KEY LIST' "MENU" followed by a carriage return.
KEY 4, "" ' Disables soft key 4.
KEY LIST
This is an example of using KEY statements to set up one-key equivalents of
menu selections. For example, pressing the F1 key is the same as entering
the string "Add":
CLS ' Clear screen.
DIM KeyText$(3)
DATA Add, Delete, Quit
' Assign soft-key strings to F1 to F3.
FOR I = 1 TO 3
READ KeyText$(I)
KEY I, KeyText$(I) + CHR$(13) ' String followed by Enter.
NEXT I
' Print menu.
PRINT " Main Menu" : PRINT
PRINT " Add to list (F1)"
PRINT " Delete from list (F2)"
PRINT " Quit (F3)" : PRINT
' Get input and respond.
DO
LOCATE 7,1 : PRINT SPACE$(50);
LOCATE 7,1 : INPUT " Enter your choice:", R$
SELECT CASE R$
CASE "Add", "Delete"
LOCATE 10,1 : PRINT SPACE$(15);
LOCATE 10,1 : PRINT R$;
CASE "Quit"
EXIT DO
CASE ELSE
LOCATE 10,1 : PRINT "Enter first word or press key."
END SELECT
LOOP
KEY Statements (Event Trapping)
────────────────────────────────────────────────────────────────────────────
Action
Enable, disable, or suspend trapping of specified keys.
Syntax
KEY( n%) ON
KEY( n%) OFF
KEY( n%) STOP
Remarks
The argument n% is an integer expression that is the number of a function
key, a direction key, or a user-defined key. The values of n% are as
follows:
╓┌──────────────────┌────────────────────────────────────────────────────────╖
n% Value
────────────────────────────────────────────────────────────────────────────
0 All keys listed in this table
1-10 F1-F10
11 Up Arrow key
12 Left Arrow key
13 Right Arrow key
14\~ Down Arrow key
15-25 User-defined keys
30-31 F11-F12 on 101-key keyboards
The KEY( n%) ON statement enables trapping of function keys, direction
keys, and user-defined keys. If key n% is pressed after a KEY( n%) ON
statement, the routine specified in the ON KEY statement is executed.
KEY( n% OFF disables trapping of key n%. No key trapping takes place
until another KEY( n%) ON statement is executed. Events occurring while
trapping is off are ignored.
KEY( n%) STOP suspends trapping of key n%. No trapping takes place until
a KEY( n%) ON statement is executed. Events occurring while trapping is
suspended are remembered and processed when the next KEY( n%) ON statement
is executed. However, remembered events are lost if KEY( n%) OFF is
executed.
When a key-event trap occurs (that is, the GOSUB is performed), an
automatic KEY( n%) STOP is executed so that recursive traps cannot take
place. The RETURN operation from the trapping routine automatically
performs a KEY( n%) ON statement unless an explicit KEY( n%) OFF was
performed inside the subroutine.
For more information on event trapping, see Chapter 9, "Event Handling" in
the Programmer's Guide.
In addition to providing the preassigned key numbers 1-14 (plus 30 and 31 on
the 101-key keyboard), BASIC enables you to create user-defined keys. You do
this by assigning the numbers 15-25 to any of the remaining keys on the
keyboard. Use the KEY statement (assignment) to create user-defined keys.
You also can set a trap for "shifted" keys. A key is shifted when you press
it simultaneously with one or more of the special keys Shift, Ctrl, or Alt
after pressing NumLock or Caps Lock. Use the KEY statement (assignment) to
define shifted keys before you trap them. The syntax for KEY (assignment)
is:
KEY n%, CHR$ ( keyboardflag) + CHR$ ( scancode)
The argument n% is in the range 15-25 to indicate a user-defined key. The
argument keyboardflag can be any combination of the following values:
╓┌─────────────────────┌─────────────────────────────────────────────────────╖
Value Key
────────────────────────────────────────────────────────────────────────────
Value Key
────────────────────────────────────────────────────────────────────────────
0 No keyboard flag
1, 2, or 3 Either Shift key
4 Ctrl
8 Alt
32 NumLock
64 Caps Lock
128 101-key keyboard extended keys
You can add the values together to test for multiple shift states. A
keyboardflag value of 12 would test for both Ctrl and Alt being pressed, for
example.
To define Shift, Ctrl, Alt, NumLock, or Caps Lock as a user-defined key (by
itself, not in combination with another key), use a keyboard flag of 0. For
example, to define Alt as a user-defined key, use the following statement:
KEY CHR$(0) + CHR$(56)
To define Alt + Alt as a user-defined key (the second Alt will be trapped
when it is pressed only if the first Alt key is already being pressed), use
the following statement:
KEY CHR$(8) + CHR$(56)
Because key trapping assumes the left and right Shift keys are the same, you
can use 1, 2, or 3 to indicate a Shift key.
The argument scancode is a number that identifies one of the 83 keys to
trap, as shown in the following table:
Keyboard Scan Codes
╓┌──────────┌─────┌────────────┌─────┌────────────┌──────────────────────────╖
Key Code Key Code Key Code
────────────────────────────────────────────────────────────────────────────
Esc 1 Ctrl 29 Spacebar 57
! or 1 2 A 30 Caps Lock 58
Key Code Key Code Key Code
────────────────────────────────────────────────────────────────────────────
! or 1 2 A 30 Caps Lock 58
@ or 2 3 S 31 F1 59
# or 3 4 D 32 F2 60
$ or 4 5 F 33 F3 61
% or 5 6 G 34 F4 62
^ or 6 7 H 35 F5 63
& or 7 8 J 36 F6 64
* or 8 9 K 37 F7 65
( or 9 10 L 38 F8 66
) or 0 11 : or ; 39 F9 67
_ or - 12 " or ' 40 F10 68
+ or = 13 ~ or ` 41 NumLock 69
Backspace 14 Left Shift 42 Scroll Lock 70
Tab 15 | or \ 43 Home or 7 71
Q 16 Z 44 Up or 8 72
W 17 X 45 PgUp or 9 73
E 18 C 46 Gray - 74
R 19 V 47 Left or 4 75
T 20 B 48 Center or 5 76
Key Code Key Code Key Code
────────────────────────────────────────────────────────────────────────────
T 20 B 48 Center or 5 76
Y 21 N 49 Right or 6 77
U 22 M 50 Gray + 78
I 23 < or , 51 End or 1 79
O 24 > or . 52 Down or 2 80
P 25 ? or / 53 PgDn or 3 81
{ or [ 26 Right Shift 54 Ins or 0 82
} or ] 27 PrtSc or * 55 Del or . 83
Enter 28 Alt 56
Note
The scan codes in the preceding table are equivalent to the first column of
the scan code table in Appendix A, "Keyboard Scan Codes and ASCII Character
Codes." The codes in the other columns of the table in the appendix should
not be used for key trapping.
See Also
KEY (Assignment), ON event
Example
The following example traps the Down Arrow key and Ctrl+s (Control key and
lowercase "s"). To trap the combination of the Ctrl key and uppercase "s",
trap Ctrl+Shift and
I = 0
CLS' Clear screen.
PRINT "Press Down Arrow key to end."
KEY 15, CHR$(&H4) + CHR$(&H1F)
KEY(15) ON ' Trap Ctrl+s.
KEY(14) ON ' Trap Down Arrow key.
ON KEY(15) GOSUB Keytrap
ON KEY(14) GOSUB Endprog
Idle: GOTO Idle' Endless loop.
Keytrap: ' Counts the number of times Ctrl+s pressed.
I = I + 1
RETURN
Endprog:
PRINT "CTRL+s trapped"; I; "times"
END
RETURN
KILL Statement
────────────────────────────────────────────────────────────────────────────
Action
Deletes files from a disk.
Syntax
KILL filespec$
Remarks
The KILL statement is similar to the DOS ERASE or DEL command.
KILL is used for all types of disk files: program files, random-access data
files, and sequential data files. The filespec$ is a string expression that
can contain a path and question marks (?) or asterisks (*) used as DOS
wildcards. A question mark matches any single character in the filename or
extension. An asterisk matches one or more characters.
KILL deletes files only. To delete directories, use the DOS RMDIR command
or BASIC RMDIR statement. Using KILL to delete a file that is currently
open produces an error message that reads File already open.
Warning
Be extremely careful when using wildcards with KILL. You can delete files
unintentionally with the wildcard characters.
See Also
FILES, RMDIR
Examples
The first example uses wildcard characters with KILL. It will not work
properly unless the specified files are found.
KILL "DATA1?.DAT" ' Kills any file with a six-character
' base name starting with DATA1 and
' also with the extension .DAT.
KILL "DATA1.*"' Kills any file with the base name
' DATA1 and any extension.
KILL "\GREG\*.DAT"' Kills any file with the extension
' .DAT in a subdirectory called GREG.
The following example deletes the file specified on the command line:
DEFINT A-Z
CLS ' Clear screen.
ON ERROR GOTO Errorhandle' Set up error handling.
FileName$ = COMMAND$ ' Get filename.
KILL FileName$
PRINT FileName$ " deleted"
END
Errorhandle:
Number = ERR
IF Number = 53 THEN
PRINT "Couldn't delete " FileName$ ;
PRINT "; file does not exist in current directory"
ELSE
PRINT "Unrecoverable error:";Number
ON ERROR GOTO 0 ' ON ERROR GOTO zero aborts program.
END IF
RESUME NEXT
LBOUND Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the lower bound (smallest available subscript) for the indicated
dimension of an array.
Syntax
LBOUND( array , dimension% )
Remarks
The LBOUND function is used with the UBOUND function to determine the size
of an array. LBOUND takes the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
array The name of the array variable to
be tested.
Argument Description
────────────────────────────────────────────────────────────────────────────
dimension% An integer ranging from 1 to the
number of dimensions in array;
indicates which dimension's lower
bound is returned. Use 1 for the
first dimension, 2 for the second
dimension, and so on. This
argument is optional for
one-dimensional arrays.
LBOUND returns the values listed below for an array with the following
dimensions:
DIM A(1 TO 100, 0 TO 3, -3 TO 4)
╓┌───────────────────────────┌───────────────────────────────────────────────╖
Invocation Value returned
────────────────────────────────────────────────────────────────────────────
LBOUND(A,1) 1
LBOUND(A,2) 0
LBOUND(A,3) -3
The default lower bound for any dimension is either 0 or 1, depending on the
setting of the OPTION BASE statement. If OPTION BASE is 0, the default
lower bound is 0, and if OPTION BASE is 1, the default lower bound is 1.
Arrays dimensioned using the TO clause in the DIM statement can have any
integer value as a lower bound.
You can use the shortened syntax LBOUND( array) for one-dimensional arrays,
because the default value for dimension% is 1. Use the UBOUND function to
find the upper limit of an array dimension.
See Also
DIM, OPTION BASE, UBOUND
Example
See the UBOUND function programming example, which uses the LBOUND
function.
LCASE$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string with all letters in lowercase.
Syntax
LCASE$ ( stringexpression$)
Remarks
The LCASE$ function takes a string variable, string constant, or string
expression as its single argument. LCASE$ works with both variable- and
fixed-length strings.
LCASE$ and UCASE$ are helpful in making string comparisons that are not
case sensitive.
See Also
UCASE$
Example
The following example converts uppercase characters in a string to
lowercase:
CLS ' Clear screen.
READ Word$
PRINT LCASE$(Word$);
DATA "THIS IS THE STRING in lower case."
Outputthis is the string in lower case.
LEFT$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string consisting of the leftmost n characters of a string.
Syntax
LEFT$( stringexpression$, n%)
Remarks
The argument stringexpression$ can be any string variable, string constant,
or string expression.
The argument n% is a numeric expression in the range 0-32,767 indicating
how many characters are to be returned.
If n% is 0, the null string (length zero) is returned.
If n% is greater than or equal to the number of characters in
stringexpression$, the entire string is returned. To find the number of
characters in stringexpression$, use LEN( stringexpression$) .
See Also
MID$ Function, RIGHT$ Function
Example
The following example prints the leftmost five characters of A$:
CLS ' Clear screen.
A$="BASIC LANGUAGE"
B$=LEFT$(A$, 5)
PRINT B$
Output
BASIC
LEN Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the number of characters in a string or the number of bytes required
by a variable.
Syntax 1
LEN( stringexpression$)
Syntax 2
LEN( variable)
Remarks
In the first form, LEN returns the number of characters in the argument
stringexpression$. The second syntax returns the number of bytes required by
a BASIC variable. This syntax is particularly useful for determining the
correct record size of a random-access file.
When you pass a string length as an argument to a procedure that may change
the value of the argument, be sure to pass it by value instead of by
reference, which is the BASIC default. Do this by placing parentheses around
LEN(N$), e.g.,(LEN(N%)). Alternatively, you can use a temporary variable,
e.g. N% = LEN(N$), and pass the temporary variable in the standard way.
Failure to use these techniques will corrupt string space if you change the
value of the passed argument.
Example
The following example prints the length of a string and the size in bytes of
several types of variables:
CLS ' Clear screen.
TYPE EmpRec
EmpName AS STRING * 20
EmpNum AS INTEGER
END TYPE
DIM A AS INTEGER, B AS LONG, C AS SINGLE, D AS DOUBLE
DIM E AS EmpRec
PRINT "A string:" LEN("A string.")
PRINT "Integer:" LEN(A)
PRINT "Long:" LEN(B)
PRINT "Single:" LEN(C)
PRINT "Double:" LEN(D)
PRINT "EmpRec:" LEN(E)
END
Output
A string: 9
Integer: 2
Long: 4
Single: 4
Double: 8
EmpRec: 22
Let Statement
────────────────────────────────────────────────────────────────────────────
Action
Assigns the value of an expression to a variable.
Syntax
LET variable= expression
Remarks
Notice that the keyword LET is optional. The equal sign in the statement is
enough to inform BASIC that the statement is an assignment statement.
The LET statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
variable A variable.
expression An expression that provides the
value to assign to the variable.
LET statements can be used with record variables only when both variables
are the same user-defined type. Use the LSET statement to assign record
variables of different user-defined types.
See Also
LSET
Examples
The first example below shows the use of the optional LET keyword:
LET D = 12
LET E = 12 - 2
LET F = 12 - 4
LET SUM = D + E + F
PRINT D E F SUM
The following program lines perform the same function, without using the
LET keyword:
D = 12
E = 12 - 2
F = 12 - 4
SUM = D + E + F
PRINT D E F SUM
Output
12 10 8 30
LINE Statement
────────────────────────────────────────────────────────────────────────────
Action
Draws a line or box on the screen.
Syntax
LINE STEP ( x1!, y1!) - STEP ( x2!, y2!) , color& , B F , style%
Remarks
The coordinates ( x1!, y1!) and ( x2!, y2!) specify the end points of the
line; note that the order in which these end points appear is unimportant,
since a line from (10,20) to (120,130) is the same as a line from (120,130)
to (10,20).
The STEP option makes the specified coordinates relative to the most-recent
point. For example, if the most-recent point referred to by the program were
(10,10), then the following statement would draw a line from (10,10) to the
point with an x coordinate equal to 10 + 10 and a y coordinate equal to 10 +
5, or (20,15):
LINE -STEP (10,5)
You may establish a new most-recent point by initializing the screen with
the CLS and SCREEN statements. Using the PSET, PRESET, CIRCLE, and
DRAW statements will also establish a new most-recent point.
Variations of the STEP argument are shown below. For the following
examples, assume that the last point plotted was (10,10):
╓┌─────────────────────────────────┌─────────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
LINE -(50,50) Draws from (10,10) to (50,50).
LINE -STEP(50,50) Draws from (10,10) to (60,60).
LINE (25,25)-STEP(50,50) Draws from (25,25) to (75,75).
LINE STEP(25,25)-STEP(50,50) Draws from (35,35) to (85,85).
LINE STEP(25,25)-(50,50) Draws from (35,35) to (50,50).
The argument color% is the number of the color in which the line is drawn.
(If the B or BF option is used, the box is drawn in this color.) For
information on valid colors, see the SCREEN statement.
The B option draws a box with the points ( x1!, y1!) and ( x2!, y2!)
specifying diagonally opposite corners.
The BF option draws a filled box. This option is similar to the B option; BF
also paints the interior of the box with the selected color.
The argument style% is a 16-bit integer mask used to put pixels on the
screen. Using style% is called "line styling." With line styling, LINE
reads the bits in style% from left to right. If a bit is 0, then no point
is plotted; if the bit is 1, a point is plotted. After plotting a point,
LINE selects the next bit position in style%.
Because a zero bit in style% does not change the point on the screen, you
may want to draw a background line before using styling so you can have a
known background. Style is used for normal lines and boxes, but has no
effect on filled boxes.
When coordinates specify a point that is not within the current viewport,
the line segment to that point is drawn to the border of the viewport.
For more information on the LINE statement, see Chapter 5, "Graphics" in
the Programmer's Guide.
See Also
CIRCLE, PSET, SCREEN Statement
Examples
The following example uses LINE statements to display a series of screens
with different line graphics. To run this program, your screen must be 320
pixels wide by 200 pixels high and support CGA screen mode.
SCREEN 1' Set up the screen mode.
LINE -(X2, Y2)' Draw a line (in the foreground color)
' from the most recent point to X2,Y2.
DO: LOOP WHILE INKEY$ = ""
CLS
LINE(0, 0)-(319, 199)' Draw a diagonal line across the screen.
DO: LOOP WHILE INKEY$ = ""
CLS
LINE(0, 100)-(319, 100)' Draw a horizontal line across the screen.
DO: LOOP WHILE INKEY$ = ""
CLS
LINE(10, 10)-(20, 20), 2 ' Draw a line in color 2.
DO: LOOP WHILE INKEY$ = ""
CLS
FOR X = 0 to 319' Draw an alternating pattern
LINE(X, 0)-(X, 199), X AND 1' (line on/line off) on mono-
NEXT' chrome display.
DO: LOOP WHILE INKEY$ = ""
CLS
LINE (0, 0)-(100, 100),, B' Draw a box in the foreground color
' (note that the color is not included).
DO: LOOP WHILE INKEY$ = ""
CLS
LINE STEP(0,0)-STEP(200,200),2,BF ' Draw a filled box in color
' 2 (coordinates are given as
' offsets with the STEP option).
DO: LOOP WHILE INKEY$ = ""
CLS
LINE(0,0)-(160,100),3,,&HFF00' Draw a dashed line from the
' upper-left corner to the
' center of the screen in color 3.
LINE INPUT Statement
────────────────────────────────────────────────────────────────────────────
Action
Enters an entire line (up to 255 characters) from the keyboard to a string
variable, without the use of delimiters.
Syntax
LINE INPUT ; " promptstring"; stringvariable
Remarks
The argument promptstring is a string constant. After promptstring is
displayed on the screen, entry of data items into the data input field is
accepted. A question mark is not printed unless it is part of promptstring.
All input from the end of promptstring to the carriage return is assigned
to stringvariable.
A semicolon immediately after the LINE INPUT keywords keeps the cursor at
the next character position after the user presses Enter. Omitting a
semicolon causes the cursor to skip to the next line.
LINE INPUT uses the same editing characters as INPUT.
See Also
INPUT$ Function, INPUT Statement
Example
See the DEF SEG statement programming example, which uses the LINE INPUT
statement.
LINE INPUT # Statement
────────────────────────────────────────────────────────────────────────────
Action
Reads an entire line from a sequential file into a string variable.
Syntax
LINE INPUT # filenumber%, stringvariable$
Remarks
The LINE INPUT # statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file.
stringvariable$ The variable the line is assigned
to.
Argument Description
────────────────────────────────────────────────────────────────────────────
The LINE INPUT # statement reads all characters in the sequential file up
to a carriage return. It then skips over the carriage-return-and-line-feed
sequence.
LINE INPUT # is especially useful if a text file is being read one line at
a time.
See Also
INPUT$ Function, INPUT Statement, INPUT # Statement, LINE INPUT
Example
The following example creates a data file consisting of customer records
that include LAST NAME, FIRST NAME, AGE, and SEX. After the file is
complete, the LINE INPUT # statement is used to read the individual
records so they can be displayed on the screen.
OPEN "LIST" FOR OUTPUT AS #1
PRINT "CUSTOMER INFORMATION:"
' Get customer information.
DO
PRINT
INPUT " LAST NAME: ", LName$
INPUT " FIRST NAME: ", FrName$
INPUT " AGE: ", Age$
INPUT " SEX: ", Sex$
Sex$ = UCASE$(Sex$)
WRITE #1, LName$, FrName$, Age$, Sex$
INPUT "Add another"; R$
LOOP WHILE UCASE$(R$) = "Y"
CLOSE #1
' Echo the file back.
OPEN "LIST" FOR INPUT AS #1
CLS
PRINT "Records in file:": PRINT
DO WHILE NOT EOF(1)
LINE INPUT #1, REC$ ' Read records from file.
PRINT REC$ ' Print the records on the screen.
LOOP
' Remove file from disk.
CLOSE #1
KILL "LIST"
Output
CUSTOMER INFORMATION:
LAST NAME: Saintsbury
FIRST NAME: Aloysius
AGE: 35
SEX: m
Add another? y
LAST NAME: Frangio
FIRST NAME: Louisa
AGE: 27
SEX: f
Add another? n
Records in file:
"Saintsbury","Aloysius","35","M"
"Frangio","Louisa","27","F"
LOC Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the current position within an open file.
Syntax
LOC( filenumber%)
Remarks
The argument filenumber% is the number of an open file or device. With
random-access files, the LOC function returns the number of the last record
read from, or written to, the file. With sequential files, LOC returns the
current byte position in the file, divided by 128. With binary mode files,
LOC returns the position of the last byte read or written.
For a communications device, LOC returns the number of characters in the
input queue waiting to be read. The value returned depends on whether the
device was opened in ASCII or binary mode. In ASCII mode, the low-level
routines stop queuing characters as soon as an end-of-file is received. The
end-of-file itself is not queued and cannot be read. If you attempt to read
the end-of-file, BASIC generates the error message Input past end of file.
In binary mode, the end-of-file character is ignored and the entire file can
be read.
For a PIPE device, LOC returns 1 if any data are available in the PIPE
queue.
Note
The LOC function cannot be used on ISAM tables, or the SCRN, KYBD, or LPT n
devices.
See Also
EOF, LOF, OPEN (File I/O)
Example
The following example stops the program if the current file position is
beyond 50. Note that this example is incomplete.
IF LOC(1) > 50 THEN STOP
LOCATE Statement
────────────────────────────────────────────────────────────────────────────
Action
Moves the cursor to the specified position on the screen.
Syntax
LOCATE row% , column% , cursor% , start% , stop%
Remarks
The LOCATE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
row% The number of a row on the screen;
row% is a numeric expression
returning an integer. If row% is
not specified, the row location of
the cursor does not change.
column% The number of a column on the
screen; column% is a numeric
Argument Description
────────────────────────────────────────────────────────────────────────────
screen; column% is a numeric
expression returning an integer.
If column% is not specified, the
column location of the cursor does
not change.
cursor% A Boolean value indicating whether
the cursor is visible or not. A
value of 0 indicates cursor off;
a value of 1 indicates cursor on.
start%, stop% The starting and ending raster
scan lines of the cursor on the
screen. The arguments start% and
stop% redefine the cursor size and
must be numeric expressions
returning an integer between 0 and
31, inclusive.
Argument Description
────────────────────────────────────────────────────────────────────────────
You can omit any argument from the statement except that if stop% is
specified, start% also must be specified. When you omit row% or column%,
LOCATE leaves the cursor at the row or column where it was moved by the most
recently executed input or output statement (such as LOCATE, PRINT, or
INPUT). When you omit other arguments, BASIC assumes the previous value for
the argument.
Note that the start% and stop% lines are the CRT scan lines that specify
which pixels on the screen are lit. A wider range between the start% and
stop% lines produces a taller cursor, such as one that occupies an entire
character block. In OS/2 real mode and under DOS, LOCATE assumes there are
eight lines (numbered 0 to 7) in the cursor. In OS/2 protected mode there
are 16 lines (numbered 0 to 15).
When start% is greater than stop%, LOCATE produces a two-part cursor. If
the start% line is given but the stop% line is omitted, stop% assumes the
same value as start%. A value of 8 for both start% and stop% produces the
underline cursor. The maximum cursor size is determined by the character
block size of the screen mode in use. Setting start% greater than stop%
displays a full-height cursor on VGA-equipped systems.
For screen mode information, see the entry for the SCREEN statement.
The last line on the screen is reserved for the soft-key display and is not
accessible to the cursor unless the soft-key display is off ( KEY OFF) and
LOCATE is used with PRINT to write on the line.
See Also
CSRLIN, POS
Examples
The first example shows the effects on the cursor of different LOCATE
statements:
CLS' Clear screen.
LOCATE 5,5 ' Moves cursor to row 5, column 5.
PRINT "C"
DO
LOOP WHILE INKEY$ = ""
LOCATE 1,1 ' Moves cursor to upper-left corner of the screen.
PRINT "C"
DO
LOOP WHILE INKEY$ = ""
LOCATE , ,1' Makes cursor visible; position remains unchanged.
PRINT "C"
DO
LOOP WHILE INKEY$ = ""
LOCATE , , ,7 ' Position and cursor visibility remain unchanged;
' sets the cursor to display at the bottom of the
' character box starting and ending on scan line 7.
PRINT "C"
DO
LOOP WHILE INKEY$ = ""
LOCATE 5,1,1,0,7 ' Moves the cursor to line 5, column 1;
' turns cursor on; cursor covers entire
' character cell starting at scan line
' 0 and ending on scan line 7.
PRINT "C"
DO
LOOP WHILE INKEY$ = ""
END
The following example prints a menu on the screen, then waits for input in
the allowable range (1-4). If a number outside that range is entered, the
program continues to prompt for a selection.
Note that this program is incomplete.
CONST FALSE = 0, TRUE = NOT FALSE
DO
CLS
PRINT "MAIN MENU": PRINT
PRINT "1) Add Records"
PRINT "2) Display/Update/Delete a Record"
PRINT "3) Print Out List of People Staying at Hotel"
PRINT "4) End Program"
' Change cursor to a block.
LOCATE , , 1, 1, 12
LOCATE 12, 1
PRINT "What is your selection?";
DO
CH$ = INPUT$(1)
LOOP WHILE (CH$ < "1" OR CH$ > "4")
PRINT CH$
' Call the appropriate SUB procedure.
SELECT CASE VAL(CH$)
CASE 1
CALL Add
CASE 2
CALL Search
CASE 3
CALL Hotel
CASE 4
CALL Quit
END SELECT
LOOP WHILE NOT ENDPROG
.
.
.
END
LOCK...UNLOCK Statement
────────────────────────────────────────────────────────────────────────────
Action
Controls access by other processes to all or part of an opened file.
Syntax
LOCK # filenumber% ,{ record& | start& TO end&}
.
.
.
UNLOCK # filenumber% ,{ record& | start& TO end&}
Remarks
These statements are used in networked environments where several processes
might need access to the same file. The LOCK and UNLOCK statements use the
following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file.
record& The number of the record or byte
to be locked. The argument
record& can be any number from 1
Argument Description
────────────────────────────────────────────────────────────────────────────
record& can be any number from 1
to 2,147,483,647 (equivalent to
231 -1). A record can be up to
32,767 bytes in length.
start& The number of the first record or
byte to be locked.
end& The number of the last record or
byte to be locked..
For binary-mode files, record&, start&, and end& represent the number of
a byte relative to the beginning of the file. The first byte in a file is
byte 1.
For random-access files, record&, start&, and end& represent the number
of a record relative to the beginning of the file. The first record is
record 1.
If the file has been opened for sequential input or output, LOCK and
UNLOCK affect the entire file, regardless of the range specified by start&
and end&.
The LOCK and UNLOCK statements are always used in pairs. The arguments to
LOCK and UNLOCK must match exactly.
If you specify just one record, then only that record is locked or unlocked.
If you specify a range of records and omit a starting record ( start&), then
all records from the first record to the end of the range ( end&) are locked
or unlocked. LOCK with no record& locks the entire file, while UNLOCK
with no record& unlocks the entire file.
LOCK and UNLOCK execute only at run time if you are using OS/2 or versions
of DOS that support networking (version 3.1 or later). In DOS, you must run
the SHARE.EXE program to enable locking operations. Using earlier versions
of DOS causes BASIC to generate the error message Feature unavailable if
LOCK and UNLOCK are executed.
Warning
Be sure to remove all locks with an UNLOCK statement before closing a file
or terminating your program. Failing to remove locks produces unpredictable
results.
The arguments to LOCK and UNLOCK must match exactly.
Do not use LOCK and UNLOCK on devices or ISAM tables.
If you attempt to access a file that is locked, BASIC may generate the
following error messages:
Bad record number
Permission denied
Example
The following example illustrates the use of the LOCK and UNLOCK
statements. The program creates a sample data record in a random-access
file. Once the sample record is created and closed, the program again opens
the file to allow customer information to be updated. As a record is opened,
it is locked to prevent use by another terminal that has access to the same
file. After the update is complete, the record is unlocked, again allowing
modifications by others with access.
' Define the record.
TYPE AccountRec
Payer AS STRING * 20
Address AS STRING * 20
Place AS STRING * 20
Owe AS SINGLE
END TYPE
DIM CustRec AS AccountRec
' This section creates a sample record to use.
ON ERROR GOTO ErrHandler
OPEN "MONITOR" FOR RANDOM SHARED AS #1 LEN = LEN(CustRec)
CustRec.Payer = "George Washington"
CustRec.Address = "1 Cherry Tree Lane"
CustRec.Place = "Mt. Vernon, VA"
CustRec.Owe = 12!
PUT #1, 1, CustRec ' Put one record in the file.
CLOSE #1
' This section opens the sample record for updating.
OPEN "MONITOR" FOR RANDOM SHARED AS #1 LEN = LEN(CustRec)
DO
Number% = 0 ' Reset to zero.
DO UNTIL Number% = 1 ' Force user to input 1.
CLS : LOCATE 10, 10
INPUT "Customer Number? #"; Number%
LOOP
' Lock the current record so another process
' doesn't change it while you're using it.
LOCK #1, Number%
GET #1, Number%, CustRec
LOCATE 11, 10: PRINT "Customer: "; CustRec.Payer
LOCATE 12, 10: PRINT "Address: "; CustRec.Address
LOCATE 13, 10: PRINT "Currently owes: $"; CustRec.Owe
LOCATE 15, 10: INPUT "Change (+ or -)", Change!
CustRec.Owe = CustRec.Owe + Change!
PUT #1, Number%, CustRec
' Unlock the record.
UNLOCK #1, Number%
LOCATE 17, 10: INPUT "Update another? ", Continue$
Update$ = UCASE$(LEFT$(Continue$, 1))
LOOP WHILE Update$ = "Y"
CLOSE #1
KILL "MONITOR"' Remove file from disk.
END
ErrHandler:
IF ERR = 70 THEN ' Permission-denied error.
CLS
PRINT "You must run SHARE.EXE before running this example."
PRINT "Exit the programming environment, run SHARE.EXE, and"
PRINT "reenter the programming environment to run this"
PRINT "example. Do not shell to DOS to run SHARE.EXE or you"
PRINT "may not be able to run other programs until you reboot."
END IF
END
LOF Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the size of an open file (in bytes), the number of records in an
ISAM table, or, when used with the OPEN COM statement, the number of bytes
free in the output buffer.
Syntax
LOF( filenumber%)
Remarks
The argument filenumber% is the number used in the OPEN statement to open
the file, device, or ISAM table.
Important
LOF can be used only on disk files, ISAM tables, or COM devices. It cannot
be used with the BASIC devices SCRN, KYBD, CONS, LPT n, or PIPE.
See Also
BOF, EOF, LOC, OPEN (File I/O)
Example
See the programming example for the SEEKGT, SEEKGE, and SEEKEQ
statements, which uses the LOF function in the context of ISAM.
LOG Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the natural logarithm of a numeric expression.
Syntax
LOG( numeric-expression)
Remarks
The argument numeric-expression must be greater than zero. The natural
logarithm is the logarithm to the base e. The constant e is approximately
equal to 2.718282.
LOG is calculated in single precision if numeric-expression is an integer
or single-precision value. If you use any other numeric type, LOG is
calculated in double precision.
You can calculate base-10 logarithms by dividing the natural logarithm of
the number by the natural logarithm of 10. The following FUNCTION procedure
calculates base-10 logarithms:
FUNCTION Log10(X) STATIC
Log10=LOG(X)/LOG(10#)
END FUNCTION
See Also
EXP
Example
The following example prints the value of e and then prints the natural
logarithms of e taken to the first, second, and third powers:
CLS ' Clear screen.
PRINT EXP(1),
FOR I = 1 TO 3
PRINT LOG(EXP(1) ^ I),
NEXT
PRINT
Output
2.718282 1 2 3
LPOS Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the number of characters sent to the printer since the last carriage
return was sent.
Syntax
LPOS( n%)
Remarks
The argument n% is an integer expression with a value between 0 and 3 that
indicates one of the printers. For example, LPT1 would be tested with
LPOS(1) or LPOS(0), LPT2 would be tested with LPOS(2), and LPT3 would be
tested with LPOS(3).
The LPOS function does not necessarily give the physical position of the
print head because it does not expand tab characters. In addition, some
printers may buffer characters.
Example
See the LPRINT statement programming example, which uses the LPOS
function.
LPRINT, LPRINT USING Statements
────────────────────────────────────────────────────────────────────────────
Action
Print data on the printer LPT1.
Syntax
LPRINT expressionlist {;|,}
LPRINT USING formatstring$; expressionlist {;|,}
Remarks
These statements function in the same way as the PRINT and PRINT USING
statements except that output goes to the printer.
The following list describes the parts of the LPRINT and LPRINT USING
statements:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
expressionlist The values that are printed on
printer LPT1.
formatstring$ Specifies the format, using the
same formatting characters as the
PRINT USING statement.
Part Description
────────────────────────────────────────────────────────────────────────────
PRINT USING statement.
{;|,} Determines the location on the
page of the first value printed by
the next statement to use LPT1
(such as the next LPRINT
statement or a PRINT # or WRITE
# directing data to LPT1). The
semicolon means to print
immediately after the last value
in this LPRINT statement; the
comma means to print at the start
of the next unoccupied print zone.
The printer output from an LPRINT statement will be the same as the screen
output from a PRINT statement, if both statements have the same
expressionlist values and output-line width.
The printer output from an LPRINT USING statement will be the same as the
screen output from a PRINT USING statement, if both statements have the
same values for formatstring$, expressionlist, and output-line width.
The LPRINT statement assumes an 80-character-wide printer. This width can
be changed with a WIDTH statement.
If you use LPRINT with no arguments, a blank line is printed.
Warning
Because the LPRINT statement uses the LPT1 printer device, you should not
use LPRINT in a program that also contains an OPEN "LPT1" statement. Using
these two statements together produces unpredictable results.
BASICA
An LPRINT CHR$(13) statement actually outputs both CHR$(13) and CHR$(10).
This feature was created to provide compatibility with BASICA.
See Also
PRINT, PRINT USING, WIDTH
Example
The following example prompts the user for team names and the names of
players on each team. Then it prints the players and their teams on the
printer.
CLS' Clear screen.
LPRINT "Team Members"; TAB(76); "TEAM" : LPRINT
INPUT "How many teams"; TEAMS
INPUT "How many players per team";PPT
PRINT
FOR T = 1 TO TEAMS
INPUT "Team name: ", TEAM$
FOR P = 1 TO PPT
INPUT " Enter player name: ", PLAYER$
LPRINT PLAYER$;
IF P < PPT THEN
IF LPOS(0) > 55 THEN ' Print a new line if print
LPRINT : LPRINT " "; ' head is past column 55.
ELSE
LPRINT ", ";' Otherwise, print a comma.
END IF
END IF
NEXT P
LPRINT STRING$(80-LPOS(0)-LEN(TEAM$),"."); TEAM$
NEXT T
LSET Statement
────────────────────────────────────────────────────────────────────────────
Action
Moves data from memory to a random-access file buffer (in preparation for a
PUT statement), copies one record variable to another, or left-justifies the
value of a string in a string variable.
Syntax 1
LSET stringvariable$= stringexpression$
Syntax 2
LSET recordvariable1= recordvariable2
Remarks
The LSET statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
Argument Description
────────────────────────────────────────────────────────────────────────────
stringvariable$ Usually a random-access file field
defined in a FIELD statement,
although it can be any string
variable.
stringexpression$ The value that is assigned to
stringvariable$ and is
left-justified.
recordvariable1 A record variable of any data type.
recordvariable2 A record variable of any data type.
If stringexpression$ requires fewer bytes than were defined for
stringvariable$ in the FIELD statement, the LSET function left-justifies
the string in the field ( RSET right-justifies the string). Spaces are used
to pad the extra positions. If the string is too long for the field, both
LSET and RSET truncate characters from the right. Numeric values must be
converted to strings before they are justified with the LSET or RSET
statements.
You also can use LSET or RSET with a string variable not defined in a
FIELD statement to left-justify or right-justify a string in a given field.
For example, the following program lines will right-justify the string N$ in
a 20-character field:
A$=SPACE$(20)
RSET A$=N$
This can be useful for formatting printed output.
You can use LSET with Syntax 2 to assign one record variable to another.
The following example copies the contents of RecTwo to RecOne:
TYPE TwoString
StrFld AS STRING * 2
END TYPE
TYPE ThreeString
StrFld AS STRING * 3
END TYPE
DIM RecOne AS TwoString, RecTwo AS ThreeString
.
.
.
LSET RecOne = RecTwo
Notice that LSET is used to assign record variables of differing types.
Record variables of the same type also can be assigned using LET. Also,
because RecOne is only two bytes long, only two bytes are copied from
RecTwo. LSET copies only the number of bytes in the shorter of the two
record variables.
See Also
LET; MKI$, MKL$, MKS$, MKD$, MKC$; PUT (File I/O); RSET
Example
The following example shows the effects of using LSET and RSET to assign
values to fixed- and variable-length strings:
DIM TmpStr2 AS STRING * 25
CLS ' Clear screen.
' Use RSET on variable-length string with a value.
TmpStr$ = SPACE$(40)
PRINT "Here are two strings that have been right and left "
PRINT "justified in a 40-character variable-length string."
PRINT
RSET TmpStr$ = "Right-|"
PRINT TmpStr$
LSET TmpStr$ = "|-Left"
PRINT TmpStr$
PRINT "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
PRINT "12345678901234567890123456789012345678901234567890"
PRINT " 1 2 3 4 5"
' Use RSET on fixed-length string of length 25.
PRINT
PRINT
PRINT "Here are two strings that have been right and left"
PRINT "justified in a 25-character fixed-length string."
PRINT
RSET TmpStr2 = "Right-|"
PRINT TmpStr2
LSET TmpStr2$ = "|-Left"
PRINT TmpStr2$
PRINT "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"
PRINT "12345678901234567890123456789012345678901234567890"
PRINT " 1 2 3 4 5"
Output
Here are two strings that have been right and left
justified in a 40-character variable-length string.
Right-|
|-Left
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12345678901234567890123456789012345678901234567890
1 2 3 4 5
Here are two strings that have been right and left
justified in a 25-character fixed-length string.
Right-|
|-Left
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12345678901234567890123456789012345678901234567890
1 2 3 4 5
LTRIM$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a copy of a string with leading spaces removed.
Syntax
LTRIM$( stringexpression$)
Remarks
The stringexpression$ can be any string expression. The LTRIM$ function
works with both fixed- and variable-length string variables.
See Also
RTRIM$
Example
The following example copies a file to a new file, removing all leading and
trailing spaces:
' Get the filenames.
INPUT "Enter input filename:", InFile$
INPUT "Enter output filename:", OutFile$
OPEN InFile$ FOR INPUT AS #1
OPEN OutFile$ FOR OUTPUT AS #2
' Read, trim, and write each line.
DO WHILE NOT EOF(1)
LINE INPUT #1, LineIn$
' Remove leading and trailing blanks.
LineIn$ = LTRIM$(RTRIM$(LineIn$))
PRINT #2, LineIn$
LOOP
CLOSE #1, #2
END
MID$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a substring of a string.
Syntax
MID$( stringexpression$, start%, length%)
Remarks
The MID$ function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
stringexpression$ The string expression from which
the substring is extracted. This
can be any string expression.
start% The character position in
stringexpression$ where the
Argument Description
────────────────────────────────────────────────────────────────────────────
stringexpression$ where the
substring starts.
length% The number of characters to
extract.
The arguments start% and length% must be between 1 and 32,767, inclusive.
If length% is omitted or if there are fewer than length% characters in the
string (including the start% character), the MID$ function returns all
characters from the position start% to the end of the string.
If start% is greater than the number of characters in stringexpression$,
MID$ returns a null string.
Use the LEN function to find the number of characters in
stringexpression$.
See Also
LEFT$, LEN, MID$ Statement, RIGHT$
Example
The following example converts a binary number to a decimal number. The
program uses the MID$ function to extract digits from the binary number
(input as a string).
INPUT "Binary number = ", Binary$' Input binary number as string.
Length = LEN(Binary$)' Get length of string.
Decimal = 0
FOR K = 1 TO Length
Digit$ = MID$(Binary$, K, 1) ' Get digit from string.
IF Digit$ = "0" OR Digit$ = "1" THEN' Test for binary digit.
Decimal = 2 * Decimal + VAL(Digit$)' Convert digits to numbers.
ELSE
PRINT "Error--invalid binary digit: "; Digit$
EXIT FOR
END IF
NEXT
PRINT "Decimal number =" Decimal
MID$ Statement
────────────────────────────────────────────────────────────────────────────
Action
Replaces a portion of a string variable with another string.
Syntax
MID$( stringvariable$, start% , length%) = stringexpression$
Remarks
The MID$ statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
Argument Description
────────────────────────────────────────────────────────────────────────────
stringvariable$ The string variable being modified.
start% A numeric expression giving the
position in stringvariable$ where
the replacement starts.
length% A numeric expression that gives
the length of the string being
replaced.
stringexpression$ The string expression that
replaces part of stringvariable$.
The arguments start% and length% are integer expressions. The argument
stringvariable$ is a string variable, but stringexpression$ can be a string
variable, a string constant, or a string expression.
The optional length% refers to the number of characters from the argument
stringexpression$ that are used in the replacement. If length% is omitted,
all of stringexpression$ is used. However, regardless of whether length%
is omitted or included, the replacement of characters never goes beyond the
original length of stringvariable$.
See Also
MID$ Function
Example
This example uses the MID$ statement to replace string characters:
CLS' Clear screen.
Test$ = "Paris, France"
PRINT Test$
MID$(Test$, 8)="Texas "' Starting at position 8, replace
' characters in Test$ with Texas.
PRINT Test$
Output
Paris, France
Paris, Texas
MKDIR Statement
────────────────────────────────────────────────────────────────────────────
Action
Creates a new directory.
Syntax
MKDIR pathname$
Remarks
The pathname$ is a string expression that specifies the name of the
directory to be created in DOS. The pathname$ must be a string of fewer
than 64 characters.
The MKDIR statement works like the DOS command MKDIR. However, the syntax
in BASIC cannot be shortened to MD, as it can in DOS.
You can use MKDIR to create a DOS directory with a name that contains an
embedded space. However, although you can access that directory through DOS,
you can remove it only with the BASIC RMDIR statement.
See Also
CHDIR, RMDIR
Example
See the CHDIR statement programming example, which uses the MKDIR
statement.
MKI$, MKL$, MKS$, MKD$, and MKC$ Functions
────────────────────────────────────────────────────────────────────────────
Action
Convert numeric values to string values.
Syntax
MKI$( integer-expression%)
MKL$( long-integer-expression&)
MKS$( single-precision-expression!)
MKD$( double-precision-expression#)
MKC$( currency-expression@)
Remarks
MKI$, MKL$, MKS$, MKD$ and MKC$ are used with FIELD and PUT
statements to write numbers to a random-access file. The functions convert
numeric expressions to strings that can be stored in the strings defined in
the FIELD statement. These functions are the inverse of CVI, CVL, CVS,
CVD, and CVC.
The following table describes these numeric-conversion functions:
╓┌───────────┌───────────────────────────────────────────────────────────────╖
Function Description
────────────────────────────────────────────────────────────────────────────
MKI$ Converts an integer to a 2-byte string.
MKL$ Converts a long-integer value to a 4-byte string.
MKS$ Converts a single-precision value to a 4-byte string.
MKD$ Converts a double-precision value to an 8-byte string.
Function Description
────────────────────────────────────────────────────────────────────────────
MKD$ Converts a double-precision value to an 8-byte string.
MKC$ Converts a currency value to an 8-byte string.
Note
These BASIC record variables provide a more efficient and convenient way of
reading and writing random-access files than some older versions of BASIC.
See Also
CVI, CVL, CVS, CVD, CVC; GET (File I/O); FIELD; PUT (File I/O)
Example
See the programming example for the CVI, CVL, CVS, CVD, and CVC
statements, which uses the MKS$ function.
MKSMBF$, MKDMBF$ Functions
────────────────────────────────────────────────────────────────────────────
Action
Convert an IEEE-format number to a string containing a
Microsoft-Binary-format number.
Syntax
MKSMBF$( single-precision-expression!)
MKDMBF$( double-precision-expression#)
Remarks
These functions are used to write real numbers to random-access files using
Microsoft Binary format. They are particularly useful for maintaining data
files created with older versions of BASIC.
The MKSMBF$ and MKDMBF$ functions convert real numbers in IEEE format to
strings so they can be written to the random-access file.
To write a real number to a random-access file in Microsoft Binary format,
convert the number to a string using MKSMBF$ (for a single-precision
number) or MKDMBF$ (for a double-precision number). Then store the result
in the corresponding field (defined in the FIELD statement) and write the
record to the file using the PUT statement.
Currency numbers are not real numbers, so they cannot be converted to
strings that contain Microsoft-Binary-format numbers.
See Also
CVSMBF, CVDMBF; CVI, CVL, CVS, CVD, CVC; MKI$, MKL$, MKS$, MKD$,
MKC$
Example
The following example stores real values in a file as
Microsoft-Binary-Format numbers:
TYPE Buffer
NameField AS STRING * 20
ScoreField AS STRING * 4
END TYPE
DIM RecBuffer AS Buffer
OPEN "TESTDAT.DAT" FOR RANDOM AS #1 LEN=LEN(RecBuffer)
PRINT "Enter a name and a score, separated by a comma."
PRINT "Enter 'END, 0' to end input."
INPUT NameIn$, Score
I=0' Read names and scores from the console until the name is END.
DO WHILE UCASE$(NameIn$) <> "END"
I=I+1
RecBuffer.NameField=NameIn$
RecBuffer.ScoreField=MKSMBF$(Score) ' Convert to a string.
PUT #1,I,RecBuffer
INPUT NameIn$, Score
LOOP
PRINT I;" records written."
CLOSE #1
MOVEFIRST, MOVELAST, MOVENEXT, MOVEPREVIOUS Statements
────────────────────────────────────────────────────────────────────────────
Action
Make records current according to their relative position in an ISAM table.
Syntax
MOVEFIRST # filenumber%
MOVELAST # filenumber%
MOVENEXT # filenumber%
MOVEPREVIOUS # filenumber%
Remarks
The filenumber% is the number used in the OPEN statement to open the
table. The MOVEFIRST, MOVELAST, MOVENEXT, and MOVEPREVIOUS statements
allow you to make records current according to their relative position on
the current index in an ISAM table:
╓┌──────────────────────┌────────────────────────────────────────────────────╖
Statement Effect
────────────────────────────────────────────────────────────────────────────
MOVEFIRST First record becomes current.
MOVELAST Last record becomes current.
MOVENEXT Next record becomes current.
MOVEPREVIOUS Previous record becomes current.
The action of these statements is made relative to the record that is
current according to the current index.
Using MOVEPREVIOUS when the first indexed record is current moves the
current position to the beginning of the table. The beginning of an ISAM
table is the position before the first record according to the current
index.
Using MOVENEXT when the last indexed record is current moves the current
position to the end of the table. The end of an ISAM table is the position
following the last record according to the current index.
See Also
BOF; EOF; SEEKGT, SEEKGE, SEEKEQ
Example
See the CREATEINDEX statement programming example, which uses the
MOVEFIRST, MOVELAST, MOVENEXT, and MOVEPREVIOUS statements.
NAME Statement
────────────────────────────────────────────────────────────────────────────
Action
Changes the name of a disk file or directory.
Syntax
NAME oldfilespec$ AS newfilespec$
Remarks
The NAME statement is similar to the DOS RENAME command. NAME can move a
file from one directory to another but cannot move a directory.
The arguments oldfilespec$ and newfilespec$ are string expressions, each
of which contains a filename and an optional path. If the path in
newfilespec$ is different from the path in oldfilespec$, the NAME
statement renames the file as indicated.
The file oldfilespec$ must exist and newfilespec$ must not be in use. Both
files must be on the same drive. If you use NAME with different drive
designations in the old and new filenames, BASIC generates the error message
Rename across disks.
Using NAME on an open file causes BASIC to generate the run-time error
message File already open. You must close an open file before renaming it.
Example
The following example shows how to use NAME to rename a README.DOC file:
CLS ' Clear screen.
'Change README.DOC to READMINE.DOC
NAME "README.DOC" AS "READMINE.DOC"
FILES ' Display the files in your directory to confirm name change.
PRINT
PRINT "README.DOC is now called READMINE.DOC"
PRINT "Press any key to continue"
DO
LOOP WHILE INKEY$ = ""
' Change name back to README.DOC and confirm by displaying files.
NAME "READMINE.DOC" AS "README.DOC"
FILES
PRINT
PRINT "README.DOC is back to its original name"
You also can use NAME to move a file from one directory to another. You can
move README.DOC to the directory \MYDIR with the following statement:
NAME "README.DOC" AS "\MYDIR\README.DOC"
OCT$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string representing the octal value of the numeric argument.
Syntax
OCT$( numeric-expression)
Remarks
The argument numeric-expression can be of any type. It is rounded to an
integer or long integer before the OCT$ function evaluates it.
See Also
HEX$
Example
The following example displays the octal version of several decimal numbers:
PRINT "The octal representation of decimal 24 is " OCT$(24)
PRINT "The octal representation of decimal 55 is " OCT$(55)
PRINT "The octal representation of decimal 101 is " OCT$(101)
Output
The octal representation of decimal 24 is 30
The octal representation of decimal 55 is 67
The octal representation of decimal 101 is 145
ON ERROR Statement
────────────────────────────────────────────────────────────────────────────
Action
Enables an error-handling routine and specifies the location of that routine
in the program. The ON ERROR statement also can be used to disable an
error-handling routine.
Syntax
ON LOCAL ERROR { GOTO line | RESUME NEXT | GOTO 0}
Remarks
If no ON ERROR statement is used in a program, any run-time error will be
fatal (BASIC generates an error message and program execution stops).
The following list describes the parts of the ON ERROR statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
LOCAL Used to indicate an error-handling
routine in the same procedure. If
not used, module-level error
handlers are indicated.
Part Description
────────────────────────────────────────────────────────────────────────────
handlers are indicated.
GOTO line Enables the error-handling routine
that starts at line. Thereafter,
if a run-time error occurs,
program control branches to line
(a label or a line number). The
specified line is either in the
module-level code or in the same
procedure (if the LOCAL keyword
is used). If not found in either
place, BASIC generates a Label not
defined compile-time error.
RESUME NEXT Specifies that, when a run-time
error occurs, control goes to the
statement after the statement
where the error occurred; the ERR
function then can be used to
Part Description
────────────────────────────────────────────────────────────────────────────
function then can be used to
obtain the run-time error code.
GOTO 0 Disables any enabled module-level
error-handling routine within the
current module, or disables any
enabled error handler within the
current procedure (if used
together with the LOCAL keyword).
The LOCAL keyword indicates an error-handling routine that is "local" to
the procedure within which the error-handling routine is located. A local
error-handling routine:
■ Overrides any enabled module-level error-handling routines.
■ Is enabled only while the procedure within which it is located is
executing.
Notice that the local error handler remains enabled while any procedures
execute that are directly or indirectly called by the procedure within which
the error handler is located. One of those procedures may supersede the
local error handler.
Note
The module-level error-handling routines provided by previous versions of
BASIC may be all you need; you may never need to use the LOCAL keyword.
Use of the RESUME NEXT option causes program execution to resume with the
statement immediately following the statement that caused the run-time
error. This enables your program to continue execution of a block of program
code, despite a run-time error, then check for the cause of the error. This
also enables you to build the error-handling code in line with the main
module code or procedure, rather than at a remote location in the program.
The statement form ON ERROR GOTO 0 disables error handling. It does not
specify line 0 as the start of the error-handling code, even if the program
or procedure contains a line num-bered 0.
Notice that an error-handling routine is not a SUB or FUNCTION procedure
or a DEF FN function. An error-handling routine is a block of code marked
by a line label or line number.
An error handler is enabled when it is referred to by an ON ERROR GOTO
line statement. Once an error handler is enabled, a run-time error causes
program control to jump to the enabled error-handling routine and makes the
error handler "active." An error handler is active from the time a run-time
error has been trapped until a RESUME statement is executed in the handler.
Error-handling routines must rely on the value in ERR to determine the
cause of the error. The error-handling routine should test or save this
value before any other error can occur or before calling a procedure that
could cause an error. The value in ERR reflects only the last error to
occur.
If you use the BASIC command line to compile a program that has been
developed in the QBX environment and has error-handling routines, compile
with the /E or /X option. The Make EXE File command in the QBX environment
uses these options.
If an error occurs in a procedure or module that does not have an enabled
error-handling routine, BASIC searches for an enabled, inactive error
handler to trap the error. BASIC searches back through all the procedures
and modules that have called the procedure where the error occurred.
Using Module-Level Error Handlers
Once enabled by execution of an ON ERROR GOTO line statement, a
module-level error handler stays enabled unless explicitly disabled by
execution of an ON ERROR GOTO 0 statement somewhere in the module.
In the following cases, BASIC searches back through the module-level code of
the calling modules, looking for an enabled, inactive error handler:
■ In a multiple-module program that contains only module-level
error handlers, if an enabled and inactive error handler cannot
be found in the module where the error occurred.
■ If an error occurs in a module-level error handler itself (BASIC
does not automatically treat this as a fatal error).
■ If an ON ERROR GOTO 0 statement is encountered while the
current module's module-level error handler is active.
Procedure-Level Error Handlers
SUB and FUNCTION procedures and DEF FN functions can contain their own
error-handling routines.
To enable a local error handler, use the statement ON LOCAL ERROR GOTO
line. The argument line must be a label or line number in the same
procedure as the ON LOCAL ERROR GOTO statement.
The local error handler is automatically disabled when the procedure
returns, or by execution of the statement ON LOCAL ERROR GOTO 0.
You will want program flow to avoid the statements that make up the
error-handling routine. One way to keep the error-handling code from
executing when there is no error is to place an EXIT SUB, EXIT FUNCTION,
or EXIT DEF statement immediately ahead of the error-handling routine, as
in the following example:
SUB InitializeMatrix (var1, var2, var3, var4)
.
.
.
ON LOCAL ERROR GOTO ErrorHandler
.
.
.
EXIT SUB
ErrorHandler:
.
.
.
RESUME NEXT
END SUB
The example shows the error-handling code located after the EXIT SUB
statement and before the END SUB statement. This partitions the
error-handling code from the normal execution flow of the procedure.
However, error-handling code can be placed anywhere in a procedure.
In the QBX environment, or if the command-line compiler is used with the /O
option:
■ If a local error handler is active and an END SUB, END
FUNCTION, or END DEF statement is encountered, BASIC generates
the run-time error message No RESUME.
■ If an EXIT SUB, EXIT FUNCTION, or EXIT DEF statement is
encountered, BASIC does not generate a run-time error; in other
words, it is assumed that this does not represent a logic error
in the program.
In a multiple-module program that contains only procedure-level (local)
error handlers, if an enabled and inactive error handler cannot be found in
the procedure where the error occurred, BASIC searches back through all the
calling procedures as well as the module-level code of all the calling
modules, looking for an enabled, inactive error handler.
Using Both Module-Level and Procedure-Level Error Handlers
For simplicity and clarity, avoid using both local- and module-level error
handlers in the same program, except for using an error handler in the main
module module-level code as the last line of defense against a fatal error.
If you need to, however, you can have both a module-level error handler and
a local error handler enabled at the same time. (In fact, you can enable
both local- and module-level error handling from within a procedure.)
While searching for an enabled, inactive error handler, BASIC may encounter
an active event handler. Unless an enabled error-handling routine is
provided in the same module-level code as the event handler, BASIC generates
a fatal error. Therefore, to produce completely bullet-proof BASIC code in
programs that trap events, make sure an error handler in the same
module-level code as the event handler is enabled at the time the event
occurs. Because event handlers can be located only at the module level, this
is another special case where you might mix module-level and procedure-level
error handlers.
Notice that when an error-handling routine is finished and program execution
resumes through execution of a RESUME 0 or RESUME NEXT statement, the
resume location is based on the location of the error-handling routine, and
not necessarily on the location where the error occurred. For more
information, see the entry for RESUME.
See Also
ERL, ERR; ERROR; RESUME
Example
The following program prompts the user for a disk drive designation. Once
the user has input the drive designation, the program attempts to write a
large file to the disk. A number of errors can occur.
DECLARE SUB ErrorMessage (Message$)
DECLARE SUB WriteBigFile (Filenum%)
ON ERROR GOTO ErrHandler
CLS
PRINT "This program will attempt to write a large file to a disk drive that"
PRINT "you have selected. The file will be erased when the program ends."
PRINT
DO
INPUT "Enter the letter of the drive where you want this file written"; DR$
DR$ = UCASE$(DR$)
LOOP UNTIL LEN(DR$) >= 1 AND LEN(DR$) <= 2 AND DR$ >= "A" AND DR$ <= "Z"
IF LEN(DR$) > 1 THEN
IF RIGHT$(DR$, 1) <> ":" THEN
DR$ = LEFT$(DR$, 1) + ":"
END IF
ELSE
DR$ = DR$ + ":"
END IF
' Put together a complete file specification.
FileSpec$ = DR$ + "BIGFILE.XXX"
' Get the next available file number.
Filenum% = FREEFILE
' Try an open the file
OPEN FileSpec$ FOR OUTPUT AS Filenum%
WriteBigFile Filenum%
CLOSE Filenum%
CLS
PRINT "Everything was OK. No errors occurred."
PRINT "Deleting the file that was created."
KILL FileSpec$
' Same as END, returns to operating system.
SYSTEM
ErrHandler:
SELECT CASE ERR
CASE 52'Bad file name or number.
END
CASE 53' File not found.
RESUME NEXT
CASE 57' Device I/O error.
ErrorMessage "You should probably format the disk."
END
CASE 64' Bad file name.
ErrorMessage "The drive name you specified was not correct."
END
CASE 68' Device unavailable
ErrorMessage "The drive you named is unavailable."
END
CASE 71' Drive not ready
ErrorMessage "The drive was not ready. Check the drive!"
END
CASE ELSE
ErrorMessage "An unexpected FATAL error has occurred."
STOP
END SELECT
SUB ErrorMessage (Message$)
ON LOCAL ERROR GOTO MessageError
CLS
PRINT Message$
PRINT "Cannot continue."
PRINT
PRINT "Press any key to exit."
DO
LOOP WHILE INKEY$ = ""
EXIT SUB
MessageError:
RESUME NEXT
END SUB
SUB WriteBigFile (Filenum%)
ON LOCAL ERROR GOTO LocalHandler
TEXT$ = STRING$(1024, "A")
FOR I% = 1 TO 400
PRINT #Filenum%, TEXT$
NEXT I%
EXIT SUB
LocalHandler:
SELECT CASE ERR
CASE 61 ' Disk full
ErrorMessage ("There is no room remaining on the disk.")
KILL "BIGFILE.XXX"
END
CASE ELSE
ERROR ERR
END SELECT
END SUB
ON event Statements
────────────────────────────────────────────────────────────────────────────
Action
Indicate the first line of an event-trapping routine.
Syntax
ON event GOSUB { linenumber | linelabel}
Remarks
The ON event statements let you specify a routine that is executed
whenever a specified type of event occurs on a specified device. The ON
event statements use the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
event Specifies the event that causes a
branch to the event-trapping
routine. See below for more
information about specific types
of events.
linenumber or linelabel The number or label of the first
line in the event-trapping routine.
This line must be in the
module-level code.
A linenumber value of 0 disables
event trapping and does not
Argument Description
────────────────────────────────────────────────────────────────────────────
event trapping and does not
specify line 0 as the start of the
routine.
The following list describes the events that can be trapped:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Event Description
────────────────────────────────────────────────────────────────────────────
COM( n%) Branches to the routine when
characters are received at a
communications port. The integer
expression n% indicates one of
the serial ports, either 1 or 2.
For more information, see "Using
ON COM" later in this entry.
KEY( n%) Branches to the routine when a
Event Description
────────────────────────────────────────────────────────────────────────────
KEY( n%) Branches to the routine when a
specified key is pressed. The
integer expression n% is the
number of a function key,
direction key, or user-defined key.
For more information, see "Using
ON KEY" later in this entry.
PEN Branches to the routine when a
lightpen is activated. For more
information, see "Using ON PEN"
later in this entry.
PLAY( queuelimit%) Branches when there are fewer than
queuelimit% notes in the
background-music queue. A PLAY
event-trapping routine can be used
with a PLAY statement to play
music in the background while a
Event Description
────────────────────────────────────────────────────────────────────────────
music in the background while a
program is running. For more
information, see "Using ON PLAY"
later in this entry.
SIGNAL( n%) Branches to the routine when an
OS/2 protected-mode signal is
received. For more information,
see "Using ON SIGNAL" later in
this entry.
STRIG( n%) Branches to the event-trapping
routine when a joystick trigger is
pressed. The integer expression
n% is the joystick trigger number.
For more information, see "Using
ON STRIG" later in this entry.
TIMER( n&) Branches to the routine when n
Event Description
────────────────────────────────────────────────────────────────────────────
TIMER( n&) Branches to the routine when n
seconds have passed. The numeric
expression n& is in the range 1
to 86,400 (1 second to 24 hours).
UEVENT Branches to the event-trapping
routine for a user-defined event.
This event usually is a hardware
interrupt (although it can be a
software interrupt). For more
information, see "Using ON UEVENT"
later in this entry.
The ON event statement specifies only the start of an event-trapping
routine. Another set of statements determines whether or not the routine is
called. This set of statements turns event trapping on or off and determines
how events are handled when trapping is off. The following list describes
these statements in a general way. See the entries for particular statements
for more specific information.
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Event Description
────────────────────────────────────────────────────────────────────────────
event ON Enables event trapping. Event
trapping occurs only after an
event ON statement is executed.
event OFF Disables event trapping. No
trapping takes place until the
execution of another event ON
statement. Events occurring while
trapping is off are ignored.
event STOP Suspends event trapping so no
trapping takes place until an
event ON statement is executed.
Events occurring while trapping is
inhibited are remembered and
processed when an event ON
Event Description
────────────────────────────────────────────────────────────────────────────
processed when an event ON
statement is executed.
When an event trap occurs and the routine is called, BASIC performs an
automatic event STOP that prevents recursive traps. The RETURN statement
from the trapping routine automatically performs an event ON statement
unless an explicit event OFF is performed inside the routine.
If your program contains event-handling statements and you are compiling
from the BC command line, use the BC /W or /V option. (The /W option checks
for events at every label or line number; the /V option checks at every
statement.) If you do not use these options and your program contains event
traps, BASIC generates the error message ON events without /V or /W on
command line.
Note
Because of the implicit event STOP and event ON statements, events that
occur during execution of the trapping routine are remembered and processed
when the routine ends.
The RETURN linenumber or RETURN linelabel forms of RETURN can be used
to return to a specific line from the trapping routine. Use this type of
return with care, however, because any GOSUB, WHILE, or FOR statements
active at the time of the trap remain active. BASIC may generate error
messages such as NEXT without FOR. In addition, if an event occurs in a
procedure, a RETURN linenumber or RETURN linelabel statement cannot get
back into the procedure because the line number or label must be in the
module-level code.
The next sections contain additional information about the ON COM, ON KEY,
ON PEN, ON PLAY, ON SIGNAL, ON STRIG, and ON UEVENT statements.
Using On Com
You can use ON COM( n%) to specify a routine to branch to when characters
are received at communications port n%, which can be either 1 or 2.
If your program receives data using an asynchronous communications adapter,
the BASIC command-line option /C can be used to set the size of the data
buffer.
For an example of the ON COM statement, see the COM statements programming
example.
Using On Key
You can use ON KEY( n%) to specify a routine to branch to when key n% is
pressed. The argument n% is the number of a function key, direction key, or
user-defined key.
Keys are processed in the following order:
■ The line printer's echo-toggle key is processed first. Defining
this key as a user-defined key trap does not prevent characters
from being echoed to the line printer when pressed.
■ Function keys and the direction keys are examined next. Defining
a function key or direction key as a user-defined key trap has
no effect because these keys are predefined.
■ Finally, the user-defined keys are examined.
The ON KEY statement can trap any key, including break or system reset.
This makes it possible to prevent accidentally breaking out of a program or
rebooting the machine.
Note
After a key is trapped, the information on which key was trapped is no
longer available. This means that you cannot subsequently use the INPUT
statement or INKEY$ function to find out which key caused the trap. Because
you do not know which key press caused the trap, you must set up a different
event-handling routine for each key you want to trap.
For an example of the ON KEY statement, see the KEY statements programming
example.
Using On PEN
You can use ON PEN to specify a routine to branch to when the lightpen is
activated.
ON PEN is not available for OS/2 protected mode.
For an example of the ON PEN statement, see the PEN statements programming
example.
Using On PLAY
You can use ON PLAY( queuelimit%) to specify a routine to branch to when
there are fewer than queuelimit% notes in the background-music queue. The
argument queuelimit% is an integer expression between 1 and 32, inclusive.
The following three rules apply to the use of ON PLAY:
■ A play-event trap occurs only when music is playing in the
background. Play-event traps do not occur when music is running
in the foreground.
■ A play-event trap does not occur if the background music queue
has already gone from having queuelimit% to queuelimit%-1
notes when a PLAY ON is executed.
■ If queuelimit% is a large number, event traps may occur often
enough to slow down the program.
ON PLAY is not available for OS/2 protected mode.
For an example of the ON PLAY statement, see the PLAY function programming
example.
Using On SIGNAL
You can use ON SIGNAL to specify a routine to branch to when an OS/2
protected-mode signal is trapped.
The following table lists the numbers of the protected-mode signals:
╓┌─────────────────────┌─────────────────────────────────────────────────────╖
Number Signal
────────────────────────────────────────────────────────────────────────────
1 Ctrl+C
2 Pipe connection broken
3 Program terminated
4 Ctrl+Break
5 Process flag A
6 Process flag B
7 Process flag C
Process flag A, process flag B, and process flag C are used for
communicating between processes. Although BASIC has no built-in mechanism
for activating a process flag, you can activate the signal handler in a
separate process by invoking the OS/2 function DOSFLAGPROCESS.
The ON SIGNAL statement is available only for OS/2 protected mode.
For an example of the ON SIGNAL statement, see the SIGNAL statements
programming example.
Using On STRIG
You can use ON STRIG( n%) to specify a routine to branch to when the button
on the joystick is pressed. The argument n% is the trigger number as
defined in the following table:
╓┌───┌───────┌───────────────────────────────────────────────────────────────╖
n% Button Joystick
────────────────────────────────────────────────────────────────────────────
0 Lower First
2 Lower Second
4 Upper First
6 Upper Second
ON STRIG is not available for OS/2 protected mode.
For an example of the ON STRIG statement, see the STRIG statements
programming example.
Using On UEVENT
You can use ON UEVENT to specify a routine to branch to when a user-defined
event occurs. The event usually is a hardware interrupt (although it also
can be a software interrupt).
When using DOS, at least two (and sometimes three) pieces of code are
needed. The first is the interrupt-service routine. The second is an
initialization routine to insert the address of the service routine into the
interrupt-vector table. The third is the routine your BASIC program calls to
retrieve the data (if any) collected by the interrupt-service routine. For
more information, see "Event Handling" in the Programmer's Guide.
If the initialization routine "steals" an interrupt used by another service
routine, the original address must be restored before your program
terminates.
These routines usually are written in assembly language. However, any
language whose compiler can generate interrupt-service routines and whose
object code can be linked with BASIC can be used.
There are four steps in creating a user-defined event:
■ Write an event-handling routine and add it to your BASIC
program.
■ Execute the ON UEVENT statement to specify the user-event
handling routine.
■ Execute the UEVENT ON statement to enable user-event trapping.
■ Call the interrupt-initialization routine to insert the address
of the interrupt-service routine into the interrupt-vector
table.
You're now ready for the interrupt when it occurs. The interrupt transfers
execution to the interrupt-service routine. The service routine collects and
stores the data the user wants. It then calls SetUEvent (see the entry for
SetUEvent for details).
SetUEvent sets a flag checked by BASIC before going to the next BASIC
statement (or label if executing compiled code using /W instead of /V). When
the flag is set, control transfers to the event-handling routine designated
in ON EVENT.
For an example of the ON UEVENT statement, see the UEVENT statements
programming example.
See Also
COM, EVENT, KEY (Event Trapping), PEN, PLAY (Event Trapping), RETURN,
SIGNAL, STRIG, TIMER, UEVENT
ON...GOSUB, ON...GOTO Statements
────────────────────────────────────────────────────────────────────────────
Action
Branches to one of several specified lines, depending on the value of an
expression.
Syntax 1
ON expression GOSUB line-label-list
Syntax 2
ON expression GOTO line-label-list
Remarks
The argument expression can be any numeric expression between 0 and 255,
inclusive ( expression is rounded to an integer before the ON... GOSUB or
ON... GOTO statement is evaluated). The argument line-label-list consists
of a list of line numbers or line labels, separated by commas. The value of
expression determines which line the program branches to. For example, if
the value is 3, the third line specified in the list is the destination of
the branch.
The value of expression should be greater than or equal to 1 and less than
or equal to the number of items in the list. If the value falls outside this
range, one of the following results occurs:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
Value Result
────────────────────────────────────────────────────────────────────────────
Number equal to 0 or greater than Control drops to the next BASIC
number of items in list statement.
Negative number or a number greater BASIC generates the error
than 255 messageIllegal function call.
You may mix line numbers and labels in the same list.
Note
You can mix line numbers and labels in the same list. The ON ... GOTO
statement accepts a maximum of 60 line labels or line numbers. The SELECT
CASE statement provides a more powerful, convenient, and flexible way to
perform multiple branching.
See Also
GOSUB, RETURN, SELECT CASE
Example
The following example causes program control to branch to one of three
subroutines, depending on the value of Chval:
CLS ' Clear screen.
Attend = 20
Fees = 5 * Attend
PRINT "1 Display attendance at workshops"
PRINT "2 Calculate total registration fees paid"
PRINT "3 End program"
PRINT : PRINT "What is your choice?"
Choice:
DO
ch$ = INKEY$
LOOP WHILE ch$ = ""
Chval = VAL(ch$)
IF Chval > 0 AND Chval < 4 THEN
ON Chval GOSUB Shop, Fees, Progend
END IF
END
Shop:
PRINT "ATTENDANCE IS", Attend
RETURN Choice
Fees:
PRINT "REGISTRATION FEES ARE $"; Fees
RETURN Choice
Progend:
END
OPEN Statement (File I/O)
────────────────────────────────────────────────────────────────────────────
Action
Enables I/O to a file, device, or ISAM table.
Syntax 1
OPEN file$ FOR mode ACCESS access lock AS # filenumber% LEN=
reclen% OPEN database$ FOR ISAM tabletype tablename$ AS #
filenumber%
Syntax 2
OPEN mode$, # filenumber%, file$, reclen%
Remarks
You must open a file before any I/O operation can be performed on it. OPEN
allocates a buffer for I/O to the file or device and determines the mode of
access used with the buffer.
The OPEN statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
file$ A filename or path.
mode A keyword that specifies one of
the following file modes: Random,
Argument Description
────────────────────────────────────────────────────────────────────────────
the following file modes: Random,
Binary, Input, Output
access A keyword that specifies the
operation performed on the open
file:
lock A keyword that specifies the lock
type:
filenumber% An integer expression with a value
between 1 and 255, inclusive. When
an OPEN statement is executed,
the file number is associated with
the file as long as it is open.
Other I/O statements may use the
Argument Description
────────────────────────────────────────────────────────────────────────────
Other I/O statements may use the
number to refer to the file.
reclen% For random-access files, the
record length; for sequential
files, the number of characters
buffered. The reclen% is an
integer expression less than or
equal to 32,767 bytes.
database$ A database filename or path.
tabletype The name of a type of table
defined using the TYPE statement.
tablename$ The name of the ISAM table being
opened. It follows the ISAM naming
conventions (listed later in this
entry).
Argument Description
────────────────────────────────────────────────────────────────────────────
entry).
Syntax 1
The arguments file$ and database$ specify an optional device, followed by
a filename or path conforming to the DOS file-naming conventions. The
argument database$ must be the name of an ISAM file.
For sequential files, if file$ does not exist, it is created when opening a
file for anything but input [mdash] that is, OUTPUT, RANDOM, BINARY, and
APPEND. For ISAM, a nonexistent database$ or tablename$ is created only
when using the PROISAMD library; with the PROISAM library, BASIC generates
the error message File Not Found if database$ or tablename$ does not
exist.
The argument mode is a keyword that specifies one of the following file
modes:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Keyword Description
────────────────────────────────────────────────────────────────────────────
Random Specifies random-access file mode,
the default mode. In random mode,
if no ACCESS clause is present,
three attempts are made to open
the file when the OPEN statement
is executed. Access is attempted
in the following order:
1. Read and write
2. Write only
3. Read only
Binary Specifies binary file mode. In
binary mode, you can read or write
Keyword Description
────────────────────────────────────────────────────────────────────────────
binary mode, you can read or write
information to any byte position
in the file using GET and PUT.
In binary mode, if no ACCESS
clause is present, three attempts
are made to open the file,
following the same order as for
random files.
Input Sequential input mode.
Output Sequential output mode.
Append Sequential output mode. Sets the
file pointer to the end-of-file
and the record number to the last
record of the file. A PRINT # or
WRITE # statement then extends
Keyword Description
────────────────────────────────────────────────────────────────────────────
WRITE # statement then extends
(appends to) the file.
If the mode argument is omitted, the default random-access mode is assumed.
The argument access is a keyword that specifies the operation performed on
the opened file. If the file is already opened by another process and the
specified type of access is not allowed, the OPEN operation fails and BASIC
generates the error Permission denied. The ACCESS clause works in an OPEN
statement only if you are using a version of DOS that supports networking
(DOS version 3.0 or later). In addition, you must run the SHARE.EXE program
(or the network startup program must run it) to perform any locking
operation. If ACCESS is used with OPEN, earlier versions of DOS return the
error message Feature unavailable.
The argument access can be one of the following:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Access type Description
────────────────────────────────────────────────────────────────────────────
Read Opens the file for reading only.
Write Opens the file for writing only.
Read Write Opens the file for both reading
and writing. This mode is valid
only for random and binary files,
and files opened for append.
The lock clause works in a multiprocessing environment to restrict access
by other processes to an open file. The argument can be one of the following
keywords specifying the lock type:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Lock type Description
────────────────────────────────────────────────────────────────────────────
Shared Any process on any machine may
read from or write to this file.
Do not confuse the shared lock
type with the SHARED statement or
the shared attribute that appears
in other statements.
Lock Read No other process is granted read
access to this file. This access
is granted only if no other
process has a previous read access
to the file.
Lock Write No other process is granted write
access to this file. This lock is
granted only if no other process
Lock type Description
────────────────────────────────────────────────────────────────────────────
granted only if no other process
has a previous write access to the
file.
Lock Read Write No other process is granted either
read or write access to this file.
This access is granted only if
read or write access has not
already been granted to another
process, or if a lock read or lock
write is not already in place.
If you do not specify a lock type, the file may be opened for reading and
writing any number of times by this statement, but other operations are
denied access to the file while it is opened.
When OPEN is restricted by a previous process, BASIC generates error 70,
Permission denied.
The argument reclen% is an integer expression less than or equal to 32,767
bytes. It specifies different settings for random-access or sequential
files:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
For random-access: For sequential files:
────────────────────────────────────────────────────────────────────────────
The argument reclen% sets the The argument reclen% specifies the
record length (the number of number of characters to be loaded
characters in a record). into the buffer before the buffer is
written to, or read from, the disk.
The default is 128 bytes. A larger buffer means more room
taken from BASIC, but faster file
I/O. A smaller buffer means more
room in memory for BASIC, but slower
I/O.
For random-access: For sequential files:
────────────────────────────────────────────────────────────────────────────
I/O.
The default is 512 bytes.
The LEN clause and reclen% are ignored if mode is binary. For sequential
files, reclen% need not correspond to an individual record size, because a
sequential file may have records of different sizes.
ISAM is a keyword that specifies you are opening an ISAM table.
The argument tabletype is the name of a user-defined type that defines a
subset of the table definition. (See the entry for the TYPE statement.) The
argument tablename$ is the name of the ISAM table being opened. It follows
the ISAM naming conventions:
■ It has no more than 30 characters.
■ It uses only alphanumeric characters (A-Z, a-z, 0-9).
■ It begins with an alphabetic character.
■ It includes no BASIC special characters.
Syntax 2
In the second (alternative) form of the OPEN syntax, mode$ is a string
expression that begins with one of the following characters and specifies
the file mode:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Mode Description
────────────────────────────────────────────────────────────────────────────
O Sequential output mode.
I Sequential input mode.
Mode Description
────────────────────────────────────────────────────────────────────────────
I Sequential input mode.
R Random-access file I/O mode.
B Binary file mode.
A Sequential output mode. Sets the
file pointer to the end of the
file and the record number to the
last record of the file. A PRINT
# or WRITE # statement extends
(appends to) the file.
Note
This alternative syntax does not support any of the access and file-sharing
options found in the primary syntax. It is supported for compatibility with
programs written in earlier versions of BASIC.
The following devices are supported by BASIC and can be named and opened
with the argument file$:
KYBD, SCRN, COM n, LPT n, CONS, PIPE.
The BASIC file I/O system allows you to take advantage of user-installed
devices. (See your DOS manual for information on character devices.)
Character devices are opened and used in the same manner as disk files.
However, characters are not buffered by BASIC as they are for disk files.
The record length for device files is set to 1.
BASIC sends only a carriage return at the end of a line. If the device
requires a line feed, the driver must provide it. When writing to device
drivers, keep in mind that other BASIC users will want to read and write
control information. Writing and reading of device-control data is handled
by the IOCTL statement and IOCTL$ function.
None of the BASIC devices directly supports binary mode. However,
line-printer devices can be opened in binary mode by adding the BIN
keyword:
OPEN "LPT1:BIN" FOR OUTPUT AS #1
Opening a printer in binary mode eliminates printing a carriage return at
the end of a line.
When you open an ISAM table, the next record is the first record in the
table and the current index is the null index.
Any ISAM operation that closes a table causes transactions to be committed.
For example, if a type mismatch occurs while you are opening an ISAM table,
the table is closed and a pending transaction is committed.
You may wish to code your programs so they first open all tables, then
perform all transactions, then close tables. Make sure any operation that
can close a table occurs outside a transaction.
Note
In input, random-access, and binary modes you can open a file under a
different file number without first closing the file. In output or append
mode you must close a file before opening it with a different file number.
See Also
CLOSE, FREEFILE, TYPE
Example
See the FREEFILE function programming example, which uses the OPEN
statement.
OPEN COM Statement
────────────────────────────────────────────────────────────────────────────
Action
Opens and initializes a communications channel for I/O.
Syntax
OPEN " COM n: optlist1 optlist2" FOR mode AS # filenum% LEN=
reclen%
Remarks
The OPEN COM statement must be executed before a device can be used for
communication using an RS232 interface. COM n is the name of the device to
be opened. If there are any syntax errors in the OPEN COM statement, BASIC
generates the error message Bad file name.
The OPEN COM statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
n The communications port to open,
such as 1 for COM1 and 2 for COM2.
optlist1 The most-often-used communications
parameters. The defaults are 300
baud, even parity, 7 data bits,
and 1 stop bit. The syntax of
optlist1 and options are described
later in this entry.
optlist2 Up to 10 other optional,
Argument Description
────────────────────────────────────────────────────────────────────────────
optlist2 Up to 10 other optional,
less-often-used data
communications parameters. The
parameters for optlist2 are
described later in this entry.
mode One of the keywords OUTPUT,
INPUT, or RANDOM (the default).
filenum% Any unused file number between 1
and 255, inclusive.
reclen% The size of a random-access-mode
buffer (128 bytes is the default).
The argument optlist1 specifies the communication-line parameters and has
this syntax:
speed , parity , data , stop
The following table lists the valid values for optlist1 options:
╓┌───────┌─────────────────────┌─────────────────────┌───────────────────────╖
Option Description Range Default
────────────────────────────────────────────────────────────────────────────
speed Baud rate (bits per 75, 110, 150, 300, 300
second) of the 600, 1200, 1800,
device to be opened) 2400, 9600
parity Method of parity N, E, O, S, M E
checking (none, even,
odd, space, mark)
data Number of data bits 5, 6, 7, or 8 7
per byte
Option Description Range Default
────────────────────────────────────────────────────────────────────────────
stop Number of stop bits 1, 1.5, or 2 1 *
* The default value is
1 for baud rates
greater than 110. For
baud rates less than
or equal to 110, the
default value is 1.5
when data is 5;
otherwise, the value
is 2.
Options in this list must be entered in the order shown. Use comma
placeholders for defaults. For example:
OPEN "COM1: ,N,8," FOR INPUT AS #1
Only the baud rates shown are supported. Any other value for speed is
invalid.
If any options from optlist2 are chosen, comma placeholders still must be
used even if all of the optlist1 options are defaults. For example:
OPEN "COM1: ,,,,CD1500" FOR INPUT AS #1
If you set data to 8 bits per byte, you must specify no parity ( N).
Note
Because BASIC uses complete bytes (8 bits) for numbers, you must specify 8
data bits when transmitting or receiving numeric data.
The optlist2 options can be specified in any order, and must be separated
by commas. There are three types of options: data mode, buffer size, and
handshaking.
The data-mode options ( ASC, BIN, and LF) are described in the following
table:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Option Description
────────────────────────────────────────────────────────────────────────────
ASC Opens the device in ASCII mode. In
ASCII mode, tabs are expanded to
blanks, carriage returns are
forced at end-of-line, and Ctrl+Z
means end-of-file. When the
Option Description
────────────────────────────────────────────────────────────────────────────
means end-of-file. When the
channel is closed, Ctrl+Z is sent
over the RS-232 line.
BIN Opens the device in binary mode.
This option supersedes the LF
option. BIN is elected by default
unless ASC is specified.
In binary mode, tabs are not
expanded to spaces, a carriage
return is not forced at the end of
a line, and Ctrl+Z is not treated
as end-of-file. When the channel
is closed, Ctrl+Z will not be sent
over the RS232 line.
LF Allows communication files to be
printed on a serial line printer.
Option Description
────────────────────────────────────────────────────────────────────────────
printed on a serial line printer.
Effective only with the ASC option.
When LF is specified, a line-feed
character (0AH) is automatically
sent after each carriage-return
character (0DH). This includes the
carriage return sent as a result
of the width setting. Note that
INPUT and LINE INPUT, when used
to read from a communications file
that was opened with the LF option,
stop when they see a carriage
return, ignoring the line feed.
The buffer-size options for sequential modes (RB and TB) are described in
the following table:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Option Description
────────────────────────────────────────────────────────────────────────────
RB n Sets the size of the receive
buffer to n bytes. The initial
buffer size, if n or the RB
option is omitted, is 512 bytes,
unless overridden by the /C option
on the QBX or BC command line. The
default value, if n or the RB
option is omitted, is the current
receive-buffer size. The maximum
size is 32,767 bytes.
TB n Sets the size of the receive
buffer to n bytes. The initial
buffer size, if n or the TB
option is omitted, is 512 bytes.
The default value, if n or the TB
option is omitted, is the current
receive-buffer size.
Option Description
────────────────────────────────────────────────────────────────────────────
receive-buffer size.
Handshake and timing options (RS, CD, CS, DS, and OP) are described in the
table below:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Option Description
────────────────────────────────────────────────────────────────────────────
RS Suppresses detection of Request To
Send (RTS).
CD m Specifies the timeout period on
the Data Carrier Detect line (DCD).
If no signal appears on the DCD
line (the DCD line remains low)
Option Description
────────────────────────────────────────────────────────────────────────────
line (the DCD line remains low)
for more than m milliseconds, a
device timeout occurs. If a CD
timeout occurs, ERDEV contains
130 (82H).
The range for m, if specified, is
0 - 65,535 milliseconds, inclusive.
The default value is 0, if the CD
option is not used, or if m is
omitted. When m is 0, either by
default or assignment, it means
that the state of the DCD line is
to be ignored.
CS m Specifies the timeout period on
the Clear To Send line (CTS). If
no signal appears on the CTS line
(the CTS line remains low) for
Option Description
────────────────────────────────────────────────────────────────────────────
(the CTS line remains low) for
more than m milliseconds, a
device timeout occurs. If a CS
timeout occurs, ERDEV contains
128 (80H).
The range for m, if specified, is
0 - 65,535 milliseconds, inclusive.
The default value is 1,000
milliseconds, if the CS option is
not used, or if m is omitted.
When m is 0, either by default or
assignment, it means the state of
the CTS line is to be ignored.
DS m Specifies the timeout period on
the Data Set Ready line (DSR). If
no signal appears on the DSR line
(the DSR line remains low) for
Option Description
────────────────────────────────────────────────────────────────────────────
(the DSR line remains low) for
more than m milliseconds, a
device timeout occurs. If a DS
timeout occurs, ERDEV contains
129 (81H).
The range for m, if specified, is
0 - 65,535 milliseconds, inclusive.
(See Note below.) The default
value is 1,000 milliseconds, if
the DS option is not used, or if
m is omitted. When m is 0, either
by default or assignment, it means
that the state of the DSR line is
to be ignored.
OP m Specifies how long the OPEN
statement waits for all
communications lines to become
Option Description
────────────────────────────────────────────────────────────────────────────
communications lines to become
active. The range for m is 0 -
65,535 milliseconds, inclusive.
The default value for m, if the
OP option is not used, is 10 times
the CD or DS timeout value,
whichever is greater. If OP is
specified, but with m omitted,
OPEN COM waits for 10 seconds.
Use a relatively large value for
the OP option compared to the CS,
DS, or CD options.
Note
Under OS/2, specifying DS0 to ignore the state of the Data Set Ready (DSR)
line does not work properly. In this case, you will have to either not
ignore the DSR line or you will have to jumper the DSR line to an active
high signal line. Refer to serial port information that specifically
pertains to your hardware, and perform any modifications at your own risk.
The argument filenum% is the number used to open the file.
The argument reclen% is effective only in random-access mode and specifies
the length of the random-access buffer (default is 128 bytes). You can use
any of the random-access I/O statements, such as GET and PUT, to treat the
device as if it were a random-access file.
The argument mode is one of the following string expressions:
╓┌──────────────────┌────────────────────────────────────────────────────────╖
Mode Description
────────────────────────────────────────────────────────────────────────────
OUTPUT Specifies sequential output mode.
Mode Description
────────────────────────────────────────────────────────────────────────────
OUTPUT Specifies sequential output mode.
INPUT Specifies sequential input mode.
RANDOM Specifies random-access mode.
If mode is omitted, it is assumed to be random-access input/output.
The OPEN COM statement performs the following steps in opening a
communications device:
■ The communications buffers are allocated and interrupts are
enabled.
■ The Data Terminal Ready line (DTR) is set high.
■ If either of the OP or DS options is nonzero, the statement
waits for the timeout period for the Data Set Ready line (DSR)
to go high. If a timeout occurs, the process goes to step 6.
■ If the RS option is not specified, the Request To Send line
(RTS) is set high.
■ If either of the OP or CD options is nonzero, the statement
waits for the timeout period for the Data Carrier Detect line
(DCD) to go high. If a timeout occurs, the process goes to step
6. Otherwise, the RS232 device has been successfully opened.
■ If there is a timeout, the open fails. The process deallocates
the buffers, disables interrupts, clears all of the control
lines, and generates the message Device timeout. In addition,
for DOS, the process sets the value of ERDEV$ to COM and sets
ERDEV to a value that indicates the signal line that timed out,
according to the following table:
╓┌────────────────────┌──────────────────────────────────────────────────────╖
ERDEV value Signal line
────────────────────────────────────────────────────────────────────────────
128 (80H) Clear to Send (CTS) timeout
ERDEV value Signal line
────────────────────────────────────────────────────────────────────────────
128 (80H) Clear to Send (CTS) timeout
129 (81H) Data Set Ready (DSR) timeout
130 (82H) Data Carrier Detect (DCD) timeout
Note
If there is not an OPEN COM statement in your program, you can reduce the
size of the .EXE file by linking your program with the stub file NOCOM.OBJ.
Example
See the COM statements programming example, which uses the OPEN COM
statement.
OPTION BASE Statement
────────────────────────────────────────────────────────────────────────────
Action
Declares the default lower bound for array subscripts.
Syntax
OPTION BASE n%
Remarks
The OPTION BASE statement is never required.
The value of n% must be either 0 or 1. The default base is 0. If the
following statement is executed, the default lowest value of an array
subscript is 1.
OPTION BASE 1
Note
The TO clause in the DIM statement provides an easier, more flexible way
to control the range of an array's subscripts. If the lower bound of an
array subscript is not explicitly set, then OPTION BASE can be used to
change the default lower bound to 1.
The OPTION BASE statement can be used only once in a module (source file)
and can appear only in the module-level code. An OPTION BASE statement
must be used before you can declare the dimensions for any arrays.
Chained programs can have an OPTION BASE statement if no arrays are passed
between them in a COMMON block, or if the specified base is identical in
the chained programs. The chained-to program inherits the OPTION BASE
value of the chaining program if OPTION BASE is omitted in the latter.
See Also
DIM, LBOUND, UBOUND
Example
The following example shows the use of OPTION BASE to override the default
base array subscript value of 0. Subscripts in array A range from 1 to 20
rather than 0 to 19.
OPTION BASE 1
DIM A(20)
PRINT "The base subscript in array A is"; LBOUND(A)
PRINT "The upper bound subscript in array A is"; UBOUND(A)
Output
The base subscript in array A is 1
The upper bound subscript in array A is 20
OUT Statement
────────────────────────────────────────────────────────────────────────────
Action
Sends a byte to a hardware I/O port.
Syntax
OUT port, data%
Remarks
The OUT statement complements the INP function, which returns the byte
read from a hardware I/O port. The OUT statement uses the following
arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
Argument Description
────────────────────────────────────────────────────────────────────────────
port A numeric expression with an
integer value between 0 and 65,535,
inclusive, that identifies the
destination hardware I/O port.
data% A numeric expression with an
integer value between 0 and 255,
inclusive, that is the data to be
sent to the port.
The OUT statement and the INP function give a BASIC program direct control
over the hardware in a system through the I/O ports. OUT and INP must be
used carefully because they directly manipulate the system hardware.
Note
The OUT statement is not available in OS/2 protected mode.
See Also
INP, WAIT
Example
The following example uses the OUT and INP statements to control the timer
and speaker to produce a note:
' Play a scale using speaker and timer.
CONST WHOLE = 5000!, QRTR = WHOLE / 4!
CONST C = 523!, D = 587.33, E = 659.26, F = 698.46, G = 783.99
CONST A = 880!, B = 987.77, C1 = 1046.5
CALL Sounds(C, QRTR): CALL Sounds(D, QRTR)
CALL Sounds(E, QRTR): CALL Sounds(F, QRTR)
CALL Sounds(G, QRTR): CALL Sounds(A, QRTR)
CALL Sounds(B, QRTR): CALL Sounds(C1, WHOLE)
SUB Sounds (Freq!, Length!) STATIC
' Ports 66, 67, and 97 control timer and speaker.
' Divide clock frequency by sound frequency
' to get number of "clicks" clock must produce.
Clicks% = CINT(1193280! / Freq!)
LoByte% = Clicks% AND &HFF
HiByte% = Clicks% \ 256
OUT 67, 182' Tell timer that data is coming.
OUT 66, LoByte%' Send count to timer.
OUT 66, HiByte%
SpkrOn% = INP(97) OR &H3' Turn speaker on by setting
OUT 97, SpkrOn%' bits 0 and 1 of PPI chip.
FOR I! = 1 TO Length!: NEXT I!' Leave speaker on.
SpkrOff% = INP(97) AND &HFC ' Turn speaker off.
OUT 97, SpkrOff%
END SUB
PAINT Statement
────────────────────────────────────────────────────────────────────────────
Action
Fills a graphics area with the color or pattern specified.
Syntax
PAINT STEP ( x!, y!) , paint , bordercolor& , background$
Remarks
The following list describes the parts of the PAINT statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
STEP Keyword indicating that
coordinates are relative to the
most recently plotted point. For
example, if the last point plotted
were (10,10), then the coordinates
referred to by STEP (4,5) would
be (4+10, 5+10) or (14,15).
( x!, y!) The coordinates where painting
begins. The point must be inside
or outside of a figure, not on the
border itself. If this point is
inside, the figure's interior is
painted; if the point is on the
outside, the background is painted.
paint A numeric or string expression. If
paint is a numeric expression,
Part Description
────────────────────────────────────────────────────────────────────────────
paint is a numeric expression,
then the number must be a valid
color attribute. The corresponding
color is used to paint the area.
If you do not specify paint, the
foreground color attribute is used.
(See the COLOR, PALETTE, and
SCREEN statements for discussions
of valid colors, numbers, and
attributes.)
If the argument paint is a string
expression, PAINT "tiles," a
process that paints a pattern
rather than a solid color. Tiling
is similar to "line styling,"
which creates dashed lines rather
than solid lines.
Part Description
────────────────────────────────────────────────────────────────────────────
bordercolor& A numeric expression that
identifies the color attribute to
use to paint the border of the
figure. When the border color is
encountered, painting of the
current line stops. If the border
color is not specified, the paint
argument is used.
background$ A string value that gives the
"background tile slice" to skip
when checking for termination of
the boundary. Painting is
terminated when adjacent points
display the paint color.
Specifying a background tile slice
allows you to paint over an
already painted area. When you
Part Description
────────────────────────────────────────────────────────────────────────────
already painted area. When you
omit background$ the default is
CHR$ (0).
Painting is complete when a line is painted without changing the color of
any pixel; in other words, when the entire line is equal to the paint color.
The PAINT statement permits coordinates outside the screen or viewport.
"Tiling" is the design of a PAINT pattern represented in string form. The
tile string is eight bits wide and up to 64 bytes long. Each byte masks
eight bits along the x axis when plotting points. The syntax for
constructing the tile mask is
A$ = CHR$( arg1)+ CHR$( arg2)+...+ CHR$( argn) PAINT ( x, y), A$
The arguments to CHR$ are numbers between 0 and 255, represented in binary
form across the x axis of the tile. There can be up to 64 of these CHR$
elements; each generates an image not of the assigned character, but of the
bit arrangement of the code for that character. For example, the decimal
number 85 is binary 01010101; the graphic image line on a black-and-white
screen generated by CHR$(85) is an eight-pixel line, with even-numbered
points white and odd-numbered points black. That is, each bit equal to 1
turns the associated pixel on and each bit equal to 0 turns the associated
bit off in a black-and-white system. The ASCII character CHR$(85), which is
U, is not displayed in this case.
When supplied, background$ defines the "background tile slice" to skip when
checking for boundary termination. You cannot specify more than two
consecutive bytes that match the tile string in the background tile slice.
If you specify more than two consecutive bytes, BASIC generates an error
message Illegal function call.
Tiling also can be done to produce various patterns of different colors. See
Chapter 5, "Graphics" in the Programmer's Guide for a complete description
of how to do tiling.
See Also
CHR$, CIRCLE, DRAW, LINE, SCREEN Statement
Example
The following example uses PAINT to create a magenta fish with a cyan tail:
CONST PI = 3.1415926536
CLS' Clear screen.
SCREEN 1
CIRCLE (190, 100), 100, 1, , , .3' Outline fish body in cyan.
CIRCLE (265, 92), 5, 1, , , .7' Outline fish eye in cyan.
PAINT (190, 100), 2, 1' Fill in fish body with magenta.
LINE (40, 120)-STEP (0, -40), 2 ' Outline tail in magenta.
LINE -STEP (60, 20), 2
LINE -STEP (-60, 20), 2
PAINT (50, 100), 1, 2' Paint tail cyan.
CIRCLE (250,100),30,0,PI*3/4,PI* 5/4,1.5' Draw gills in black.
FOR Y = 90 TO 110 STEP 4
LINE (40, Y)-(52, Y), 0' Draw comb in tail.
NEXT
PALETTE, PALETTE USING Statements
────────────────────────────────────────────────────────────────────────────
Action
Change one or more colors in the palette.
Syntax
PALETTE attribute%, color&
PALETTE USING array-name ( array-index)
Remarks
The PALETTE and PALETTE USING statements use the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
attribute% The palette attribute to be
changed.
color& The display color number to be
assigned to the attribute. The
color& value must be a
long-integer expression for the
IBM Video Graphics Array adapter
(VGA) and IBM Multicolor Graphics
Array adapter (MCGA) in screen
Argument Description
────────────────────────────────────────────────────────────────────────────
Array adapter (MCGA) in screen
modes 11 to 13. Integer or
long-integer expressions can be
used with the IBM Enhanced
Graphics Adapter (EGA).
array-name An array that contains more than
one display color. It must be a
long-integer array for VGA and
MCGA adapters in screen modes 11
to 13. Otherwise, it can be either
an integer or long-integer array.
array-index The index of the first array
element to use in setting the
palette.
The arguments array-name and
array-index are used to change
Argument Description
────────────────────────────────────────────────────────────────────────────
array-index are used to change
more than one palette assignment
with a single PALETTE USING
statement.
The PALETTE statement works only on systems equipped with the EGA, VGA, or
MCGA adapters. The PALETTE statement is not supported in screen modes 3 or
4.
The PALETTE statement provides a way of mapping display colors (the actual
binary values used by the adapter) to color attributes (a smaller set of
values).
When a program enters a screen mode, the attributes are set to a series of
default color values. (See the SCREEN statement for a list of the default
colors.) In the EGA, VGA, and MCGA adapters, the default values have been
selected so the display shows the same colors, even though the EGA uses
different color values.
With the PALETTE statement you can assign different colors to the
attributes. Changing the display color assigned to an attribute immediately
changes those colors currently displayed on the screen associated with that
attribute.
For example, assume that the current palette contains colors 0, 1, 2, and 3
in the four attributes numbered 0, 1, 2, and 3. The following DRAW
statement selects attribute 3, and draws a line of 100 pixels using the
display color associated with attribute 3, in this case also 3:
DRAW "C3L100"
If the following statement is executed, the color associated with attribute
3 is changed to color 2:
PALETTE 3,2
All text or graphics currently on the screen displayed using attribute 3,
including the line that is 100 pixels long, are instantaneously changed to
color 2. Text or graphics subsequently dis-played with attribute 3 also are
displayed in color 2. The new palette of colors contains 0, 1, 2, and 2. A
PALETTE statement with no arguments sets the palette back to the default
color values.
With PALETTE USING, all entries in the palette can be modified in one
statement. Each attribute in the palette is assigned a corresponding color
from the array.
The dimensions for the array must be large enough to set all the palette
entries after array-index. For example, if you are assigning colors to a
palette with 16 attributes and the array-index argument is 5 (the first
array element to use in resetting the palette), then the dimensions for the
array must be declared to hold at least 20 elements (because the number of
elements from 5 to 20, inclusive, is 16):
DIM PAL%(20)
.
.
.
PALETTE USING PAL%(5)
Note that a color& argument of -1 in the array leaves the attribute
unchanged in the palette. All other negative numbers are invalid values for
color.
Attribute 0 is always the screen background color. Under a common initial
palette setting, points colored with the attribute 0 appear black on the
display screen. Using the PALETTE statement, you could, for example, change
the mapping of attribute 0 from black to white. You can also use the COLOR
statement to change the screen background color in modes 1 and 7 through 10.
The 64 EGA colors are derived from four levels each of red, green, and blue.
For example, black is composed of red, green, and blue levels of (0,0,0),
bright white is (3,3,3), dark gray is (1,1,1), and so on. The best way to
see the Microsoft BASIC color code (0-63) associated with each combination
of red, green, and blue levels is to run the following program:
' Display the EGA color codes 1 through 63
' using color code 0 (black) as background.
DEFINT A-Z
SCREEN 9 ' Establish EGA screen mode.
' Display a set of nine color bars.
FOR ColorCode% = 1 TO 9
LINE (((ColorCode% * 64) - 24), 40)-STEP(60, 140), ColorCode%, BF
NEXT ColorCode%
' Display seven sets of nine color bars.
' A new set is displayed each time user presses a key.
FOR Set% = 0 TO 6
FOR ColorBar% = 1 TO 9
DisplayCode% = (Set% * 9) + ColorBar%
LOCATE 15, (ColorBar% * 8)
PRINT DisplayCode%
PALETTE ColorBar%, DisplayCode%
NEXT ColorBar%
SLEEP
NEXT Set%
END
The following table lists attribute and color ranges for various adapter
types and screen modes. See the SCREEN statement for the list of colors
available for various screen modes, monitor, and graphics-adapter
combinations.
╓┌───────────┌───────────┌───────────┌───────────┌───────────┌───────────────╖
Screen Monitor Adapter Attribute Color PALETTE
mode attached range range supported
────────────────────────────────────────────────────────────────────────────
0 Monochrome MDPA 0 - 15 No
Monochrome EGA 0 - 15 0 - 2 Yes
Color CGA 0 - 15 No
Color/Enha EGA 0 - 15 0 - 15 / 0 Yes
nced1 - 63
Analog VGA 0 - 15 0 - 63 Yes
Color/Anal MCGA 0 - 15 0 - 63 No
og
1 Color CGA 0 - 3 0 - 152 No
Screen Monitor Adapter Attribute Color PALETTE
mode attached range range supported
────────────────────────────────────────────────────────────────────────────
Color/Enha EGA 0 - 3 0 - 15 Yes
nced1
Analog VGA 0 - 3 0 - 15 Yes
Color/Anal MCGA 0 - 1 0 - 15 No
og
2 Color CGA 0 - 1 No
Color/Enha EGA 0 - 1 0 - 15 Yes
nced1
Analog VGA 0 - 1 0 - 15 Yes
Color/Anal MCGA 0 - 1 0 - 15 No
og
Screen Monitor Adapter Attribute Color PALETTE
mode attached range range supported
────────────────────────────────────────────────────────────────────────────
og
3 Monochrome HGC 0 - 1 No
4 Color/Enha OCGA/ 0 - 1 0 - 153 No
nced OEGA/ OVGA
7 Color/Enha EGA 0 - 15 0 - 15 Yes
nced1
VGA 0 - 15 0 - 15 Yes
8 Color/Enha EGA 0 - 15 0 - 15 Yes
nced1
VGA 0 - 15 0 - 15 Yes
9 Enhanced1 EGA4 0 - 3 0 - 63 Yes
Screen Monitor Adapter Attribute Color PALETTE
mode attached range range supported
────────────────────────────────────────────────────────────────────────────
9 Enhanced1 EGA4 0 - 3 0 - 63 Yes
Enhanced1 EGA5 0 - 15 0 - 63 Yes
Analog VGA 0 - 16 0 - 63 Yes
10 Monochrome EGA 0 - 3 0 - 8 Yes
Analog VGA 0 - 3 0 - 8 Yes
11 Analog VGA 0 - 1 0 - Yes
262,1436
Analog MCGA 0 - 1 0 - Yes
262,1436
12 Analog VGA 0 - 15 0 - Yes
262,1436
Screen Monitor Adapter Attribute Color PALETTE
mode attached range range supported
────────────────────────────────────────────────────────────────────────────
262,1436
13 Analog VGA 0 - 255 0 - Yes
262,1436
Analog MCGA 0 - 255 0 - Yes
262,1436
1 IBM Enhanced Color Display.
2 Color range available for attribute 0 only.
3 Color range available for attribute 1 only.
4 With 64K of EGA memory.
5 With more than 64K of EGA memory.
6 Range of display colors is actually from 0 to 4,144,959, but only
262,144 of these can be displayed.
To calculate a VGA color value, select the intensities of red, green, and
blue. The intensity of a color is a number from 0 (low intensity) to 63
(high intensity). Then use the following formula to calculate the actual
color number:
color number = 65,536 * blue + 256 * green + red
This formula yields integer values from 0 to 4,144,959, but because there
are gaps in the range of color numbers, you should use the formula rather
than just select a number.
When used with the IBM Analog Monochrome Monitor, the VGA color values are
converted to a gray-scale value by taking a weighted sum of the red, blue,
and green intensities:
gray value = 11% blue + 59% green + 30% red
For example, if the blue, green, and red intensities are 45, 20, and 20, the
gray intensity value calculation would be gray value = (.11 * 45) + (.59 *
20) + (.30 * 20) = 22. The fractional part of the result is dropped.
See Also
COLOR, SCREEN Statement
Example
The following example illustrates the use of the PALETTE and PALETTE USING
statements:
DEFINT A-Z
DIM SHARED PaletteArray(15)
CONST ASPECT = 1 / 3
SCREEN 8' 640 x 200, 16 color resolution.
' Initialize PaletteArray.
FOR I = 0 TO 15
PaletteArray(I) = I
NEXT I
' Draw and paint concentric ellipses.
FOR ColorVal = 15 TO 1 STEP -1
Radius = 20 * ColorVal
CIRCLE (320, 100), Radius, ColorVal, , , ASPECT
PAINT (320, 100), ColorVal
NEXT
' Shift the palette until a key is pressed.
DO
FOR I = 1 TO 15
PaletteArray(I) = (PaletteArray(I) MOD 15) + 1
NEXT I
PALETTE USING PaletteArray(0)
' Map the black background to a random color.
PALETTE 0, PaletteArray(INT(RND * 15))
LOOP WHILE INKEY$ = ""
PCOPY Statement
────────────────────────────────────────────────────────────────────────────
Action
Copies one video memory page to another.
Syntax
PCOPY sourcepage%, destinationpage%
Remarks
The PCOPY statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
sourcepage% A numeric expression with an
integer value between 0 and n
that identifies a video memory
page to be copied.
Argument Description
────────────────────────────────────────────────────────────────────────────
destinationpage% A numeric expression with an
integer value between 0 and n
that identifies the video memory
page to be copied to.
The value of n is determined by the current size of video memory and the
current screen mode. The number of video memory pages available depends on
the current screen mode, the graphics adapter, and how much screen memory is
available with the adapter.
Note
Multiple video pages are not available in OS/2 protected mode, so the PCOPY
statement has no effect.
See the SCREEN statement for more information about the number of pages
available in different modes
See Also
CLEAR, SCREEN Statement
Example
See the SCREEN statement programming example, which uses the PCOPY
statement.
PEEK Function
────────────────────────────────────────────────────────────────────────────
Action
Returns byte value stored at a specified memory location. Complements the
POKE statement.
Syntax
PEEK( address)
Remarks
The returned value is an integer between 0 and 255, inclusive. The argument
address is a value between 0 and 65,535, inclusive. The argument address
is treated as the offset from the current default segment (as set by the
DEF SEG statement).
If address is a single- or double-precision floating-point value, or a long
integer, it is converted to a 2-byte integer.
When using PEEK to return a byte from a far-string array, use the SSEG and
SADD functions to obtain the current segment and offset. For example:
DEF SEG = SSEG(a$) ' Set current segment address to address of a$.
StringOffset = SADD(a$) ' Determine string's location within segment.
PEEK(StringOffset)' Return the byte stored at this location.
Direct string manipulation with PEEK should be used cautiously, because
BASIC moves string locations during run time.
PEEK and Expanded Memory Arrays
Do not use PEEK to return a byte from an expanded memory array. If you
start QBX with the /Ea switch, any of these arrays may be stored in expanded
memory:
■ Numeric arrays less than 16K in size.
■ Fixed-length string arrays less than16K in size.
■ User-defined-type arrays less than 16K in size.
If you want to use PEEK to return a byte from an array, first start QBX
without the /Ea switch. (Without the /Ea switch, no arrays are stored in
expanded memory.)
For more information on using expanded memory, see "Memory Management for
QBX" in Getting Started.
Note
When programming with OS/2 protected mode, note that any address referred to
by PEEK must be readable. If PEEK refers to an address for which your
process does not have read permission, the operating system may generate a
protection exception, or BASIC may generate the error message Permission
denied.
See Also
DEF SEG; POKE; SADD; SSEG; SSEGADD; VARPTR, VARSEG; VARPTR$
Example
See the DEF SEG statement programming example, which uses the PEEK
statement.
PEN Function
────────────────────────────────────────────────────────────────────────────
Action
Returns lightpen status.
Syntax
PEN( n%)
Remarks
The argument n% is an integer value between 0 and 9, inclusive, that
specifies what information is to be returned about the status of the
lightpen.
Note
The PEN function does not work when the mouse driver is enabled because the
mouse driver uses the PEN function's BIOS calls. Use mouse function 14 to
disable the driver's lightpen emulation. Mouse function 13 turns emulation
back on. See your mouse manual for more information.
The following list describes the values for n% and the corresponding values
returned by PEN:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Value returned
────────────────────────────────────────────────────────────────────────────
0 Whether the pen was down since the
last function call (-1 if yes, 0
if no).
1 The x coordinate of the last pen
press.
2 The y coordinate of the last pen
press.
3 The current pen switch status (-1
if down, 0 if up).
4 The x coordinate where the pen
last left the screen.
Argument Value returned
────────────────────────────────────────────────────────────────────────────
5 The y coordinate where the pen
last left the screen.
6 The character row of the last pen
press.
7 The character column of the last
pen press.
8 The character row where the pen
last left the screen.
9 The character column where the pen
last left the screen.-
The light-pen coordinate system is identical to the current graphics screen
mode, without viewport or window considerations.
Note
The PEN function is not available in OS/2 protected mode.
See Also
PEN Statements
Example
See the ON PEN statement programming example, which uses the PEN function.
PEN Statements
────────────────────────────────────────────────────────────────────────────
Action
Enable, disable, or suspend lightpen-event trapping.
Syntax
PEN ON
PEN OFF
PEN STOP
Remarks
The PEN ON statement enables lightpen-event trapping. A lightpen event
occurs whenever the lightpen is activated by pressing the tip to the screen
or pressing the touch ring. If a lightpen event occurs after a PEN ON
statement, the routine specified in the ON PEN statement is executed.
The PEN OFF statement disables lightpen-event trapping. No trapping takes
place until a PEN ON statement is executed. Events occurring while
trapping is off are ignored.
The PEN STOP statement suspends lightpen-event trapping. No trapping takes
place until a PEN ON statement is executed. Events occurring while
trapping is suspended are remembered and processed when the next PEN ON
statement is executed. However, remembered events are lost if PEN OFF is
executed.
When a lightpen-event trap occurs (that is, the GOSUB is performed), an
automatic PEN STOP is executed so that recursive traps cannot take place.
The RETURN statement from the trapping routine automatically performs a
PEN ON statement unless an explicit PEN OFF was performed inside the
routine.
A PEN ON statement must be executed before you use the PEN function. If a
Pen function is executed when the lightpen is off, BASIC generates the error
message Illegal function call.
Note
The lightpen requires an IBM Color Graphics Adapter.
The PEN statements are not available for OS/2 protected mode.
For more information, see Chapter 9, "Event Handling" in the Programmer's
Guide.
See Also
ON event
Example
The following example uses the PEN statements and the PEN function to
enable and display current lightpen status (up or down) and position (x and
y coordinates). The ON PEN statement passes control to the PenReport
routine when a lightpen event occurs.
' Note: Do not run this program with your mouse driver enabled.
CLS ' Clear screen.
COLOR 0, 7 ' Set black on white.
CLS ' Clear screen.
PEN ON ' Enable lightpen
ON PEN GOSUB PenReport
DO
LOCATE 23, 12
PRINT "Press the lightpen against the screen to see a report."
LOCATE 24, 17
PRINT " Press the Spacebar to exit the program. ";
LOOP UNTIL INKEY$ = " "
PEN OFF ' Disable lightpen.
COLOR 7, 0 ' Set back to black on white.
CLS ' Clean up the screen.
END
PenReport:
DO
P = PEN(3)
' Report lightpen status and get X and Y position.
LOCATE 10, 27
PRINT "A Pen event has occurred."
LOCATE 24, 17
PRINT "Press ANY key to exit the lightpen report.";
LOCATE 12, 30
PRINT "lightpen is ";
IF P THEN
PRINT "Down"
X = PEN(4): Y = PEN(5)
ELSE
PRINT "Up "
X = 0: Y = 0
END IF
' Report the X and Y position.
LOCATE 14, 22
PRINT "X Position ="; X; " "
LOCATE 14, 40
PRINT "Y Position ="; Y; " "
LOOP WHILE INKEY$ = ""
RETURN
PLAY Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the number of notes currently in the background-music queue.
Syntax
PLAY ( n)
Remarks
The argument n is a dummy argument and can be any numeric value.
PLAY( n) will return 0 when music is running in the foreground.
The PLAY function is not available for OS/2 protected mode.
See Also
ON event, PLAY Statements (Event Trapping), PLAY Statement (Music)
Example
The following example plays continuous music by calling an event-handling
routine when the background music buffer goes from three to two notes:
CLS
' Call routine Replay when the music buffer goes
' from 3 to 2 notes.
ON PLAY(3) GOSUB Replay
' Turn on event trapping for PLAY.
PLAY ON
' Define a string containing the melody.
FElise$ = "o3 L8 E D+ E D+ E o2 B o3 D C L2 o2 A"
PLAY "MB X" + VARPTR$(FElise$)
' Suspend event trapping until next PLAY ON but remember
' events that occur while event trapping is disabled.
PLAY STOP
' Introduce a variable-length delay.
LOCATE 23, 1: PRINT "Press any key to continue."
DO
LOOP WHILE INKEY$ = ""
' Re-enable play-event trapping, remembering that a play event
' has occurred.
PLAY ON
LOCATE 23, 1: PRINT "Press any key to stop. "
' Loop until a key is pressed.
DO
GOSUB BackGround
LOOP WHILE INKEY$ = ""
' Disable play-event processing.
PLAY OFF
' Count down to 0 notes in the queue.
DO
GOSUB BackGround
LOOP UNTIL NoteCount = 0
END
' Play event-handling routine.
Replay:
' Increment and print a counter each time.
Count% = Count% + 1
LOCATE 3, 1: PRINT "Replay routine called"; Count%; "time(s)";
' Play it again to fill the buffer.
PLAY "MB X" + VARPTR$(FElise$)
RETURN
' Background music queue reporting routine.
BackGround:
' Get a note count.
NoteCount = PLAY(0)
LOCATE 1, 1
PRINT "Background queue notes remaining --> "; NoteCount
' Loop until Notecount changes or equals 0.
DO
LOOP UNTIL NoteCount <> PLAY(0) OR NoteCount = 0
RETURN
PLAY Statements (Event Trapping)
────────────────────────────────────────────────────────────────────────────
Action
Enable, disable, and suspend play-event trapping.
Syntax
PLAY ON
PLAY OFF
PLAY STOP
Remarks
The PLAY ON statement enables play-event trapping. (A play event occurs
when the number of notes in the background music queue drops below the limit
you set with the ON PLAY statement.) If a play event occurs after a PLAY
ON statement, the routine specified in the ON PLAY statement is executed.
The PLAY OFF statement disables play-event trapping. No trapping takes
place until a PLAY ON statement is executed. Events occurring while
trapping is off are ignored.
PLAY STOP suspends play-event trapping. No trapping takes place until a
PLAY ON statement is executed. Events occurring while trapping is suspended
are remembered and processed when the next PLAY ON statement is executed.
However, remembered events are lost if PLAY OFF is executed.
When a play-event trap occurs (that is, the GOSUB is performed), an
automatic PLAY STOP is executed so that recursive traps cannot take place.
The RETURN operation from the trapping routine automatically executes a
PLAY ON statement unless an explicit PLAY OFF was performed inside the
routine.
For more information, see Chapter 9, "Event Handling" in the Programmer's
Guide.
Note
The PLAY statements (event trapping) are not available for OS/2 protected
mode.
See Also
ON event, PLAY Function, PLAY Statements (Music)
Example
See the PLAY function programming example, which uses the PLAY ON
statement.
PLAY Statement (Music)
────────────────────────────────────────────────────────────────────────────
Action
Plays music as specified by a string.
Syntax
PLAY commandstring$
Remarks
The commandstring$ argument is a string expression that contains one or
more music commands listed later in this entry.
The PLAY statement uses a concept similar to DRAW in that it embeds a
music macro language (described below) in one statement. A set of commands,
used as part of the PLAY statement, specifies a particular action.
The VARPTR$( variablename) form for variables must be used with DRAW and
PLAY (music) statements in BASIC to execute substrings that contain
variables. BASICA supports both the VARPTR$ syntax and the syntax
containing just the variable name. For example, consider these BASICA
statements:
PLAY "XA$"
PLAY "O = I"
For BASIC programs, those statements should be written like this:
PLAY "X" + VARPTR$(A$)
PLAY "O=" + VARPTR$(I)
The commandstring$ music commands are described as follows:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Command Action
────────────────────────────────────────────────────────────────────────────
Octave command
o n Sets the current octave. There are
seven octaves, numbered 0-6.
> Increases octave by 1. Octave
cannot go beyond 6.
< Decreases octave by 1. Octave
cannot drop below 0.
Tone command
Command Action
────────────────────────────────────────────────────────────────────────────
A - G Plays a note in the range A - G.
The number sign (#) or the plus
sign (+) after a note specifies
sharp; a minus sign (-) specifies
flat.
N n Plays note n. The range for n is
0 - 84 (in the seven possible
octaves, there are 84 notes); an
n value of 0 means a rest.
Duration command
L n Sets the length of each note. L4
is a quarter note, L1 is a whole
note, etc. The range for n is 1 -
Command Action
────────────────────────────────────────────────────────────────────────────
note, etc. The range for n is 1 -
64. The length can also follow the
note when a change of length only
is desired for a particular note.
For example, A16 can be equivalent
to L16A.
MN Sets "music normal" so that each
note will play 7/8 of the time
determined by the length (L).
ML Sets "music legato" so that each
note will play the full period set
by length (L).
MS Sets "music staccato" so that each
note will play 3/4 of the time
determined by the length (L).
Command Action
────────────────────────────────────────────────────────────────────────────
Tempo command
P n Specifies a pause, ranging from 1
to 64. This option corresponds to
the length of each note, set with
L n.
T n Sets the "tempo," or the number of
L4 quarter notes in one minute.
The range for n is 32-255. The
default for n is 120.
Because of the slow
clock-interrupt rate, some notes
will not play at higher tempos
(L64 at T255, for example).
Command Action
────────────────────────────────────────────────────────────────────────────
(L64 at T255, for example).
Mode command
MF Sets music ( PLAY statement) and
SOUND to run in the foreground.
That is, each subsequent note or
sound will not start until the
previous note or sound has
finished. This is the default
setting.
MB Music ( PLAY statement) and SOUND
are set to run in the background.
That is, each note or sound is
placed in a buffer, allowing the
BASIC program to continue
Command Action
────────────────────────────────────────────────────────────────────────────
BASIC program to continue
executing while the note or sound
plays in the background. The
maximum number of notes that can
be played in the background at one
time is 32.
Suffix
# or + Follows a specified note and turns
it into a sharp.
- Follows a specified note and turns
it into a flat..
. A period after a note causes the
note to play one-and-a-half times
Command Action
────────────────────────────────────────────────────────────────────────────
note to play one-and-a-half times
the length determined by L*T
(length times tempo). The period
has the same meaning as in a
musical score. Multiple periods
can appear after a note. Each
period adds a length equal to
one-half the length of the
previous period. For example, the
command A . plays 1 + 1/2, or 3/2
times the length; A.. plays 1 +
1/2 + 1/4, or 7/4 times the length.
Periods can appear after a pause
(P). In this case, the pause
length is scaled in the same way
notes are scaled.
Command Action
────────────────────────────────────────────────────────────────────────────
Substring command
"X" + VARPTR$(string) Executes a substring. This
powerful command enables you to
execute a second substring from a
string. You can have one string
expression execute another, which
executes a third, and so on.
Note
The PLAY statement is not available in OS/2 protected mode.
See Also
BEEP, ON event, PLAY Function, PLAY Statements (Event Trapping), SOUND
Example
See the PLAY function programming example, which uses the PLAY statement.
PMAP Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the window coordinate equivalent to a specified viewport coordinate,
or the viewport coordinate equivalent to a specified window coordinate.
Syntax
PMAP ( expression#, n%)
Remarks
The argument expression# specifies the known coordinate, either an x
coordinate or y coordinate, in the window or in the viewport. The argument
n% specifies the mapping function and can have one of the four following
values:
╓┌──────────────────────┌──────────┌─────────────────────────────────────────╖
If expression is n must be Returns:
────────────────────────────────────────────────────────────────────────────
Window x coordinate 0 Viewport x coordinate
Window y coordinate 1 Viewport y coordinate
Viewport x coordinate 2 Window x coordinate
Viewport y coordinate 3 Window y coordinate
The four PMAP functions allow you to find equivalent point locations
between the window coordinates created with the WINDOW statement and the
absolute screen coordinates or viewport coordinates as defined by the VIEW
statement.
If no VIEW statement has been executed, or the most recently executed VIEW
statement has no arguments, the viewport coordinates are equivalent to the
absolute screen coordinates established by the most recently executed
SCREEN statement.
See Also
POINT, VIEW, WINDOW
Example
See the WINDOW statement programming example, which uses the PMAP
function.
POINT Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the current horizontal or vertical position of the graphics cursor,
or the color of a specified pixel.
Syntax 1
POINT ( x%,y%)
Syntax 2
POINT ( number%)
Remarks
The coordinates x% and y% refer to the viewport coordinates of the pixel
being evaluated by the POINT function; POINT returns the color number of
the indicated pixel. If the specified pixel is out of range, POINT returns
the value -1.
POINT with the argument number% allows the user to retrieve the current
graphics-cursor coordinates, as described in the following table:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Value returned
────────────────────────────────────────────────────────────────────────────
0 The current viewport x coordinate.
1 The current viewport y coordinate.
2 The current window x coordinate.
This returns the same value as the
POINT(0) function if the WINDOW
statement has not been used.
3 The current window y coordinate.
This returns the same value as the
POINT(1) function if the WINDOW
statement has not been used.
Argument Value returned
────────────────────────────────────────────────────────────────────────────
statement has not been used.
See Also
Pmap, Screen Statement, VIEW, Window
Example
The following example redraws an ellipse drawn with the CIRCLE statement,
using POINT to find the border of the ellipse by testing for a change in
color:
DEFINT X-Y
INPUT "Enter angle of tilt in degrees (0 to 90): ",Ang
SCREEN 1' Medium resolution screen.
Ang = (3.1415926# / 180) * Ang' Convert degrees to radians.
Cs = COS(Ang) : Sn = SIN(Ang)
CIRCLE (45, 70), 50, 2, , , 2' Draw ellipse.
PAINT (45, 70), 2 ' Paint interior of ellipse.
FOR Y = 20 TO 120
FOR X = 20 TO 70
' Check each point in rectangle enclosing ellipse.
IF POINT(X, Y) <> 0 THEN
' If the point is in the ellipse, plot a corresponding
' point in the "tilted" ellipse.
Xnew = (X * Cs - Y * Sn) + 200 : Ynew = (X * Sn + Y * Cs)
PSET(Xnew, Ynew), 2
END IF
NEXT
NEXT
END
POKE Statement
────────────────────────────────────────────────────────────────────────────
Action
Writes a byte value into a specified memory location.
Syntax
POKE address, byte%
Remarks
The POKE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
address An offset into the memory segment
specified by the current default
segment (as set by the DEF SEG
Argument Description
────────────────────────────────────────────────────────────────────────────
segment (as set by the DEF SEG
statement). The value of address
is between 0 and 65,535, inclusive.
byte% The data byte to be written into
the memory location. The argument
byte% is an integer value between
0 and 255, inclusive. Any value
for byte% that must be
represented in more than one byte
(for instance, a long integer or
any real number) is accepted;
however, only the low order byte
is used. The value of any high
order bytes is ignored.
If address is a single- or double-precision floating-point value, or a long
integer, it is converted to a 2-byte integer.
The POKE statement complements the PEEK function.
Before using POKE to directly manipulate data stored in far memory, use the
DEF SEG statement to set the current segment address. For example:
DEF SEG = SSEG(a$)' Set current segment address to address of a$.
Offset1 = SADD(a$)' Determine string's location within the segment.
' Write the byte stored in:
POKE Offset1, PEEK(Offset2)
Note
BASIC moves string locations during run time. Therefore, the DEF SEG
statement must be executed immediately before using the POKE statement.
POKE and Expanded Memory Arrays
Do not use POKE to manipulate expanded memory arrays. If you start QBX with
the /Ea switch, any of these arrays may be stored in expanded memory:
■ Numeric arrays less than 16K in size.
■ Fixed-length string arrays less than 16K in size.
■ User-defined-type arrays less than 16K in size.
If you want to use POKE to manipulate an array, first start QBX without the
/Ea switch. (Without the /Ea switch, no arrays are stored in expanded
memory.)
For more information on using expanded memory, see "Memory Management for
QBX" in Getting Started.
Any address referred to by POKE in OS/2 protected mode must be open for
writing. If POKE refers to a memory address for which your process does not
have write permission, the operating system may generate a protection
exception, or BASIC may generate the error message Permission denied.
Warning
Use POKE carefully. If used incorrectly, it can cause BASIC or the
operating system to fail.
See Also
DEF SEG; PEEK; VARPTR, VARSEG; VARPTR$
Example
See the DEF SEG statement programming example, which uses the POKE
statement.
POS Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the current horizontal position (column) of the text cursor.
Syntax
POS( numeric-expression)
Remarks
If the screen cursor is in the leftmost column, this function returns a
value of 1. To return the current vertical-line position of the cursor, use
the CSRLIN function. The argument numeric-expression can be any numeric
expression; while it passes no information, it is required to maintain
consistent BASIC function syntax.
See Also
CSRLIN, LPOS
Example
The following example uses POS to start a new line after every 40
characters:
CLS ' Clear screen.
PRINT "This program starts a new line after every 40"
PRINT "characters you type. Press Ctrl+C to end."
PRINT
DO
DO WHILE POS(0) < 41 ' Stay on same line until 40 characters
DO ' printed.
Char$ = INKEY$
LOOP WHILE Char$ = ""
' If input is key combination CTRL-C then end; otherwise,
' print the character.
IF ASC(Char$) = 3 THEN END ELSE PRINT Char$;
LOOP
PRINT ' Print a new line.
LOOP
PRESET Statement
────────────────────────────────────────────────────────────────────────────
Action
Draws a specified point on the screen.
Syntax
PRESET STEP( x%, y%) , color&
Remarks
The following list describes the parts of the PRESET statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
STEP Indicates that x% and yc% are
relative, not absolute. The
coordinates are treated as
distances from the most recent
graphics cursor location, not
distances from the (0,0) screen
coordinate.
For example, if the most recent
graphics cursor location were
Part Description
────────────────────────────────────────────────────────────────────────────
graphics cursor location were
(10,10), PRESET STEP (10,5) would
draw a point at (20,15).
x% The x coordinate of the pixel that
is to be set.
y% The y coordinate of the pixel that
is to be set.
color& The color attribute for the
specified pixel.
The valid range of screen coordinate values and color values depends on the
screen mode established by the most recently executed SCREEN statement. If
a coordinate is outside the current viewport, no action is taken, nor is an
error message generated.
If you use PRESET without color&, the background color is selected. In
contrast, if you use PSET without color&, the foreground color is
selected. Otherwise, the two statements work exactly the same.
See Also
PSET
Example
The following example uses PSET and PRESET to draw a line 20 pixels long,
then move the line across the screen from left to right:
SCREEN 1 : COLOR 1,1 : CLS
FOR I = 0 TO 299 STEP 3
FOR J = I TO 20 + I
PSET (J, 50), 2' Draw the line in new location.
NEXT
FOR J = I TO 20 + I
PRESET (J, 50) ' Erase the line.
NEXT
NEXT
PRINT Statement
────────────────────────────────────────────────────────────────────────────
Action
Outputs data to the screen.
Syntax
PRINT expressionlist {;|,}
Remarks
If expressionlist is omitted, a blank line is displayed. If expressionlist
is included, the values of its expressions are printed on the screen.
The PRINT statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
expressionlist The values that are displayed on
the screen. The argument
expressionlist can contain numeric
or string expressions. String
Argument Description
────────────────────────────────────────────────────────────────────────────
or string expressions. String
literals must be enclosed in
quotation marks.
{;|,} Determines the screen location of
the text cursor for the next
screen input or output statement:
a semicolon means the text cursor
is placed immediately after the
last character displayed; a comma
means the text cursor is placed at
the start of the next print zone.
The PRINT statement supports only elementary BASIC data types (integers,
long integers, single-precision real numbers, double-precision real numbers,
currency, and strings). To print information from a record, use individual
record-element names in the PRINT statement, as in the following code
fragment:
TYPE MyType
Word AS STRING * 20
Count AS LONG
END TYPE
DIM Myrec AS MyType
PRINT Myrec.Word
Item-Format Rules
A printed number always is followed by a space. If the number is positive,
it also is preceded by a space; if the number is negative, it is preceded by
a minus sign (-). If a single-precision number can be expressed as seven or
fewer digits with no loss of accuracy, then it is printed in fixed-point
format; otherwise, floating-point format is used. For example, the number
1.1E-6 is output displayed as .0000011, but the number 1.1E-7 is output as
1.1E-7.
If a double-precision number can be expressed with 15 or fewer digits and no
loss of accuracy, it is printed in fixed-point format; otherwise,
floating-point format is used. For example, the number 1.1D-14 is displayed
as .000000000000011, but the number 1.1D-15 is output as 1.1D-15.
Print-Line Format Rules
The print line is divided into print zones of 14 spaces each. The position
of each printed item is determined by the punctuation used to separate the
items in expressionlist: a comma makes the next value print at the start of
the next zone; a semicolon makes the next value print immediately after the
last value. Using one or more spaces or tabs between expressions has the
same effect as using a semicolon.
If a comma or a semicolon terminates the list of expressions, the next
PRINT statement to execute prints on the same line, after spacing
accordingly. If the expression list ends without a comma or a semicolon, a
carriage-return-and-line-feed sequence is printed at the end of the line. If
the printed line is wider than the screen width, BASIC goes to the next
physical line and continues printing.
See Also
PRINT #, PRINT USING, WIDTH
Examples
The following examples show the use of commas and semicolons with PRINT.
First is an example of using commas in a PRINT statement to print each
value at the beginning of the next print zone:
CLS ' Clear screen.
X = 5
PRINT X + 5, X - 5, X * (-5), X ^ 5
END
Output
10 0 -25 3125
In the second example, the semicolon at the end of the first PRINT
statement makes the first two PRINT statements display output on the same
line. The last PRINT statement prints a blank line before the next prompt.
CLS ' Clear screen.
DO
INPUT "Input X (type 0 to quit): ", X
IF X = 0 THEN
EXIT DO
ELSE
PRINT X; "squared is"; X ^ 2; "and";
PRINT X; "cubed is"; X^3
PRINT
END IF
LOOP
Output
Input X (type 0 to quit): 9
9 squared is 81 and 9 cubed is 729
Input X (type 0 to quit): 21
21 squared is 441 and 21 cubed is 9261
Input X (type 0 to quit): 0
In the third example, the semicolons in the PRINT statement print each
value immediately after the preceding value. Note that a space always
follows a number and precedes a positive number.
CLS ' Clear screen.
FOR X = 1 TO 5
J = J + 5
K = K + 10
PRINT J; K;
NEXT X
Output
5 10 10 20 15 30 20 40 25 50
PRINT # Statement
────────────────────────────────────────────────────────────────────────────
Action
Writes data to a sequential device or file.
Syntax
PRINT # filenumber%, USING formatstring$; expressionlist{,|;}
Remarks
The PRINT # statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number of an open sequential
file.
Argument Description
────────────────────────────────────────────────────────────────────────────
file.
formatstring$ Specifies the exact format in
which values are written to the
file; described under PRINT
USING.
expressionlist Numeric or string expressions to
be written to the file.
Spaces, commas, and semicolons in expressionlist have the same meaning as
they have in a PRINT statement.
If you omit expressionlist, the PRINT # statement prints a blank line in
the file.
PRINT # works like PRINT and writes an image of the data to the file, just
as the data would be displayed on the terminal screen. For this reason, be
careful to delimit the data so it is output correctly. If you use commas as
delimiters, the blanks between print fields are also written to the file.
For more information, see "File and Device I/O" in the Programmer's Guide.
See Also
OPEN (File I/O), PRINT, PRINT USING, WRITE #
Example
The following example shows the effects of using data delimiters with PRINT
#:
CONST A$ = "CAMERA, AUTOFOCUS", B$ = "September 20, 1989", C$ = "42"
Q$ = CHR$(34)
OPEN "INVENT.DAT" FOR OUTPUT AS #1' Open INVENT.DAT for writing.
PRINT #1, A$; B$; C$ ' Write without delimiters.
PRINT #1, Q$; A$; Q$; Q$; B$; Q$; Q$; C$; Q$' With delimiters.
CLOSE #1
OPEN "INVENT.DAT" FOR INPUT AS #1' Open INVENT.DAT for reading.
FOR I% = 1 TO 2' Read first two records and print.
INPUT #1, First$, Second$, Third$
PRINT First$; TAB(30); Second$; TAB(60); Third$
NEXT
CLOSE #1
Output
CAMERA AUTOFOCUSSeptember 20 198942
CAMERA, AUTOFOCUS September 20, 1989 42
PRINT USING Statement
────────────────────────────────────────────────────────────────────────────
Action
Prints strings or numbers using a specified format.
Syntax
PRINT USING formatstring$; expressionlist {;|,}
Remarks
The PRINT USING statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
formatstring$ A string literal (or variable)
that contains literal characters
to print (such as labels) and
special formatting characters. The
latter determine the field and
format of printed strings or
numbers.
expressionlist The values displayed on the screen.
Commas, semicolons, spaces, or
tabs can be used in
Argument Description
────────────────────────────────────────────────────────────────────────────
tabs can be used in
expressionlist to separate items.
In contrast with the PRINT
statement, delimiters in the
expressionlist argument used with
PRINT USING have no effect on
item placement.
{;|,} Determines the screen location of
the text cursor for the next
screen input or output statement:
a semicolon means the text cursor
is placed immediately after the
last character displayed; a comma
means the text cursor is placed at
the start of the next print zone.
When PRINT USING is used to print strings, you can use one of three
formatting characters to format the string field, as described in the
following list:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Character Rules
────────────────────────────────────────────────────────────────────────────
! Only the first character in the
given string is to be printed.
\ \ Prints 2 + n characters from the
string, where n is the number of
spaces between the two backslashes.
For example, if the backslashes
are typed with no spaces, two
characters are printed; with one
space, three characters are
printed, and so on. If the field
is longer than the string, the
string is left-justified in the
field and padded with spaces on
Character Rules
────────────────────────────────────────────────────────────────────────────
field and padded with spaces on
the right.
& The string is output without
modification.
When PRINT USING is used to print numbers, the following special characters
can be used to format the numeric field:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Character Rules
────────────────────────────────────────────────────────────────────────────
# Represents each digit position.
Digit positions are always filled.
Character Rules
────────────────────────────────────────────────────────────────────────────
Digit positions are always filled.
If the number to be printed has
fewer digits than positions
specified, the number is
right-justified (preceded by
spaces) in the field.
. Prints a decimal point. A decimal
point can be inserted at any
position in the field. If the
format string specifies that a
digit is to precede the decimal
point, the digit is always printed
(as 0, if necessary). Numbers are
rounded as necessary.
+ Prints the sign of the number (+
or -) before the number (if it
appears at the beginning of the
Character Rules
────────────────────────────────────────────────────────────────────────────
appears at the beginning of the
format string) or after (if it
appears at the end).
- Prints a negative number with a
trailing minus sign if it appears
at the end of the format string.
** Fills leading spaces in the
numeric field with asterisks. Also
specifies positions for two more
digits.
$$ Prints a dollar sign to the
immediate left of the formatted
number. Specifies two more digit
positions, one of which is the
dollar sign.
Character Rules
────────────────────────────────────────────────────────────────────────────
**$ Combines effects of
double-asterisk and
double-dollar-sign symbols.
Leading spaces are filled with
asterisks and a dollar sign is
printed before the number.
Specifies three more digit
positions, one of which is the
dollar sign. When negative numbers
are printed, the minus sign
appears to the immediate left of
the dollar sign.
, If the comma appears to the left
of the decimal point in a format
string, it makes a comma print to
the left of every third digit left
of the decimal point. If the comma
Character Rules
────────────────────────────────────────────────────────────────────────────
of the decimal point. If the comma
appears at the end of the format
string, it is printed as part of
the string. Specifies another
digit position. Has no effect if
used with exponential (^^^^ or
^^^^^) format.
^^^^ Specifies exponential format. Five
carets (^^^^^) allows D+ xxx to be
printed for larger numbers. Any
decimal point position can be
specified. The significant digits
are left-justified and the
exponent is adjusted. Unless a
leading +, trailing +, or - is
specified, one digit position is
used to the left of the decimal
point to print a space or a minus
Character Rules
────────────────────────────────────────────────────────────────────────────
point to print a space or a minus
sign.
_ An underscore in the format string
prints the next character as a
literal character. A literal
underscore is printed as the
result of two underscores ( _ _ )
in the format string.
If the number to be printed is larger than the specified numeric field, a
percent sign (%) is printed in front of the number. If rounding causes the
number to exceed the field, a percent sign is printed in front of the
rounded number. If the number of digits specified exceeds 24, BASIC
generates the error message Illegal function call.
Examples
The following examples show the use of string- and numeric-formatting
characters with PRINT USING.
This is an example of using string-formatting characters:
CLS ' Clear screen.
A$ = "LOOK" : B$ = "OUT"
PRINT USING "!"; A$; B$' First characters of A$ and B$.
PRINT USING "\ \"; A$; B$' Two spaces between backslashes,
' prints four characters from A$;
PRINT USING "\ \"; A$; B$; "!!" ' three spaces prints A$ and
' a blank.
PRINT USING "!"; A$;' First character from A$ and
PRINT USING "&"; B$' all of B$ on one line.
Output
LO
LOOKOUT
LOOK OUT !!
LOUT
This example shows the effects of different combinations of numeric
formatting characters:
' Format and print numeric data.
CLS ' Clear screen.
PRINT USING "##.##"; .78
PRINT USING "###.##"; 987.654
PRINT USING "##.## "; 10.2, 5.3, 66.789, .234
PRINT USING "+##.## "; -68.95, 2.4, 55.6, -.9
PRINT USING "##.##- "; -68.95, 22.449, -7.01
PRINT USING "**#.# "; 12.39, -0.9, 765.1
PRINT USING "$$###.##"; 456.78
PRINT USING "**$##.##"; 2.34
PRINT USING "####,.##"; 1234.5
PRINT USING "##.##^^^^"; 234.56
PRINT USING ".####^^^^-"; -888888
PRINT USING "+.##^^^^^"; 123
PRINT USING "_!##.##_!"; 12.34
PRINT USING "##.##"; 111.22
PRINT USING ".##"; .999
Output
0.78
987.65
10.20 5.30 66.79 0.23
-68.95 +2.40 +55.60 -0.90
68.95- 22.45 7.01-
*12.4 *-0.9 765.1
$456.78
***$2.34
1,234.50
2.35E+02
.8889E+06-
+.12E+003
!12.34!
%111.22
%1.00
PSET Statement
────────────────────────────────────────────────────────────────────────────
Action
Draws a specified point on the screen.
Syntax
PSET STEP( x%, y%) , color&
Remarks
The following list describes the parts of the PSET statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
STEP Indicates that x% and y% are
Part Description
────────────────────────────────────────────────────────────────────────────
STEP Indicates that x% and y% are
relative, not absolute.
Coordinates are treated as
distances from the most recent
graphics cursor location, not
distances from the (0,0) screen
coordinate.
For example, if the most recent
graphics cursor location were
(10,10), PSET STEP (10,5) would
refer to the point at (20,15).
x% The x coordinate of the pixel that
is to be set.
y% The y coordinate of the pixel that
is to be set.
Part Description
────────────────────────────────────────────────────────────────────────────
color& The color attribute for the
specified pixel.
The valid range of screen coordinate values and color values depends on the
screen mode established by the most recently executed SCREEN statement. If
a coordinate is outside the current viewport, no action is taken, nor is an
error message generated.
If you use PSET without specifying color&, the foreground color is
selected. In contrast, if you use PRESET without specifying color&, the
background color is selected. Otherwise, the two statements work exactly the
same.
See Also
PRESET
Example
The following example draws a line from (0,0) to (100,100), then erases the
line by writing over it with the background color:
SCREEN 2
FOR I = 0 TO 100
PSET (I, I)
NEXT I
LOCATE 16, 2: INPUT "Press the Return key to erase the line ", Gar$
' Now erase the line.
PSET (I - 1, I - 1), 0
FOR I = 0 TO 100
PSET STEP(-1, -1), 0
NEXT I
LOCATE 16, 2: PRINT " "
PUT Statement (File I/O)
────────────────────────────────────────────────────────────────────────────
Action
Writes from a variable or a random-access buffer to a file.
Syntax
PUT # filenumber%, recordnumber%, variable
Remarks
Do not use PUT on ISAM files.
The PUT statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file.
recordnumber% For random-access files, the
number of the record to be written.
For binary-mode files, the byte
position where writing is done.
The first record or byte position
in a file is 1. If you omit
Argument Description
────────────────────────────────────────────────────────────────────────────
in a file is 1. If you omit
recordnumber%, the next record or
byte (the one after the last GET
or PUT statement, or the one
pointed to by the last SEEK) is
written to. The largest possible
record number is 231 -1 or
2,147,483,647.
variable A variable that contains output to
be written to the file. The PUT
statement writes as many bytes to
the file as there are bytes in the
variable.
If you specify a variable, you do
not need to use MKI$, MKL$,
MKS$, MKD$, or MKC$ to convert
numeric fields before writing. You
Argument Description
────────────────────────────────────────────────────────────────────────────
numeric fields before writing. You
cannot use a FIELD statement with
the file if you use the variable
argument.
For random-access files, you can
use any variable as long as the
length of the variable is less
than or equal to the length of the
record. Usually, a record variable
defined to match the fields in a
data record is used. A record
cannot be longer than 32,767 bytes.
For binary-mode files, you can use
any variable.
When you use a variable-length
string variable, the statement
Argument Description
────────────────────────────────────────────────────────────────────────────
string variable, the statement
writes as many bytes as there are
characters in the string's value.
For example, the following two
statements write 15 bytes to file
number 1:
VarString$=STRING$(15, "X")
PUT #1,,VarString$
See the examples for more
information about using variables
rather than FIELD statements for
random-access files.
You can omit recordnumber%, variable, or both. If you omit recordnumber%
but include a variable, you must still include the commas:
PUT #4,,FileBuffer
If you omit both arguments, do not include the commas:
PUT #4
GET and PUT statements allow fixed-length input and output for BASIC
communication files. Be careful using GET and PUT for communication
because PUT writes a fixed number of characters and may wait indefinitely
if there is a communication failure.
Note
When using a file buffer defined by a FIELD statement, LSET, RSET, PRINT
# , PRINT # USING, and WRITE # can be used to put characters in the
random-file buffer before executing a PUT statement. In the case of WRITE
#, BASIC pads the buffer with spaces up to the carriage return. If you
attempt to read or write past the end of the buffer, BASIC generates the
error message FIELD overflow.
See Also
CVI, CVL, CVS, CVD, CVC; GET (File I/O); LSET; MKI$, MKL$, MKS$,
MKD$, MKC$; OPEN (File I/O)
Example
The following example reads names and test scores from the console and
stores them in a random-access file:
' Define record fields.
TYPE TestRecord
NameField AS STRING * 20
ScoreField AS SINGLE
END TYPE
DIM FileBuffer AS TestRecord
DIM I AS LONG
' Open the test data file.
OPEN "TESTDAT.DAT" FOR RANDOM AS #1 LEN = LEN(FileBuffer)
' Read pairs of names and scores from the console.
CLS ' Clear screen.
I = 0
DO
I = I + 1
INPUT "Name ? ", FileBuffer.NameField
INPUT "Score? ", FileBuffer.ScoreField
INPUT "-->More (y/n)? ", Resp$
PUT #1, I, FileBuffer
LOOP UNTIL UCASE$(MID$(Resp$, 1, 1)) = "N"
PRINT I; " records written."
CLOSE #1
KILL "TESTDAT.DAT"' Remove file from disk.
PUT Statement (Graphics)
────────────────────────────────────────────────────────────────────────────
Action
Places a graphic image obtained by a GET statement onto the screen.
Syntax
PUT STEP ( x!, y!), arrayname# ( indexes%) , actionverb
Remarks
The list below describes the parts of the PUT statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
STEP Keyword indicating that the given
x and y coordinates are relative
to the most recently plotted point.
The coordinates are treated as
distances from the most-recent
cursor location, not distances
from the (0,0) screen coordinate.
For example, if the most recent
cursor location were (10,10) then
the following statement would put
the object stored in Ball at
(20,15):
PUT STEP (10,5),Ball
Part Description
────────────────────────────────────────────────────────────────────────────
PUT STEP (10,5),Ball
( x!, y!) Coordinates that specify the
top-left corner of the rectangle
enclosing the image to be placed
in the current output window. The
entire rectangle to be put on the
screen must be within the bounds
of the current viewport.
Note that if a WINDOW statement
without the argument SCREEN
appears in a program before PUT,
the coordinates refer to the
lower-left corner of the rectangle.
arrayname# The name of the array that holds
the image. See the GET statement
for information about the number
Part Description
────────────────────────────────────────────────────────────────────────────
for information about the number
of elements that are required in
the array, which can be
multidimensional.
indexes% Specifies that the image is
retrieved starting from the
designated array element, rather
than at the first array element.
actionverb Determines interaction between
stored image and the one already
on the screen. This allows display
of the image with special effects.
The different values for actionverb are described in the following list.
The default actionverb value is XOR.
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Verb Description
────────────────────────────────────────────────────────────────────────────
XOR Causes the points on the screen to
be inverted where a point exists
in the array image. When an image
is placed on the screen against a
complex background twice, the
background is restored. This
behavior is exactly like that of
the cursor. You can move an object
around the screen without erasing
the background, thus creating
animation effects.
PSET Transfers the data point-by-point
onto the screen. Each point has
the exact color attribute it had
when it was taken from the screen
with GET. The PSET argument
Verb Description
────────────────────────────────────────────────────────────────────────────
with GET. The PSET argument
draws the image as stored, wiping
out any existing image.
PRESET The same as PSET except that a
negative image (for example, black
on white) is produced.
AND Used when the image is to be
transferred over an existing image
on the screen. The resulting
merged image is the result of a
logical- AND operation on the
stored image and the screen.
Points that had the same color in
both the existing image and the
stored image remain the same color.
Points that do not have the same
color in both the existing image
Verb Description
────────────────────────────────────────────────────────────────────────────
color in both the existing image
and the stored image do not.
OR Used to superimpose the image onto
an existing image. The resulting
image is the product of a logical-
OR operation on the stored image
and the screen image. The stored
image does not erase the previous
screen contents.
See Also
GET (Graphics)
Example
The following example creates a moving white ball that ricochets off the
sides of the screen until you press a key:
DEFINT A-Z
DIM Ball(84)' Set the dimensions for an integer array large
' enough to hold ball.
SCREEN 2' 640 pixels by 200 pixels screen resolution.
INPUT "Press any key to end; press <ENTER> to start", Test$
CLS
CIRCLE (16, 16), 14' Draw and paint ball.
PAINT (16, 16), 1
GET (0, 0)-(32, 32), Ball
X = 0 : Y = 0
Xdelta = 2 : Ydelta = 1
DO
' Continue moving in same direction as long as ball is within
' the boundaries of the screen - (0,0) to (640,200).
X = X + Xdelta : Y = Y + Ydelta
IF INKEY$ <> "" THEN END ' Test for key press.
' Change X direction if ball hits left or right edge.
IF (X < 1 OR X > 600) THEN
Xdelta = -Xdelta
BEEP
END IF
' Change Y direction if ball hits top or bottom edge.
IF (Y < 1 OR Y > 160) THEN
Ydelta = -Ydelta
BEEP
END IF
' Put new image on screen, simultaneously erasing old image.
PUT (X, Y), Ball, PSET
LOOP
END
RANDOMIZE Statement
────────────────────────────────────────────────────────────────────────────
Action
Initializes (reseeds) the random-number generator.
Syntax
RANDOMIZE expression%
Remarks
If you omit expression%, BASIC pauses and asks for a value by printing the
following messages before executing the RANDOMIZE statement:
Random Number Seed (-32768 to 32767)?
When you use the argument expression%, BASIC uses this value to initialize
the random-number generator.
If the random-number generator is not reseeded, the RND function returns
the same sequence of random numbers each time the program is run. To change
the sequence of random numbers every time the program is run, place a
RANDOMIZE statement at the beginning of the program and change the argument
with each run.
A convenient way to initialize the random-number generator is to use the
TIMER function. Using TIMER ensures a new series of random numbers each
time you use the program. See the example below.
See Also
RND, TIMER
Example
The following example uses RANDOMIZE to seed and reseed the random number
generator. It uses the RND function to simulate rolling a pair of dice.
' Use the timer as the seed for the number generator.
RANDOMIZE TIMER
DO
' Simulate rolling two dice using RND.
D1 = INT(RND * 6) + 1
D2 = INT(RND * 6) + 1
' Report the roll.
CLS ' Clear screen.
PRINT "You rolled a"; D1; "and a"; D2; "for a total of"; D1 + D2
INPUT "Roll again (Y/N)"; Resp$
PRINT
LOOP UNTIL UCASE$(MID$(Resp$, 1, 1)) = "N"
END
Output
You rolled a 3 and a 5 for a total of 8
Roll again (Y/N)? n
READ Statement
────────────────────────────────────────────────────────────────────────────
Action
Reads values from a DATA statement and assigns the values to variables.
Syntax
READ variablelist
Remarks
The argument variablelist is a series of BASIC variables that receive the
data from a DATA statement. The variables are separated by commas and can
be string or numeric. Only individual elements of a record variable can
appear in a READ statement.
The following table describes what happens when you try to read data of one
data type into a variable with a different data type:
╓┌────────────────────────┌────────────────────────┌─────────────────────────╖
If you try to read Into this: The result is:
If you try to read Into this: The result is:
this:
────────────────────────────────────────────────────────────────────────────
String value Numeric variable A run-time error.
Numeric value String variable The value is stored as a
string of numerals (no
error is produced).
Any numeric value Integer variables The value is rounded
before it is assigned to
the variable.
Numeric value A variable not large A run-time error.
enough to handle the
numeric variable.
String value Fixed-length string Truncated if the string
variables is too long;
left-justified and
padded with blanks if
If you try to read Into this: The result is:
this:
padded with blanks if
the string is shorter
than the variable.
Each variable in a READ statement receives its value from some DATA
statement. Which value the variable receives depends on how many values have
previously been read. The values of all DATA statements in a module can be
considered as a single list of values. Each value in this list is assigned
in turn to the variables specified in READ statements. It doesn't matter
how many values are specified in a given DATA statement or how many
variables are specified in a READ statement. If you attempt to read more
values than are specified in all of the statements combined, BASIC generates
the error message Out of data.
Use the RESTORE statement to reread DATA statements.
See Also
DATA, RESTORE
Example
The following example shows how you can use a READ statement to assign
values to the user-defined type Employee.
TYPE Employee
EmpName AS STRING * 35
SocSec AS STRING * 11
JobClass AS INTEGER
END TYPE
CLS ' Clear screen.
DIM ThisEmp AS Employee
DATA "Julia Magruder","300-32-3403",3
DATA "Amelie Reeves Troubetzkoy","777-29-3206",7
' Read first data input line and verify by printing data.
READ ThisEmp.EmpName, ThisEmp.SocSec, ThisEmp.JobClass
PRINT "Employee is "; ThisEmp.EmpName
PRINT "Employee's social security number is "; ThisEmp.SocSec
PRINT "Employee's job class is"; ThisEmp.JobClass
PRINT' Print blank line
' Read second data input line and verify.
READ ThisEmp.EmpName, ThisEmp.SocSec, ThisEmp.JobClass
PRINT "Employee is "; ThisEmp.EmpName
PRINT "Employee's social security number is "; ThisEmp.SocSec
PRINT "Employee's job class is"; ThisEmp.JobClass
Output
Employee is Julia Magruder
Employee's social security number is 300-32-3403
Employee's job class is 3
Employee is Amelie Reeves Troubetzkoy
Employee's social security number is 777-29-3206
Employee's job class is 7
REDIM Statement
────────────────────────────────────────────────────────────────────────────
Action
Changes the space allocated to an array that has been declared dynamic.
Syntax
REDIM SHARED variable( subscripts) AS type , variable( subscripts) AS
type...
Remarks
The REDIM statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Arguments Description
────────────────────────────────────────────────────────────────────────────
SHARED The optional SHARED attribute
allows a module to share variables
with all the procedures in the
module; this differs from the
SHARED statement, which affects
only the variables within a single
module. SHARED can be used in
Arguments Description
────────────────────────────────────────────────────────────────────────────
module. SHARED can be used in
REDIM statements only in the
module-level code.
variable A BASIC variable name.
subscripts The dimensions of the array.
Multiple dimensions can be
declared. The subscript syntax is
described below.
AS type Declares the type of the variable.
The type can be INTEGER, LONG,
SINGLE, DOUBLE, STRING (for
variable-length strings), STRING
* length (for fixed-length
strings), CURRENCY, or a
user-defined type.
Arguments Description
────────────────────────────────────────────────────────────────────────────
Subscripts in REDIM have the following form:
lower TO upper , lower TO upper...
The TO keyword provides a way to indicate both the lower and the upper
bounds of an array's subscripts. The arguments lower and upper are numeric
expressions that specify the lowest and highest value for the subscript. For
more information about using the TO keyword, see the DIM statement. For
more information about static and dynamic arrays, see Appendix B, "Data
Types, Constants, Variables, and Arrays" in the Programmer's Guide.
When a REDIM statement is compiled, all arrays declared in the statement
are treated as dynamic. At run time, when a REDIM statement is executed,
the array is deallocated (if it is already allocated) and then reallocated
with the new dimensions. Old array-element values are lost because all
numeric elements are reset to 0, and all string elements are reset to null
strings.
Although you can change the size of an array's dimensions with the REDIM
statement, you can not change the number of dimensions. For example, the
following statements are legal:
' $DYNAMIC
DIM A(50,50)
ERASE A
REDIM A(20,15) ' Array A still has two dimensions.
However, the following statements are not legal, and if you use them, BASIC
generates the error message Wrong number of dimensions:
' $DYNAMIC
DIM A(50,50)
ERASE A
REDIM A(5,5,5) ' Changed number of dimensions from two to three.
Note
BASIC now supports the CURRENCY data type (type suffix @). This is used in
the AS type clause of REDIM. BASIC now supports static arrays in
user-defined types.
See Also
DIM, ERASE
Example
The following example shows how to use REDIM to allocate an array of
records and then how to free the memory that the records use.
TYPE KeyElement
Word AS STRING * 20
Count AS INTEGER
END TYPE
' Make arrays dynamic.
' $DYNAMIC
CLS ' Clear screen.
' Allocate an array of records when you need it.
REDIM Keywords(100) AS KeyElement
Keywords(99).Word = "ERASE"
Keywords(99).Count = 2
PRINT "Keyword 99 is "; Keywords(99).Word
PRINT "Count is"; Keywords(99).Count
' Free the space taken by Keywords when you're finished.
ERASE Keywords
END
Output
Keyword 99 is ERASE
Count is 2
REM Statement
────────────────────────────────────────────────────────────────────────────
Action
Allows explanatory remarks to be inserted in a program.
Syntax 1
REM remark
Syntax 2
' remark
Remarks
REM statements are not compiled, but they appear exactly as entered when
the program is listed. You can branch from a GOTO or GOSUB statement to a
REM statement. Execution continues with the first executable statement after
the REM statement.
A single quotation mark can be used instead of the REM keyword. If the REM
keyword follows other statements on a line, it must be separated from the
statements by a colon.
REM statements also are used to introduce metacommands. For more
information, see Chapter 2, "SUB and FUNCTION Procedures" in the
Programmer's Guide.
Note
Do not use the single quotation form of the REM statement in a DATA
statement because it will be considered valid data.
Examples
The following example shows two equivalent remark statements. Note that you
must precede a REM statement at the end of a line with a colon.
This is not a complete program.
DIM Array(23)
FOR I = 1 TO 23 : Array(I) = 1 : NEXT I : REM Initialize the array.
FOR I = 1 TO 23 : Array(I) = 1 : NEXT I ' Initialize the array.
RESET Statement
────────────────────────────────────────────────────────────────────────────
Action
Closes all disk files.
Syntax
RESET
Remarks
The RESET statement closes all open disk files and writes data still in the
file buffers to disk.
See Also
CLOSE, END, SYSTEM
Example
The following example opens several files for sequential output, then
performs a RESET. The program attempts to write to the previously opened
files. The error that occurs is trapped and a message is printed indicating
that all files have been closed using the RESET statement.
DEFINT A-Z
ON ERROR GOTO ErrHandler ' Set up the error-handling routine.
CLS
FOR I = 1 TO 3
OPEN "Test" + RIGHT$(STR$(I), 1) + ".dat" FOR OUTPUT AS FREEFILE
PRINT "File #"; I; "has been opened for output."
NEXT I
PRINT : PRINT "Press any key to reset all open files."
PRINT
Z$ = INPUT$(1)
RESET
FOR I = 1 TO 3
PRINT "Trying to write to file #"; I
PRINT #I, "Test data"
NEXT I
END
ErrHandler:
' Error 52 is "Bad file name or number"
IF ERR = 52 THEN PRINT " File #"; I; "not open. RESET closed it."
RESUME NEXT
RESTORE Statement
────────────────────────────────────────────────────────────────────────────
Action
Allows DATA statements to be reread from a specified line.
Syntax
RESTORE { linelabel | linenumber}
Remarks
After executing a RESTORE statement without a specified linelabel or
linenumber, the next READ statement gets the first item in the first DATA
statement in the program.
If linelabel or linenumber is specified, the next READ statement gets the
first item in the specified DATA statement. If a line is specified, the
line label or line number must be in the module-level code. (Note that in
the QBX environment, DATA statements are automatically moved to the
module-level code.)
See Also
DATA, READ
Example
See the SEEK (file I/O) statement programming example, which uses the
RESTORE statement.
RESUME Statement
────────────────────────────────────────────────────────────────────────────
Action
Resumes program execution after an error-handling routine is finished.
Syntax
RESUME { 0 | NEXT | line}
Remarks
The different forms of the RESUME statement redirect program flow as
described in the following list:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
RESUME 0 Program execution resumes with the
statement that caused the error,
or at the most recent call out of
Part Description
────────────────────────────────────────────────────────────────────────────
or at the most recent call out of
the error-handling procedure or
module.
RESUME NEXT Execution resumes with the
statement immediately following
the one that caused the error, or
with the statement immediately
following the most recent call out
of the error-handling procedure or
module.
line Execution resumes at line, a
label or a line number. The
argument line must be in the same
procedure (for local
error-handlers) or within the same
module (for module-level
error-handlers).
Part Description
────────────────────────────────────────────────────────────────────────────
error-handlers).
The location where execution resumes is based on the location of the error
handler in which the error is trapped, not necessarily on the location where
the error occurred.
The following table summarizes the resumption rules for the RESUME 0
statement:
╓┌──────────────────────┌─────────────────────────┌──────────────────────────╖
Error handler Location of error Where program resumes
────────────────────────────────────────────────────────────────────────────
Local Same procedure Statement that caused
error
Error handler Location of error Where program resumes
────────────────────────────────────────────────────────────────────────────
Module level Same module Statement that caused
error
Local or module level Another procedure, same Statement that last
or another module called out of the
procedure or module that
contains the error
handler
Note
If BASIC had to search for the error handler (the error handler that
contains the RESUME statement is in a procedure or module other than the
one in which the the error occurred), then the last statement executed in
that procedure (or module) is the last call out of that procedure or module.
As a rule, avoid using a line argument with a RESUME statement in a
module-level error handler, unless you expect errors to occur only at the
module level.
If you use a RESUME statement outside an error-handling routine, BASIC
generates the error message RESUME without error.
When an error handling routine is active and the end of the program text is
encountered before executing a RESUME statement, BASIC generates the error
message No RESUME. This also is true if an END statement (or an END SUB,
END FUNCTION, or END DEF statement for a local error handler) is executed
before a RESUME.
Note
Programs containing error-handling routines must be compiled with either the
/E (On error) or /X (Resume next) options when you are compiling from the
BASIC command line.
See Also
ON ERROR
Example
See the ON ERROR statement programming example, which uses the RESUME
statement.
RETRIEVE Statement
────────────────────────────────────────────────────────────────────────────
Action
Fetches the current record in an ISAM table and places its data into a
record variable.
Syntax
RETRIEVE # filenumber%, recordvariable
Remarks
RETRIEVE places the current record's data into recordvariable. You can
change the data in recordvariable, then update the current record with the
changes you've made. Use the UPDATE statement to update the current record.
The RETRIEVE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the table.
recordvariable The name of the variable that will
hold the current record's data. It
is a variable of the user-defined
type tabletype that was specified
in the OPEN statement.
RETRIEVE has no effect on the current position.
If the values passed to recordvariable do not match the record strucure in
the user-defined type, BASIC generates the error message Type Mismatch.The
record structure includes the names and types of columns or fields.
See Also
INSERT, UPDATE
Example
See the programming example for the SEEKGT, SEEKGE, and SEEKEQ
statements, which uses the RETRIEVE statement.
RETURN Statement
────────────────────────────────────────────────────────────────────────────
Action
Returns control from a routine.
Syntax
RETURN { linelabel | linenumber}
Remarks
Without a line label or number, RETURN continues execution where an event
occurred (for event handling) or at the statement following the GOSUB
statement (for subroutine calls). GOSUB and RETURN without a line number
can be used anywhere in a program, but the GOSUB and corresponding RETURN
must be at the same level.
The linelabel or linenumber in the RETURN statement causes an
unconditional return from a GOSUB subroutine to the specified line. RETURN
with a line label or line number can return control to a statement in the
module-level code only, not in procedure-level code.
A RETURN statement cannot be used to return control to a calling program
from a SUB procedure. Use EXIT SUB for this purpose.
Note
BASIC's SUB procedures provide a better-structured alternative to GOSUB
subroutines.
See Also
EXIT, GOSUB, ON event
Example
See the GOSUB statement programming example, which uses the RETURN
statement.
RIGHT$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string consisting of the rightmost n% characters of a string.
Syntax
RIGHT$( stringexpression$, n%)
Remarks
The argument stringexpression$ can be any string variable, string constant,
or string expression.
The argument n% is a numeric expression between 0 and 32,767, inclusive,
indicating how many characters are to be returned.
If n% is 0, the null string (length 0) is returned.
If n% is greater than or equal to the number of characters in
stringexpression$, the entire string is returned. To find the number of
characters in stringexpression$, use LEN( stringexpression$) .
See Also
LEFT$, MID$ Function
Example
The following example converts names entered in the form "Firstname
[Middlename] Lastname" to the form "Lastname, Firstname [Middlename]."
CLS' Clear screen.
LINE INPUT "Name: "; Nm$
I = 1 : Sppos = 0
DO WHILE I > 0
I = INSTR(Sppos + 1, Nm$, " ")' Get position of next space.
IF I > 0 THEN Sppos = I
LOOP
' Sppos now points to the position of the last space.
IF Sppos = 0 THEN
PRINT Nm$ ' Only a last name was input.
ELSE
' Everything after last space.
Lastname$ = RIGHT$(Nm$, LEN(Nm$) - Sppos)
' Everything before last space.
Firstname$ = LEFT$(Nm$, Sppos - 1)
PRINT Lastname$ ", " Firstname$
END IF
END
RMDIR Statement
────────────────────────────────────────────────────────────────────────────
Action
Removes an existing directory.
Syntax
RMDIR pathname$
Remarks
The pathname$ is the name of the directory that is to be deleted. The
pathname$ must be a string of fewer than 64 characters. The directory to be
removed must be empty except for the working directory ( '.' ) and the
parent directory ( '..' ); otherwise, BASIC generates one of two error
messages, either Path not found or Path/File access error.
RMDIR works like the DOS command of the same name. However, the syntax in
BASIC cannot be shortened to RD, as it can in DOS.
See Also
CHDIR, MKDIR
Example
The following example shows how to use RMDIR to remove a subdirectory.
CHDIR "C:\SALES\TEMP"' Move to \TEMP subdirectory in \SALES.
KILL "*.*" ' Remove all files in \TEMP.
CHDIR ".." ' Move back up to \SALES.
RMDIR "TEMP"' Remove \TEMP subdirectory.
RND Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a single-precision random number between 0 and 1.
Syntax
RND ( n#)
Remarks
The value of n# determines how RND generates the next random number:
╓┌──────────────────────┌────────────────────────────────────────────────────╖
Value Number returned
────────────────────────────────────────────────────────────────────────────
n# < 0 Always returns the same number for any given n#.
n# > 0 or n omitted Returns the next random number in the sequence.
n# = 0 Returns the last number generated.
Even if n# > 0, the same sequence of random numbers is generated each time
the program is run unless you initialize the random-number generator each
time. (See the RANDOMIZE statement entry for more information about
initializing the random-number generator.)
To produce random integers in a given range, use this formula:
INT (( upperbound - lowerbound + 1) * RND + lowerbound)
In this formula, upperbound is the highest number in the range, and
lowerbound is the lowest number in the range.
Example
See the RANDOMIZE statement programming example, which uses the RND
function.
ROLLBACK, ROLLBACK ALL Statements
────────────────────────────────────────────────────────────────────────────
Action
Rescind all or part of the operations of a transaction (a series of ISAM
database operations).
Syntax
ROLLBACK savepoint%
ROLLBACK ALL
Remarks
The savepoint% is an integer that identifies a savepoint within a
transaction -- a series of ISAM database operations that is either committed
as a whole or rescinded. Use the savepoint function to designate a
savepoint, which marks the beginning of a subset of operations that can be
rescinded.
If you specify a savepoint% argument, ROLLBACK returns the data affected
by a transaction to its state at that savepoint.
If you do not specify a savepoint% argument, ROLLBACK returns the data
affected by the transaction to its state at the previous savepoint, or at
the beginning of the transaction if there are no intermediate savepoints.
ROLLBACK ALL rescinds all operations in a transaction and returns the data
to its initial state at the beginning of the transaction. Use BEGINTRANS to
indicate the beginning of a transaction. Use COMMITTRANS to commit all
operations since the most recent BEGINTRANS statement.
See Also
BEGINTRANS, COMMITTRANS, SAVEPOINT
Example
See the BEGINTRANS statement programming example, which uses the ROLLBACK
statement.
RSET Statement
────────────────────────────────────────────────────────────────────────────
Action
Moves data from memory to a random-access file buffer (in preparation for a
PUT statement), or right-justifies the value of a string in a string
variable.
Syntax
RSET stringvariable$ = stringexpression$
Remarks
The RSET statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
stringvariable$ Usually a random-access file field
defined in a FIELD statement,
although it can be any string
variable.
stringexpression$ The value that is assigned to
stringvariable$ and is
right-justified.
If stringexpression$ requires fewer bytes than were defined for
stringvariable$ in the FIELD statement, the RSET statement right-justifies
the string in the field ( LSET left-justifies the string). Spaces are used
to pad the extra positions. If the string is too long for the field, both
LSET and RSET truncate characters from the right. Numeric values must be
converted to strings before they are justified with the RSET or LSET
statements.
The RSET statement can be used with string variables unrelated to FIELD
statements. When used with a fixed-length string variable, the value is
right-justified and left-padded with blanks.
When RSET is used with a variable-length string, the string is treated as a
fixed field. The length of the field is the length of the value the variable
had before the RSET statement.
See Also
FIELD; LSET; MKI$, MKL$, MKS$, MKD$, MKC$; PUT (File I/O)
Example
See the LSET statement programming example, which uses the RSET statement.
RTRIM$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string with trailing (rightmost) spaces removed.
Syntax
RTRIM$( stringexpression$)
Remarks
The stringexpression$ can be any string expression. The RTRIM$ function
works with both fixed- and variable-length string variables.
See Also
LTRIM$
Example
The following example shows the effects of RTRIM$ on fixed- and
variable-length strings:
DIM FixStr AS STRING * 10
CLS ' Clear screen.
PRINT " 1 2"
PRINT "12345678901234567890"
FixStr = "Twine"
PRINT FixStr + "*"
PRINT RTRIM$(FixStr) + "*"
VarStr$ = "Braided" + SPACE$(10)
PRINT VarStr$ + "*"
PRINT RTRIM$(VarStr$) + "*"
Output
1 2
12345678901234567890
Twine *
Twine*
Braided *
Braided*
RUN Statement
────────────────────────────────────────────────────────────────────────────
Action
Restarts the program currently in memory, or executes a specified program.
Syntax
RUN { linenumber | filespec$}
Remarks
The RUN statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
linenumber The numeric label of the line
where execution begins. If no
argument is given, execution
begins at the first executable
line of code.
filespec$ A string expression that names the
program file to load and run. The
Argument Description
────────────────────────────────────────────────────────────────────────────
program file to load and run. The
current program is cleared from
memory before the specified
program is loaded.
The line where execution begins must be in the module-level code. Therefore,
a RUN statement in a SUB or FUNCTION procedure must point to labels at
module level. If no line label is given, execution always starts with the
first executable line of the main module.
Program lines can have line numbers or alphanumeric labels, such as
OpenWindow:. If an alphanumeric label is the target of a RUN statement, the
compiler generates the error message String expression required.
You do not need to specify the filename extension in filespec$. The .BAS
extension is assumed in the QBX environment, whereas the .EXE extension is
assumed for compiled, stand-alone programs. If the program you wish to run
has a different extension, you must give the extension. If the program name
has no extension, the filename given must end with a period. For example,
the following statement would execute CATCHALL.EXE from a BC-compiled
program, and CATCHALL.BAS from within the QBX environment:
RUN "CATCHALL"
Programs running within the QBX environment must call only BASIC program
files. The file is loaded and run as if it were a BASIC program; if it is
not in the BASIC program format, execution halts. The error message that
results varies, depending on the file's contents. Likewise, programs
compiled with the compiler must not invoke BASIC source files, as these run
only in the QBX environment.
An executable file need not have been written in BASIC. Any executable file
can be run.
When running a program in the QBX environment, if an executable file
matching the filename in the command line cannot be found, BASIC generates
the error message File not found and control returns to BASIC. When running
a program compiled by BC, BASIC generates the error message File not found
in module module-name at address segment:offset and control returns to the
operating system.
When the invoked program completes execution, control does not return to the
invoking program. If the invoking program ran outside QBX, control returns
to the operating system. If the invoking program ran under QBX, control
returns to BASIC.
RUN closes all files and clears program memory before loading the
designated program. The compiler does not support the R option from BASICA.
(The R option keeps all open data files open.) If you want to run a
different program, but leave open files open, use the CHAIN statement.
See Also
CHAIN
Example
This example shows how RUN linenumber resets all numeric variables to 0.
As the line number following RUN increases in lines 60, 70, 80, and 90, the
variables in the earlier statements lose their assigned values.
10 A = 9
20 B = 7
30 C = 5
40 D = 4
50 PRINT A, B, C, D
60 IF A = 0 THEN 70 ELSE RUN 20
70 IF B = 0 THEN 80 ELSE RUN 30
80 IF C = 0 THEN 90 ELSE RUN 40
90 IF D = 0 THEN END ELSE RUN 50
Output
9 7 5 4
0 7 5 4
0 0 5 4
0 0 0 4
0 0 0 0
SADD Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the address of a specified string variable.
Syntax
SADD( stringvariable$)
Remarks
The SADD function returns the address of a string as an offset (near
pointer) from the current data segment. The offset is a two-byte integer.
SADD is most often used in mixed-language programming to obtain far
addresses before passing far strings to procedures written in other
languages.
The argument stringvariable$ is the string whose offset you want to
determine. It can be a simple string variable or a single element of a
string array. You cannot use fixed-length string arguments.
SADD can be used with both near and far strings. To obtain the segment
address of a far string, use the SSEG function. In previous versions of
BASIC, SADD was used only for near strings.
Note
Do not add characters to the beginning or end of a string passed using SADD
and LEN. Adding characters can cause BASIC to generate a run-time error.
Use this function with caution, because strings can move in the BASIC string
space (storage area) at any time.
See Also
BLOAD; BSAVE; DEF SEG; FRE; PEEK; POKE; SSEG; SSEGADD; VARPTR,
VARSEG; VARPTR$
Example
The following example illustrates the use of the SADD and SSEG functions.
SADD returns the offset address of a variable-length string. SSEG returns
the segment of a variable-length string. Typically these functions are used
in mixed-language programs or with PEEK, POKE, BLOAD, or BSAVE.
In this example, a string is created and then its offset and segment are
calculated with SADD and SSEG. The information is then passed to a BASIC
SUB procedure that mimics the performance of a non-BASIC print routine.
DEFINT A-Z
' Create the string.
Text$ = ".... a few well-chosen words"
' Calculate the offset, segment, and length of the string.
Offset = SADD(Text$)
Segment = SSEG(Text$)
Length = LEN(Text$)
' Pass these arguments to the print routine.
CALL printit(Segment, Offset, Length)
SUB printit (Segment, Offset, Length)
CLS
' Set the segment for the PEEK function.
DEF SEG = Segment
FOR i = 0 TO Length - 1
' Get each character from memory, convert to ASCII, and display.
PRINT CHR$(PEEK(i + Offset));
NEXT i
END SUB
SAVEPOINT Function
────────────────────────────────────────────────────────────────────────────
Action
Marks the beginning of a subset of ISAM database operations in a
transaction.
Syntax
SAVEPOINT
Remarks
The SAVEPOINT function marks the beginning of a subset of operations within
a transaction that can be rescinded using a ROLLBACK statement. The
function returns an integer that refers to the savepoint.
Transactions are a way to group a series of ISAM operations so that you can
commit them as a whole, rescind them all, or rescind operations since a
designated savepoint. Use BEGINTRANS to indicate the beginning of a
transaction and COMMITTRANS to commit all operations since the beginning of
a transaction.
Use ROLLBACK with the argument savepoint% to return the data affected by a
transaction to its state at that savepoint. Use ROLLBACK with no argument
to return the data affected by the transaction to its state at the most
recent savepoint, or at the beginning of the transaction if there are no
intermediate savepoints.
ROLLBACK ALL rescinds all ISAM operations in a transaction and returns the
data to its initial state at the beginning of the transaction.
If there is no transaction pending when you use SAVEPOINT, BASIC generates
the error message Illegal function call.
See Also
BEGINTRANS, COMMITTRANS, ROLLBACK
Example
See the BEGINTRANS statement programming example, which uses the SAVEPOINT
function.
SCREEN Function
────────────────────────────────────────────────────────────────────────────
Action
Reads a specified character's ASCII value or its color from a specified
screen location.
Syntax
SCREEN( line%, column% , colorflag%)
Remarks
The SCREEN function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
line% The line number of the character
location on the screen. The
argument line% is an integer
expression whose valid range
depends on the number of lines on
screen.
column% The column number of the character
location on the screen. The
argument column% is an integer
expression with a value between 1
Argument Description
────────────────────────────────────────────────────────────────────────────
expression with a value between 1
and 80, inclusive.
colorflag% A numeric expression that
determines which information is
returned. When colorflag% is
nonzero, SCREEN returns the
number of the color attribute at
the screen location. If
colorflag% is 0 or is absent, the
SCREEN function returns the ASCII
character code.
Note
In graphics screen modes, if the pattern on the screen at the given
character location does not exactly match any pattern in the current ASCII
character set, the SCREEN function will return the ASCII code for a space.
If colorflag% is nonzero, the SCREEN function will return 0.
See Also
Appendix A, "Keyboard Scan Codes and ASCII Character Codes," COLOR,
PALETTE, SCREEN Statement
Examples
If the character at (10,10) is A, then the following statement would return
65, the ASCII code for A, to the variable X:
X = SCREEN(10,10)
The following statement returns the color attribute of the character in the
upper-left corner of the screen:
X = SCREEN(1, 1, 1)
SCREEN Statement
────────────────────────────────────────────────────────────────────────────
Action
Sets the specifications for the graphics adapter and monitor.
Syntax
SCREEN mode% , colorswitch% , activepage% , visiblepage%
Remarks
The SCREEN statement sets a screen mode for a particular combination of
display and adapter. Later sections in this entry describe the available
modes for specific adapters. The SCREEN statement uses the following
arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
mode% An integer constant or expression
that selects a screen mode for a
particular combination of display
and adapter (see "Summary of
Screen Modes" later in this entry
for information on what the
acronyms represent). There also
are more details on mode% later
in this entry.
colorswitch% Integer expression that switches
Argument Description
────────────────────────────────────────────────────────────────────────────
colorswitch% Integer expression that switches
composite monitor display between
color and monocolor (modes 0 and 1
only). See below for more details
on colorswitch%.
activepage% Integer expression that identifies
the screen page that text or
graphics output is written to.
visiblepage% Integer expression that identifies
the screen page that is displayed.
The colorswitch% is effective only for screen modes 0 and 1 and for
composite monitors. In screen mode 0, use a colorswitch% value of 0 to
disable color, and a non-zero value to enable color. In screen mode 1, use a
non-zero value to disable color and 0 to enable color.
See "Adapters, Screen Modes, and Displays" later in this entry for the valid
ranges for activepage% and visiblepage% for each graphics adapter. The
"Attributes and Colors" section lists the default color attributes for
different screen modes. If mode% is an expression, rather than a constant,
and if you know your program will not use certain screen modes, you can
achieve a smaller .EXE file by linking one or more stub files:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
If not using screen modes: Link to file:
────────────────────────────────────────────────────────────────────────────
1 or 2 NOCGA.OBJ
3 NOHERC.OBJ
4 NOOGA.OBJ
7, 8, 9, or 10 NOEGA.OBJ
11, 12, or 13 NOVGA.OBJ
If you do not need graphics in your custom run-time module (because the
programs use screen mode 0 only), you can save 15K by creating the run-time
module with NOGRAPH.OBJ.
Summary of Screen Modes
The following lists summarize each of the screen modes. The color adapters
referred to are the IBM Monochrome Display and Printer Adapter (MDPA), the
IBM Color Graphics Adapter (CGA), the IBM Enhanced Graphics Adapter (EGA),
the IBM Video Graphics Array (VGA), the IBM Multicolor Graphics Array
(MCGA), and the Olivetti Color Adapter. The Hercules Graphics Card, Graphics
Card Plus and InColor adapters are supported, but only with monochrome
monitors.
Note
Many screen modes support more than one combination of rows and columns. See
the WIDTH statement for more information about changing the number of rows
and columns on the display.
SCREEN 0
■ MDPA, CGA, EGA, MCGA, Hercules, Olivetti, or VGA Adapter Boards
■ Text mode only
■ 40 x 25, 40 x 43, 40 x 50, 80 x 25, 80 x 43, or 80 x 50 text
format with 8 x 8 character box size (8 x 14, 9 x 14, or 9 x 16
with EGA or VGA)
■ 16 colors assigned to two color attributes
■ 16 colors assigned to any of 16 color attributes with CGA or EGA
■ 64 colors assigned to any of 16 color attributes with EGA or VGA
SCREEN 1
■ CGA, EGA, VGA, or MCGA Adapter Boards
■ 320 x 200 graphics
■ 40 x 25 text format, 8 x 8 character box
■ 16 background colors and one of two sets of three foreground
colors assigned using COLOR statement with CGA
■ 16 colors assigned to four color attributes with EGA, VGA or
MCGA
SCREEN 2
■ CGA, EGA, VGA, or MCGA Adapter Boards
■ 640 x 200 graphics
■ 80 x 25 text format with character box size of 8 x 8
■ 2 colors (black and white) with CGA
■ 16 colors assigned to two color attributes with EGA or VGA
SCREEN 3
■ Hercules, Olivetti, or AT&T Adapter Boards
■ Hercules adapter required, monochrome monitor only
■ 720 x 348 graphics
■ 80 x 25 text format, 9 x 14 character box
■ Two screen pages (one only if a second display adapter is
installed)
■ PALETTE statement not supported
SCREEN 4
■ Hercules, Olivetti, or AT&T Adapter Boards
■ 640 x 400 graphics
■ 80 x 25 text format, 8 x 16 character box
■ One of 16 colors assigned as the foreground color (selected by
the COLOR statement); background fixed at black
■ Supports Olivetti Personal Computers models M24, M240, M28,
M280, M380, M380/C, and M380/T, and AT&T Personal Computers 6300
series
Warning
Olivetti personal computers running 3XBOX under OS/2 should avoid screen
mode 4.
SCREEN 7
■ EGA or VGA Adapters
■ 320 x 200 graphics
■ 40 x 25 text format, character box size 8 x 8
■ 32K page size, pages 0-1 (64K adapter memory), 0-3 (128K), or
0-7 (256K)
■ Assignment of 16 colors to any of 16 color attributes
SCREEN 8
■ EGA or VGA Adapters
■ 640 x 200 graphics
■ 80 x 25 text format, 8 x 8 character box
■ 64K page size, pages 0 (64K adapter memory), 0-1 (128K), or 0-3
(256K)
■ Assignment of 16 colors to any of 16 color attributes
SCREEN 9
■ EGA or VGA Adapters
■ 640 x 350 graphics
■ 80 x 25 or 80 x 43 text format, 8 x 14 or 8 x 8 character box
size
■ 64K page size, page 0 (64K adapter memory); 128K page size,
pages 0 (128K adapter memory) or 0 - 1 (256K)
■ 16 colors assigned to four color attributes (64K adapter
memory), or 64 colors assigned to 16 color attributes (more than
64K adapter memory)
SCREEN 10
■ EGA or VGA adapters, monochrome monitor only
■ 640 x 350 graphics, monochrome monitor only
■ 80 x 25 or 80 x 43 text format, 8 x 14 or 8 x 8 character box
size
■ 128K page size, pages 0 (128K adapter memory) or 0 - 1 (256K)
■ Up to nine shades of gray assigned to four color attributes
SCREEN 11
■ VGA or MCGA adapters
■ 640 x 480 graphics
■ 80 x 30 or 80 x 60 text format, character box size of 8 x 16 or
8 x 8
■ Assignment of up to 256K colors to two color attributes
SCREEN 12
■ VGA adapter
■ 640 x 480 graphics
■ 80 x 30 or 80 x 60 text format, character box size of 8 x 16 or
8 x 8
■ Assignment of up to 256K colors to 16 color attributes
SCREEN 13
■ VGA or MCGA adapters
■ 320 x 200 graphics
■ 40 x 25 text format, character box size of 8 x 8
■ Assignment of up to 256K colors to up to 256 color attributes
Screen Modes, Adapters, and Displays
This section describes the screen modes available for each adapter. If the
display device also is a factor in choosing a screen mode, it is listed. The
IBM Monochrome Display and Printer Adapter (MDPA) must be used with a
monochrome display. Only SCREEN 0, text mode, can be used with the MDPA.
Table 1.10 describes the screen mode available with the MDPA.
Table 1.11 summarizes the screen modes available with Hercules Adapters.
The IBM Color Graphics Adapter (CGA) and Color Display typically are paired.
This combination permits running text-mode programs, and both
medium-resolution and high-resolution graphics programs.
Table 1.12 summarizes the screen modes available with the CGA.
The IBM Enhanced Graphics Adapter (EGA) can be used with either the IBM
Color Display or the Enhanced Color Display. In modes 0, 1, 2, 7, and 8,
these pairings produce similar results, except for the following
differences:
■ Border color can't be set on an Enhanced Color Display when it
is in 640 x 350 text mode.
■ The text quality is better on the Enhanced Color Display (an 8 x
14 character box for Enhanced Color Display versus an 8 x 8
character box for Color Display).
Screen mode 9 takes full advantage of the capabilities of the Enhanced Color
Display. Mode 9 provides for the highest resolution possible for the
EGA/Enhanced Color Display configuration. Programs written for this mode
will not work for any other hardware configuration except the VGA.
Table 1.13 summarizes the screen modes that can be used with an EGA.
Only the EGA and VGA can be paired with the IBM Monochrome display to run
programs in screen mode 10. This mode can be used to display monochrome
graphics at a very high resolution with the optional effects of blinking and
high intensity.
The following two tables summarize the color attributes, display colors, and
effects for screen mode 10 used with a monochrome display.
Tables 1.14 and 1.15 summarize EGA and VGA adapters used with monochrome
display (SCREEN 10).
The IBM Video Graphics Array (VGA) adapter offers significantly enhanced
text and graphics in all modes. Table 1.16 summarizes the modes available
with the VGA.
The IBM Multicolor Graphics Array (MCGA) combines the modes of the CGA with
the very high resolution and 256K color modes of the VGA to provide enhanced
text and graphics in all modes. Table 1.17 summarizes the modes supported by
the MCGA.
The MCGA uses the same display color values as the VGA. For a description of
how the MCGA calculates display color values, see the PALETTE statement.
Attributes and Colors
For various screen modes and display hardware configurations, different
color-attribute and display-color settings exist. (See the PALETTE
statement for a discussion of color attributes and display colors.) The
majority of these color-attribute and display-color configurations are
summarized in Tables 1.18-1.20.
Note
In OS/2 protected mode, BASIC supports only screen modes 0 - 2 and does not
support the activepage% and visiblepage% arguments.
See Also
COLOR, PALETTE, SCREEN Function, WIDTH
Example
The following example sets up a multipage EGA or VGA mode 7 (320x200)
display using the SCREEN statement. A help screen is displayed for several
seconds then copied (using the PCOPY statement) to page 2 for later use. A
cube is displayed and rotated on the screen. By pressing Shift+F1, the user
can again see the help screen, after which the cube display is resumed.
DEFINT A-Z
' Define a macro string to draw a cube and paint its sides.
One$ = "BR30 BU25 C1 R54 U45 L54 D45 BE20 P1, 1G20 C2 G20"
Two$ = "R54 E20 L54 BD5 P2, 2 U5 C4 G20 U45 E20 D45 BL5 P4, 4"
Plot$ = One$ + Two$
' Initialize values for active page, visual page, and help page.
APage% = 0 : VPage% = 1 : HPage% = 2
Angle% = 0
' Create a HELP screen on the visual page.
SCREEN 7, 0, VPage%, VPage%
LOCATE 1, 18
PRINT "HELP"
LOCATE 5, 1
PRINT "Press 'Alt+F1' keys to see this HELP"
PRINT "screen while the cube is rotating"
PRINT "around the center of the screen."
PRINT
PRINT "After a brief delay, the cube will"
PRINT "resume at the next point in its rotation."
PRINT
PRINT "Press any other key to exit the program."
' Put a copy of the help screen in page 2.
PCOPY VPage%, HPage%
SLEEP 5
DO
SCREEN 7, 0, APage%, VPage%
' Clear the active page.
CLS 1
' Rotate the cube Angle% degrees.
DRAW "TA" + STR$(Angle%) + Plot$
' Angle% is some multiple of 15 degrees.
Angle% = (Angle% + 15) MOD 360
' Drawing is complete. Make the cube visible in its ' new position by
swapping the active and visual pages.
SWAP APage%, VPage%
' Check the keyboard input.
Kbd$ = INKEY$
SELECT CASE Kbd$
' If Shift+F1 is pressed, show the HELP page.
CASE CHR$(0) + CHR$(104)
PCOPY HPage%, APage%
SLEEP 3
' Do nothing if no key is pressed.
CASE ""
CASE ELSE
EXIT DO
END SELECT
LOOP
END
SEEK Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the current file position.
Syntax
SEEK( filenumber%)
Remarks
The argument filenumber% is the number used in the OPEN statement to open
the file. SEEK returns a value between 1 and 2,147,483,647, inclusive
(equivalent to 231 -1).
SEEK returns the number of the next record read or written when used on
random-access files. For files opened in binary, output, append, or input
mode, SEEK returns the byte position in the file where the next operation
is to take place. The first byte in a file is 1.
SEEK returns zero when used on an ISAM table or on BASIC devices (SCRN,
CONS, KYBD, COM n, LPT n, PIPE) that do not support SEEK.
See Also
GET (File I/O); OPEN; PUT (File I/O); SEEK Statement; SEEKGT, SEEKGE,
SEEKEQ Statements
Example
See the SEEK statement programming example, which uses the SEEK function.
SEEK Statement
────────────────────────────────────────────────────────────────────────────
Action
Sets the position in a file for the next read or write.
Syntax
SEEK # filenumber%, position&
Remarks
The SEEK statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file.
position& A numeric expression that
indicates where the next read or
write occurs. The position& value
must be between 1 and
2,147,483,647 (equivalent to 231
-1), inclusive.
For files opened in random-access mode, position& is the number of a record
in the file.
For files opened in binary, input, output, or append mode, position& is the
byte position relative to the beginning of the file. The first byte in a
file is at position 1; the second byte is at position 2, and so on. After a
SEEK operation, the next file I/O operation starts at the specified byte
position.
Note
Record numbers on a GET or PUT override the file positioning done by
SEEK.
Performing a file write after doing a SEEK operation beyond the end of a
file extends the file. If you attempt a SEEK operation to a negative or
zero position, BASIC generates the error message Bad record number.
BASIC leaves the file position unchanged when you use SEEK on an ISAM table
or on BASIC devices (SCRN, CONS, KYBD, COM n, LPT n, PIPE) that do not
support SEEK.
See Also
GET (File I/O); OPEN; PUT (File I/O); SEEK Function; SEEKGT, SEEKGE,
SEEKEQ Statements
Example
The following example uses a combination of the SEEK function and SEEK
statement to move the file position exactly one record back and rewrite the
record if a variable is true (nonzero):
CONST FALSE = 0, TRUE = NOT FALSE
' Define record fields and a user-type variable.
TYPE TestRecord
NameField AS STRING * 20
ScoreField AS SINGLE
END TYPE
DIM RecordVar AS TestRecord
DIM I AS LONG
' This part of the program creates the random-access file used by the
' second part of the program, which demonstrates the SEEK statement.
OPEN "TESTDAT2.DAT" FOR RANDOM AS #1 LEN = LEN(RecordVar)
RESTORE
READ NameField$, ScoreField
I = 0
DO WHILE NameField$ <> "END"
I = I + 1
RecordVar.NameField = NameField$
RecordVar.ScoreField = ScoreField
PUT #1, I, RecordVar
READ NameField$, ScoreField
LOOP
CLOSE #1
DATA "John Simmons", 100
DATA "Allie Simpson", 95
DATA "Tom Tucker", 72
DATA "Walt Wagner", 90
DATA "Mel Zucker", 92
DATA "END", 0
' Open the test data file.
DIM FileBuffer AS TestRecord
OPEN "TESTDAT2.DAT" FOR RANDOM AS #1 LEN = LEN(FileBuffer)
' Calculate number of records in the file.
Max = LOF(1) \ LEN(FileBuffer)
' Read and print contents of each record.
FOR I = 1 TO Max
GET #1, I, FileBuffer
IF FileBuffer.NameField = "Tom Tucker" THEN
ReWriteFlag = TRUE
EXIT FOR
END IF
NEXT I
IF ReWriteFlag = TRUE THEN
' Back up file by the length of the record variable that
' is used to write to the file.
FileBuffer.ScoreField = 100
SEEK #1, SEEK(1) - LEN(RecordVar)
PUT #1, , RecordVar
END IF
CLOSE #1
KILL "TESTDAT2.DAT"
END
SEEKGT, SEEKGE, SEEKEQ Statements
────────────────────────────────────────────────────────────────────────────
Action
Causes the first matching record in an ISAM table to become the current
record.
Syntax
SEEKGT # filenumber% , keyvalue, keyvalue
SEEKGE # filenumber% , keyvalue, keyvalue
SEEKEQ # filenumber% , keyvalue, keyvalue
Remarks
The SEEKGT, SEEKGE, and SEEKEQ statements cause the first matching record
in the table, according to the current index, to become the current record.
The following table shows which value of the current index column causes the
record to become current for each statement.
╓┌──────────────────┌────────────────────────────────────────────────────────╖
Statement Current-index column value
────────────────────────────────────────────────────────────────────────────
SEEKGT Greater than keyvalue
SEEKGE Greater than, or equal to, keyvalue
SEEKEQ Equal to keyvalue
The argument filenumber% is the number used in the OPEN statement to open
the table. The argument keyvalue is an expression fewer than 256 characters
long that is evaluated based on the operand condition in the SEEK operand
keyword. If more than one keyvalue argument is specified, BASIC assumes the
current index is based on the combination of their values.
If no match is found, the current index position is at the end of the table
and there is no current record.
If the number of keyvalues is greater than the number of values that makes
up the current index, BASIC generates the error message Syntax Error.
No error is generated if the number of keyvalues is less than the number of
values that makes up the current index. The seek either fails or is based on
the keyvalues supplied:
■ SEEKEQ with too few keyvalues always fails.
■ SEEKGE with too few keyvalues is equivalent to a SEEKGE with
the same arguments.
■ SEEKGT with too few keyvalues seeks for the first record that
matches the keyvalues supplied.
BASIC removes trailing spaces from strings used in a seek.
Note
The keyvalue expression must be explicitly typed if it is a DOUBLE or
CURRENCY value.
See Also
MOVEFIRST, MOVELAST, MOVENEXT, MOVEPREVIOUS Statements; OPEN
Example
The following example uses the CREATETABLE statement to create a new table
in an ISAM file and uses the SEEKGE, RETRIEVE, UPDATE, and INSERT
statements to insert records into the file. It uses the LOF function to
display the number of records in the new table and then deletes the table
with DELETETABLE.
The program uses a file called BOOKS.MDB, the sample ISAM file that SETUP
copies to your disk.
DEFINT A-Z
TYPE BookRec
IDNum AS DOUBLE ' Unique ID number for each book.
Title AS STRING * 50 ' Book's title.
Publisher AS STRING * 50 ' Book's publisher.
Author AS STRING * 36 ' Book's author.
Price AS CURRENCY ' Book's price.
END TYPE
CONST Database = "BOOKS.MDB" ' Name of the disk file.
DIM Library AS BookRec ' Variable for current record.
DIM MinPrice AS CURRENCY ' SEEK criteria.
CLS
DO
INPUT "Display books that cost as much or more than "; MinPrice
IF MinPrice < 0 THEN PRINT "Positive values only, please."
LOOP UNTIL MinPrice > 0
' Open existing table.
LibraryFile = FREEFILE
OPEN Database FOR ISAM BookRec "BooksStock" AS LibraryFile
CREATEINDEX LibraryFile, "Library", 0, "Price"
SETINDEX LibraryFile, "Library"
' Create and open a new table.
NewFile = FREEFILE
OPEN Database FOR ISAM BookRec "PricyBooks" AS NewFile
' Fill new table with records for all books with price >= MinPrice.
SEEKGE LibraryFile, MinPrice
DO
RETRIEVE LibraryFile, Library
INSERT NewFile, Library
MOVENEXT LibraryFile
LOOP UNTIL EOF(LibraryFile)
' First time through loop get price increase;
' second time display new price.
FOR count = 1 TO 2
CLS
PRINT SPC(18); LOF(NewFile); "books cost at least ";
PRINT USING ("$###.##"); MinPrice
PRINT " ID Number"; SPC(3); "Title"; SPC(20); "Author";
PRINT SPC(11); "Publisher"; SPC(10); "Price"
VIEW PRINT 3 TO 20
MOVEFIRST NewFile
DO
RETRIEVE NewFile, Library
PRINT Library.IDNum; " "; LEFT$(Library.Title, 20);
IF LEN(RTRIM$(Library.Title)) > 20 THEN
PRINT "... ";
ELSE
PRINT " ";
END IF
PRINT LEFT$(Library.Author, 15); " ";
PRINT LEFT$(Library.Publisher, 16); " ";
PRINT USING ("$###.##"); Library.Price
MOVENEXT NewFile
LOOP UNTIL EOF(NewFile)
IF count = 1 THEN
VIEW PRINT 20 TO 24: LOCATE 20, 1
DO
INPUT "Increase cost by how much (0-100%)"; increase
IF increase < 0 OR increase > 100 THEN PRINT "Illegal value"
LOOP UNTIL increase >= 0 AND increase <= 100
' Update records in PricyBooks.
MOVEFIRST NewFile
DO
RETRIEVE NewFile, Library
Library.Price = (Library.Price * (100 + increase)) / 100
' Overwrite record with increased price.
UPDATE NewFile, Library
CHECKPOINT' Force ISAM to flush the buffer to disk.
MOVENEXT NewFile
LOOP UNTIL EOF(NewFile)
END IF
VIEW PRINT 1 TO 19
NEXT count
' Destroy index and temporary table, close files.
DELETEINDEX LibraryFile, "Library"
CLOSE
DELETETABLE Database, "PricyBooks"
SELECT CASE Statement
────────────────────────────────────────────────────────────────────────────
Action
Executes one of several statement blocks depending on the value of an
expression.
Syntax
SELECT CASE testexpression
CASE expressionlist1
statementblock-1
CASE expressionlist2
statementblock-2
CASE ELSE
statementblock-n
END SELECT
Remarks
The following list describes the parts of the SELECT CASE statement:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
testexpression Any numeric or string expression.
statementblock-1, statementblock-2, The elements statementblock-1 to
statementblock-n statementblock-n consist of any
number of statements on one or more
lines.
expressionlist1, expressionlist2 These elements can have any of the
three following forms:
expression , expression...
expression TO expression
IS relational-operator expression
The following list describes the parts of expressionlist :
╓┌───────────────────────────────────────┌───────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
expression Any numeric or string expression.
The type of the expression must be
compatible with the type of
testexpression. (The type of the
expression will be coerced to the
same type as testexpression. For
example, if testexpression is an
integer, expressionlist can
contain a double-precision data
type.)
relational-operator Any of the following operators:
< Less than
────────────────────────────────────────────────────────────────────────────
< Less than
<= Less than or equal to
> Greater than
>= Greater than or equal to
< > Not equal
= Equal
If testexpression matches the expression list associated with a CASE
clause, then the statement block following that CASE clause is executed up
to the next CASE clause or, for the last one, up to END SELECT. Control
then passes to the statement following END SELECT.
If you use the TO keyword to indicate a range of values, the smaller value
must appear first. For example, the statements associated with the line CASE
-1 TO -5 are not executed if testexpression is -4. The line should be
written as CASE -5 TO -1.
You can use a relational operator only if the IS keyword appears. If CASE
ELSE is used, its associated statements are executed only if testexpression
does not match any of the other CASE selections. It is a good idea to have
a CASE ELSE statement in your SELECT CASE block to handle unforeseen
testexpression values.
When there is no CASE ELSE statement and no expression listed in the CASE
clauses matches testexpression, program execution continues normally.
You can use multiple expressions or ranges in each CASE clause. For
example, the following line is valid:
CASE 1 TO 4, 7 TO 9, 11, 13, IS > MaxNumber%
You also can specify ranges and multiple expressions for strings:
CASE "everything", "nuts" TO "soup", TestItem$
CASE matches strings that are exactly equal to everything, the current
value of TestItem$, or that fall between nuts and soup in alphabetical
order.
Strings are evaluated according to the ASCII values of their characters.
Lowercase letters have larger ASCII values than uppercase letters, so this
statement is true:
nuts > Nuts > NUTS
If an expression appears in more than one CASE clause, only the statements
associated with the first appearance of the expression are executed.
SELECT CASE statements can be nested. Each SELECT CASE statement must have
a matching END SELECT statement.
Examples
In the first example, SELECT CASE is used to take different actions based
on the input value:
INPUT "Enter acceptable level of risk (1-10): ", Total
SELECT CASE Total
CASE IS >= 10
PRINT "Maximum risk and potential return."
PRINT "Choose stock investment plan."
CASE 6 TO 9
PRINT "High risk and potential return."
PRINT "Choose corporate bonds."
CASE 2 TO 5
PRINT "Moderate risk and return."
PRINT "Choose mutual fund."
CASE 1
PRINT "No risk, low return."
PRINT "Choose IRA."
CASE ELSE
PRINT "Response out of range."
END SELECT
Output
Enter acceptable level of risk (1-10): 10
Maximum risk and potential return.
Choose stock investment plan.
Enter acceptable level of risk (1-10): 0
Response out of range.
In the following program, the SELECT CASE statement is used to take
different actions based on the ASCII value of a character.
' Function and control key constants.
CONST ESC = 27, DOWN = 80, UP = 72, LEFT = 75, RIGHT = 77
CONST HOME = 71, ENDKEY = 79, PGDN = 81, PGUP = 73
CLS
PRINT "Press Escape key to end."
DO
' Get a function or ASCII key.
DO
Choice$ = INKEY$
LOOP WHILE Choice$ = ""
IF LEN(Choice$) = 1 THEN' Handle ASCII keys.
SELECT CASE ASC(Choice$)
CASE ESC
PRINT "Escape key"
END
CASE IS < 32, 127
PRINT "Control code"
CASE 48 TO 57
PRINT "Digit: "; Choice$
CASE 65 TO 90
PRINT "Uppercase letter: "; Choice$
CASE 97 TO 122
PRINT "Lowercase letter: "; Choice$
CASE ELSE
PRINT "Punctuation: "; Choice$
END SELECT
ELSE' Convert 2-byte extended code to 1-byte ASCII code.
Choice$ = RIGHT$(Choice$, 1)
SELECT CASE Choice$
CASE CHR$(DOWN)
PRINT "DOWN direction key"
CASE CHR$(UP)
PRINT "UP direction key"
CASE CHR$(PGDN)
PRINT "PGDN key"
CASE CHR$(PGUP)
PRINT "PGUP key"
CASE CHR$(HOME)
PRINT "HOME key"
CASE CHR$(ENDKEY)
PRINT "END key"
CASE CHR$(RIGHT)
PRINT "RIGHT direction key"
CASE CHR$(LEFT)
PRINT "LEFT direction key"
CASE ELSE
BEEP
END SELECT
END IF
LOOP
SETINDEX Statement
────────────────────────────────────────────────────────────────────────────
Action
Makes the specified ISAM table index the current index.
Syntax
SETINDEX # filenumber% , indexname$
Remarks
The SETINDEX statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the table.
indexname$ The name used in the CREATEINDEX
statement to create the index. If
no indexname$ argument or set of
double quotation marks ("") is
specified, the null index becomes
the current index. The NULL index
represents the order in which
Argument Description
────────────────────────────────────────────────────────────────────────────
represents the order in which
records were added to the file.
After SETINDEX makes an index current, the current record is the first
record according to that index.
See Also
CREATEINDEX, DELETEINDEX, GETINDEX$
Example
See the CREATEINDEX statement programming example, which uses the SETINDEX
statement.
SETMEM Function
────────────────────────────────────────────────────────────────────────────
Action
Changes the amount of memory used by the far heap -- the area where far
objects are stored -- and returns information about the far heap.
Syntax
SETMEM( numeric- expression&)
Remarks
The SETMEM function increases or decreases the far heap by the number of
bytes indicated by numeric- expression&. If numeric-expression& is
negative, SETMEM decreases the far heap by the indicated number of bytes.
If numeric-expression& is positive, SETMEM attempts to increase the far
heap by the number of bytes. If SETMEM cannot change the far heap by the
requested number of bytes, it reallocates as many bytes as possible.
SETMEM can be used in mixed-language programming to decrease the far heap
so procedures in other languages can dynamically allocate far memory.
The information that the SETMEM function returns about the far heap depends
on the value of numeric-expression&, as follows:
╓┌─────────────────────────┌─────────────────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
Positive or negative Total number of bytes in the far heap.
0 Current size of far heap.
Note
A first call to SETMEM trying to increase the far heap has no effect
because BASIC allocates as much memory as possible to the far heap when a
program starts.
When programming with OS/2 protected mode, the SETMEM function performs no
other function than to return a dummy value. This value is the previous
SETMEM value adjusted by the SETMEM argument. The initial value for SETMEM
is 655,360.
Example
In the following example, SETMEM is used to free memory for a C routine
that uses the C function malloc to get dynamic memory. The C routine must be
separately compiled and then put in a Quick library or linked to the BASIC
program.
DECLARE SUB CFunc CDECL (BYVAL X AS INTEGER)
' Decrease the size of the far heap so CFunc can use
' malloc to get dynamic memory.
BeforeCall = SETMEM(-2048)
CFunc(1024%)' Call the C routine.
' Return the memory to the far heap; use a larger value so
' all space goes back into the heap.
AfterCall = SETMEM(3500)
IF AfterCall <= BeforeCall THEN PRINT "Memory not reallocated."
END
This routine is compiled using the large memory model, so calls to the C
function malloc use the far space freed by the BASIC program.
void far cfunc(bytes)
int bytes;
{
char *malloc();
char *workspace;
/* Allocate working memory using amount BASIC freed. */
workspace=malloc((unsigned) bytes);
/* Working space would be used here. */
/* Free memory before returning to BASIC. */
free(workspace);
}
SetUEvent Routine
────────────────────────────────────────────────────────────────────────────
Action
Sets the BASIC entry point that causes a user-defined event.
Syntax
SetUEvent
Remarks
SetUEvent is used in user-event trapping.
SetUEvent signals an event for the ON UEVENT event-handling routine.
The SetUEvent routine is a part of BASIC, and is automatically included in
compiled applications or when running QBX with the /L command-line option.
Your interrupt-service routine must call SetUEvent; it is the only way to
alert your program that the event has occurred. You can call SetUEvent from
any non-BASIC language.
To use the SetUEvent routine in the QBX environment, use any Quick library.
Outside of the QBX environment, you do not have to link to another library.
See Also
ON event, UEVENT
Example
See the UEVENT statements programming example, which uses the SetUEvent
routine.
SGN Function
────────────────────────────────────────────────────────────────────────────
Action
Indicates the sign of a numeric expression.
Syntax
SGN( numeric-expression)
Remarks
The SGN function returns a value depending on the sign of its argument:
■ If numeric-expression > 0, then SGN( numeric-expression) returns 1.
■ If numeric-expression = 0, then SGN( numeric-expression) returns 0.
■ If numeric-expression < 0, then SGN( numeric-expression) returns -1.
Example
The following example calculates and prints the solution for the input
quadratic (or second-degree) equation. The program uses the sign of a test
expression to determine how to calculate the solution.
CONST NoRealSoln=-1, OneSoln=0, TwoSolns=1
' Input coefficients of quadratic equation:
' ax^2 + bx + c = 0.
INPUT;"a = ", A
INPUT;", b = ",B
INPUT ", c = ",C
Test = B^2 - 4 * A * C
SELECT CASE SGN(Test)
CASE NoRealSoln
PRINT "This equation has no real-number solutions."
CASE OneSoln
PRINT "This equation has one solution: ";
PRINT -B/(2 * A)
CASE TwoSolns
PRINT "This equation has two solutions: ";
PRINT (-B + SQR(Test))/(2 * A) " and ";
PRINT (-B - SQR(Test))/(2 * A)
END SELECT
Output
a = 3, b = -4, c = 1
This equation has two solutions: 1 and .3333333
SHARED Statement
────────────────────────────────────────────────────────────────────────────
Action
Gives a SUB or FUNCTION procedure access to variables declared at the
module level without passing them as parameters.
Syntax
SHARED variable( ) AS type , variable( ) AS type...
Remarks
The argument variable is the module-level variable the procedure will use.
It is either an array name followed by ( ), or a variable name. The AS
type clause can be used to indicate the variable's type, which can be
INTEGER, LONG, SINGLE, DOUBLE, STRING, fixed-length string ( STRING *
length), CURRENCY, or a user-defined type.
By using either the SHARED statement in a SUB or FUNCTION procedure, or
the SHARED attribute with COMMON or DIM in the module-level code, you can
use variables in a procedure without passing them as parameters. The SHARED
attribute used with COMMON or DIM shares variables among all procedures in
a module, while the SHARED statement shares variables between a single
procedure and the module-level code.
Note
The SHARED statement shares variables only within a single compiled module.
It does not share variables with programs in the Quick library or with
procedures compiled separately and linked to the program. The SHARED
statement shares variables only between the module-level code and a SUB or
FUNCTION procedure in the same module.
The SHARED statement can appear only in a SUB or FUNCTION procedure. For
more information, see Chapter 2, "SUB and FUNCTION Procedures" in the
Programmer's Guide.
See Also
COMMON, DIM, SUB
Example
The following example calls a SUB procedure named Convert that converts the
input decimal number to its string representation in the given new base. The
string N$ is shared by the procedure and the main program.
DEFINT A-Z
DO
INPUT "Decimal number (input number <= 0 to quit): ",Decimal
IF Decimal <= 0 THEN EXIT DO
INPUT "New base: ",Newbase
N$ = ""
PRINT Decimal "base 10 equals ";
DO WHILE Decimal > 0
CALL Convert (Decimal,Newbase)
Decimal = Decimal\Newbase
LOOP
PRINT N$ " base" Newbase
PRINT
LOOP
SUB Convert (D,Nb) STATIC
SHARED N$
' Take the remainder to find the value of the current
' digit.
R = D MOD Nb
' If the digit is less than ten, return a digit (0-9).
' Otherwise, return a letter (A-Z).
IF R < 10 THEN Digit$ = CHR$(R+48) ELSE Digit$ = CHR$(R+55)
N$ = RIGHT$(Digit$,1) + N$
END SUB
SHELL Function
────────────────────────────────────────────────────────────────────────────
Action
Returns an integer value that is the OS/2 process ID for the shelled
process.
Syntax
SHELL( commandstring$)
Remarks
The argument commandstring$ is the name of the OS/2 process to be executed,
along with any command-line arguments that the executed process requires.
The command string is required.
The SHELL function is used only under OS/2 protected mode.
Like the SHELL statement, the OS/2 protected-mode SHELL function permits a
BASIC program to execute another process. In addition, the SHELL function
allows the BASIC program to continue execution without waiting for the child
process to terminate, and returns the process ID of the child process. The
process ID is used by some of the OS/2 API functions (which can be called
from BASIC).
See Also
SHELL Statement
Example
The following example uses the SHELL function to execute three OS/2
commands:
ON ERROR GOTO ErrHandler
Ext$ = CHR$(34) + " EXE" + CHR$(34)
' The child process does: DIR | FIND " EXE" | SORT
Child$ = "dir | find " + Ext$ + "| sort"
ProcessID = SHELL(Child$)
PRINT "Process ID is:" ProcessID
END
ErrHandler:
SELECT CASE ERR
CASE 73
PRINT : PRINT "You cannot use the SHELL function in DOS."
CASE ELSE
END SELECT
END
SHELL Statement
────────────────────────────────────────────────────────────────────────────
Action
Suspends execution of the BASIC program, runs a .COM, .EXE, .BAT, or .CMD
program, or a DOS or OS/2 command, and resumes execution of the BASIC
program at the statement following the SHELL statement.
Syntax
SHELL commandstring
Remarks
The argument commandstring must be a valid string expression that contains
the name of a program to run, and any program arguments.
Any .COM file, .EXE file, .BAT program, .CMD program, DOS command, or OS/2
command that runs under the SHELL statement is called a "child process."
Child processes are executed by the SHELL statement, which loads and runs a
copy of COMMAND.COM (for DOS) or CMD.EXE (for OS/2) with the /C option.
The /C option allows any parameters in commandstring to be passed to the
child process. It also allows redirection of standard input and output, and
execution of built-in commands such as DIR and PATH.
The program name in commandstring can have any extension you wish. If no
extension is supplied, COMMAND.COM (for DOS) or CMD.EXE (for OS/2) looks for
a .COM file, then an .EXE file, and finally, a .BAT file (for DOS) or a .CMD
file (for OS/2). If COMMAND.COM or CMD.EXE is not found, BASIC generates the
error message File not found. BASIC does not generate an error if
COMMAND.COM or CMD.EXE cannot find the file specified in commandstring, but
the operating system generates an error message.
COMMAND.COM or CMD.EXE treat as program parameters any text separated from
the program name by at least one blank. BASIC remains in memory while the
child process is running. When the child process finishes, BASIC continues.
If you omit the argument commandstring, SHELL gives you a new shell
(COMMAND.COM for DOS or CMD.EXE for OS/2). You then can enter
operating-system commands at the prompt. Use the EXIT command to return to
BASIC.
Note
If you are using OS/2, make sure that the SET COMSPEC configuration command
in your CONFIG.SYS file specifies the path for the CMD.EXE file. If the path
for CMD.EXE is not set, BASIC generates an error message when SHELL
searches for the CMD.EXE file.
See Also
SHELL Function
Examples
The following example shows how a single SHELL statement starts up a new
COMMAND.COM:
' Get a new COMMAND.COM
' Type EXIT at the operating system prompt to return to this program.
SHELL
If the name of a any executable file or command is provided as an argument
to the SHELL statement, that command will be executed as if it had been
invoked from the operating-system prompt. When the program is finished,
control returns to BASIC. The following use of the SHELL statement
illustrates how to display a directory listing to check the creation time of
a file:
SHELL "DIR | MORE"
SIGNAL Statements
────────────────────────────────────────────────────────────────────────────
Action
Enable, disable, or suspend event trapping for an OS/2 protected-mode
signal.
Syntax
SIGNAL( n%) ON
SIGNAL( n%) OFF
SIGNAL( n%) STOP
Remarks
The argument n% identifies an OS/2 protected-mode signal. The following
table lists the numbers of the protected-mode signals:
╓┌─────────────────────┌─────────────────────────────────────────────────────╖
Number Signal
────────────────────────────────────────────────────────────────────────────
1 Ctrl+C
2 Pipe connection broken
3 Program terminated
4 Ctrl+Break
5 Process flag A
6 Process flag B
7 Process flag C
SIGNAL( n%) OFF disables trapping of OS/2 signal n%. No trapping takes
place until another SIGNAL( n%) ON statement is executed. Events occurring
while trapping is off are ignored.
SIGNAL( n%) STOP suspends trapping of OS/2 signal n%. No trapping takes
place until a SIGNAL( n%) ON statement is executed. Events occurring while
trapping is suspended are remembered and processed when the next SIGNAL(
n%) ON statement is executed. However, remembered events are lost if
SIGNAL( n%) OFF is executed.
When a signal-event trap occurs (that is, the GOSUB is performed), an
automatic SIGNAL STOP is executed so that recursive traps cannot take
place. The RETURN operation from the trapping routine automatically
performs a SIGNAL ON statement unless an explicit SIGNAL OFF was performed
inside the routine. For more information, see Chapter 9, "Event Handling" in
the Programmer's Guide.
Note
The SIGNAL statement is available only for OS/2 protected mode.
See Also
ON event
Example
The following example uses ON SIGNAL to trap an event in the OS/2 operating
system:
PRINT "This program traps Ctrl+Break. Press Q to quit."
EVENT ON
' Set up the signal-event trap and enable.
ON SIGNAL(4) GOSUB CtrlBreak
SIGNAL(4) ON
' Wait until the signal event occurs.
DO : LOOP UNTIL UCASE$(INKEY$) = "Q"
PRINT "'Q' pressed - Program terminating normally."
END
CtrlBreak:
PRINT "A SIGNAL(4) event occurred."
PRINT "Press 'Q' to quit."
RETURN
SIN Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the sine of an angle given in radians.
Syntax
SIN( x)
Remarks
The argument x can be of any numeric type.
The sine of an angle in a right triangle is the ratio between the length of
the side opposite the angle and the length of the hypotenuse.
SIN is calculated in single precision if x# is an integer or
single-precision value. If you use any other numeric data type, SIN is
calculated in double precision.
To convert values from degrees to radians, multiply the angle (in degrees)
times π/180 (or .0174532925199433). To convert a radian value to degrees,
multiply it by 180/π (or 57.2957795130824). In both cases, π ≈ 3.141593.
See Also
ATN, COS, TAN
Example
The following example plots the graph of the polar equation r = 1 + sin (n *
Θ). This figure is sometimes known as a cardioid, owing to its resemblance
to a heart when n equals 1.
CLS
CONST PI = 3.141593
SCREEN 1 : COLOR 1,1 ' Medium resolution, blue background.
WINDOW (-3,-2)-(3,2) ' Convert screen to Cartesian coordinates.
INPUT "Number of petals = ", N
CLS
PSET (1,0) ' Set initial point.
FOR Angle = 0 TO 2 * PI STEP .02
R = 1 + SIN(N * Angle) ' Polar equation for "flower."
X = R * COS(Angle)' Convert polar coordinates to
Y = R * SIN(Angle)' Cartesian coordinates.
LINE -(X,Y)' Draw line from previous point to new point.
NEXT
END
SLEEP Statement
────────────────────────────────────────────────────────────────────────────
Action
Suspends execution of the calling program.
Syntax
SLEEP seconds&
Remarks
The optional argument seconds& determines the number of seconds to suspend
the program. The SLEEP statement suspends the program until one of the
following events occurs:
■ The time period in the argument seconds& has elapsed.
■ A key is pressed.
■ An enabled event occurs.
A BASIC event is one you can trap with an ON event statement such as ON
COM or ON TIMER. A BASIC event cannot interrupt a SLEEP suspension unless
its trapping is active when the event occurs. This means that trapping must
have been initialized with an ON event statement, turned on with an event
ON statement, and not have been disabled with an event OFF statement or
an event STOP statement.
If seconds& is 0 or is omitted, the program is suspended until a key is
pressed or an enabled event occurs.
SLEEP responds only to keystrokes that occur after it executes. SLEEP
ignores characters in the keyboard buffer that were typed before it
executed.
See Also
WAIT
Example
The following example suspends execution for 10 seconds. There is no ON
event statement, so the only way to interrupt the suspension before 10
seconds have passed is to press a key.
CLS ' Clear the screen.
PRINT "Taking a 10 second nap..."
SLEEP 10
PRINT "Awake!"
END
SOUND Statement
────────────────────────────────────────────────────────────────────────────
Action
Generates sound through the speaker.
Syntax
SOUND frequency, duration!
Remarks
The SOUND statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
frequency The frequency of the sound in
cycles per second or hertz. It
must be a numeric expression with
a value between 37 and 32,767,
inclusive.
duration! The number of system clock ticks
the sound lasts. The duration
argument accepts any positive
single-precision, floating-point
value between 0 and 65,535,
inclusive. There are 18.2 clock
ticks per second, regardless of
CPU speed.
Argument Description
────────────────────────────────────────────────────────────────────────────
CPU speed.
If duration! is 0, any current SOUND statement that is running in the
background is turned off. If no SOUND statement is running, a duration of
zero has no effect.
Note
The SOUND statement is not available in OS/2 protected mode.
See Also
PLAY (Music)
Example
The following example produces a rising and descending glissando:
FOR I = 440 TO 1000 STEP 5
SOUND I, I/1000
NEXT
FOR I = 1000 TO 440 STEP -5
SOUND I, I/1000
NEXT
SPACE$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string of spaces of length n.
Syntax
SPACE$( n)
Remarks
The expression n specifies the number of spaces you want in the string. It
is rounded to an integer and must be between 0 and 32,767, inclusive.
See Also
LSET, Print Using, RSET, SPC, String $
Example
The following example demonstrates use of the SPACE$ function:
CLS' Clear the screen.
FOR I=1 TO 5
X$=SPACE$(I)
PRINT X$;I
NEXT I
Output
1
2
3
4
5
SPC Function
────────────────────────────────────────────────────────────────────────────
Action
Skips a specified number of spaces in a PRINT, LPRINT, OR PRINT #
statement, starting at the current print position.
Syntax
SPC( n%)
Remarks
SPC can only be used with PRINT, LPRINT, or PRINT # statements. The
argument n% is a number between 0 and 32,767, inclusive, that is combined
with the width of the output line to determine the number of blank
characters to print.
A semicolon (;) is assumed to follow the SPC function. For example, the
following two print statements are equivalent:
PRINT SPC(10) FixLen1$; SPC(10) FixLen2$; SPC(10) FixLen3$
PRINT SPC(10); FixLen1$; SPC(10); FixLen2$; SPC(10); FixLen3$
Note that the SPC function does more than move the text cursor to a new
print position. For screen output it also overwrites any existing characters
on a display screen with blanks. The n% blank characters are printed
starting at the current print position.
The leftmost print position on an output line is always 1; to have any
effect, the value of n% must be greater than or equal to 1.
The rightmost print position is the current line width of the output device
(which can be set with the WIDTH statement).
The behavior of an SPC function depends on the relationship between three
values: n%, the output-line print position when the SPC function is
executed, and the current output-line width:
■ If n% is greater than the output-line width, SPC calculates
n% MOD width and generates the number of blanks indicated by
that calculation, starting at the current print position.
■ If the difference between the current print position and the
output-line width is less than n% (or n% MOD width), the SPC
function skips to the beginning of the next line and generates a
number of blanks equal to n% - (width - current print
position).
See Also
SPACE$, TAB
Example
The following example demonstrates the use of the SPC statement to insert a
number of spaces within a printed line using either the PRINT statement or
the LPRINT statement:
CLS ' Clear the screen.
PRINT "The following line is printed using standard screen print"
PRINT "zones."
PRINT : PRINT "Column 1","Column 2","Column 3","Column 4","Column 5"
PRINT : PRINT
PRINT "The next line is printed using the SPC(n%) statement to achieve"
PRINT "the same results."
PRINT
PRINT "Column 1"; SPC(6); "Column 2"; SPC(6); "Column 3";
PRINT SPC(6); "Column 4"; SPC(6); "Column 5"
Output
The following line is printed using standard screen print
zones.
Column 1 Column 2 Column 3 Column 4 Column 5
The next line is printed using the SPC(n%) statement to achieve
the same results.
Column 1 Column 2 Column 3 Column 4 Column 5
SQR Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the square root of a numeric expression.
Syntax
SQR( numeric-expression)
Remarks
The argument numeric-expression must be greater than or equal to 0.
SQR is calculated in single precision if numeric-expression is an integer
or single-precision value. If you use any other numeric data type, SQR is
calculated in double precision.
Example
The following example uses the SQR function to plot the graph of y =
sqr(abs(x)) for -9 x 9 :
SCREEN 1 : COLOR 1 ' Low-resolution color graphics mode.
WINDOW (-9,-.25)-(9,3.25) ' Convert screen to Cartesian coordinates.
LINE (-9,0)-(9,0) ' Draw x-axis.
LINE (0,-.25)-(0,3.25) ' Draw y-axis.
FOR x = -9 TO 9
LINE(x,.04)-(x,-.04) ' Put tick marks on x-axis.
NEXT x
FOR y = .25 TO 3.25 STEP .25
LINE (-.08,y)-(.12,y) ' Put tick marks on y-axis.
NEXT y
PSET (-9,3) ' Plot the first point of function.
FOR x = -9 TO 9 STEP .25
y = SQR(ABS(x)) ' SQR argument cannot be negative.
LINE -(x,y),2 ' Draw a line to the next point.
NEXT x
SSEG Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the segment address of a string (or 0 if the argument is a null
string).
Syntax
SSEG( stringvariable$)
Remarks
The argument stringvariable$ is the string variable for which you want the
segment address. It can be a simple string variable or a single element of a
string array. You cannot use fixed-length string arguments.
SSEG returns the segment address for strings. It is typically used in
mixed-language programming to obtain far addresses before passing far
strings to procedures written in other languages.
SSEG usually is used with far strings but also can be used with strings
stored in DGROUP (in which case it returns DGROUP's address). The offset of
a string can be found by using the SADD function.
In OS/2 protected mode, the SSEG function returns the selector of the
specified string variable.
See Also
BLOAD, BSAVE, DEF SEG, PEEK, POKE, SADD, SSEGADD
Example
See the sadd function programming example, which uses the SSEG function.
SSEGADD Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the far address of a string variable (both segment and offset).
Syntax
SSEGADD( stringvariable$)
Remarks
The argument stringvariable$ is the string variable for which you want an
address. It can be a simple string variable or a single element of a string
array. You cannot use fixed-length string arguments.
The SSEGADD function combines the segment and offset information into one
long integer (4 bytes).
SSEG returns the far address for a string. It is typically used in
mixed-language programming to obtain far addresses before passing far
strings to procedures written in other languages.
SSEGADD usually is used with far strings but also can be used with strings
stored in DGROUP.
The offset of a string can be found with the SADD function, while the
segment of a string can be found with the SSEG function.
See Also
BLOAD, BSAVE, DEF SEG, SADD, SSEG, PEEK, POKE
Example
The following example passes a string to a C routine. It uses SSEGADD to
obtain the memory address of the string.
DEFINT A-Z
DECLARE SUB printmessage CDECL (BYVAL farstring AS LONG)
' Create the message as an ASCIIZ string (last character null),
' as required by the C function printf.
a$ = "This is a short example of a message" + CHR$(0)
' Call the C function with pointers
CALL printmessage(SSEGADD(a$))
This C routine prints a BASIC far string on the screen:
#include <stdio.h>
/* Define a procedure which inputs a string far pointer */
void printmessage (char far *farpointer)
{
/* print the string addressed by the far pointer */
printf( "%s\n", farpointer);
}
STACK Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a long integer that is the maximum stack size that can be allocated.
Syntax
STACK
Remarks
The STACK function can be used with the stack statement to set the stack to
the maximum possible size. For example:
STACK STACK
See Also
CLEAR, STACK Statement
Example
See the FRE function programming example, which uses the STACK function.
STACK Statement
────────────────────────────────────────────────────────────────────────────
Action
Resets the size of the stack.
Syntax
STACK longinteger&
Remarks
The default stack size is 3K for DOS and 3.5K for OS/2. The minimum stack
size
(if longinteger& is 0) is 0.325K for DOS and 0.825K for OS/2.
The argument longinteger& is the number of bytes to reserve for the stack.
If longinteger& is omitted, the stack is reset to its default size. If you
request a stack space that is too large, the STACK statement allocates as
much stack space as possible.
The STACK statement is useful in programs that contain recursion and lots
of nesting of sub and function procedures.
The STACK statement is allowed only at the module level.
The STACK function can be used with the stack statement to set the stack to
the maximum possible size. For example:
STACK STACK
See Also
CLEAR, STACK Function
Example
See the FRE function programming example, which uses the STACK statement.
$STATIC, $DYNAMIC Metacommands
────────────────────────────────────────────────────────────────────────────
Action
Set aside storage for arrays, while program is either compiling ( $STATIC)
or running ( $DYNAMIC).
Syntax
REM $STATIC
'$STATIC
REM $DYNAMIC
'$DYNAMIC
Remarks
The $STATIC metacommand sets aside storage for arrays during compilation.
When the $STATIC metacommand is used, the ERASE statement reinitializes
all array values to zero (numeric arrays) or the null string (string arrays)
but does not remove the array.
The $DYNAMIC metacommand allocates storage for arrays while the program is
running. This means that the ERASE statement removes the array and frees
the memory it took for other uses. You also can use the REDIM statement to
change the size of an array allocated using $DYNAMIC.
The $STATIC and $DYNAMIC metacommands affect all arrays except implicitly
dimensioned arrays (arrays not declared in a DIM statement). Implicitly
dimensioned arrays are always allocated as if $STATIC had been used. All
arrays inside a SUB or FUNCTION procedure are dynamic unless the STATIC
keyword is included in the SUB or FUNCTION statement.
Example
See the ERASE statement programming example, which demonstrates uses of the
$DYNAMIC and $STATIC metacommands.
STATIC Statement
────────────────────────────────────────────────────────────────────────────
Action
Makes simple variables or arrays local to a DEF FN function, a FUNCTION
procedure, or a SUB procedure, and preserves values between calls.
Syntax
STATIC variable( ) AS type , variable( ) AS type...
Remarks
The STATIC statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
variable The variable the procedure will
use. It is either an array name
followed by ( ), or a variable
name.
AS type Declares the type of the variable.
The type can be INTEGER, LONG,
SINGLE, DOUBLE, STRING (for
variable-length strings), STRING
* length (for fixed-length
strings), CURRENCY, or a
user-defined type.
Argument Description
────────────────────────────────────────────────────────────────────────────
STATIC is a BASIC declaration that makes simple variables or arrays local
to a procedure (or a function defined by DEF FN) and preserves the variable
value between procedure calls.
The STATIC statement can appear only in a SUB or FUNCTION procedure or
DEF FN function. Earlier versions of BASIC required the number of
dimensions in parentheses after an array name. The number of dimensions in
BASIC is now optional.
Variables declared in a STATIC statement override variables of the same
name shared by DIM or COMMON statements in the module-level code.
Variables in a STATIC statement also override global constants of the same
name.
Usually, variables used in DEF FN functions are global to the module;
however, you can use the STATIC statement inside a DEF FN statement to
declare a variable as local to only that function.
The differences between the STATIC statement, the STATIC attribute, and
the $STATIC metacommand are:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
Statement/Attribute Differences
────────────────────────────────────────────────────────────────────────────
STATIC attribute on SUB and Declares default for variables to be
FUNCTION statements static. Variables having the same
name as variables shared by
module-level code are still shared.
STATIC statement Makes specific variables static and
overrides any variables shared by
the module-level code.
$STATIC metacommand Affects how memory is allocated for
arrays.
See Also
DEF FN, FUNCTION, SUB
Example
The following example searches for every occurrence of a certain string
expression in a file and replaces that string with another string. The
program also prints the number of substitutions and the number of lines
changed.
INPUT "Name of file";F1$
INPUT "String to replace";Old$
INPUT "Replace with";Nw$
Rep = 0 : Num = 0
M = LEN(Old$)
OPEN F1$ FOR INPUT AS #1
CALL Extension
OPEN F2$ FOR OUTPUT AS #2
DO WHILE NOT EOF(1)
LINE INPUT #1, Temp$
CALL Search
PRINT #2, Temp$
LOOP
CLOSE
PRINT "There were ";Rep;" substitutions in ";Num;" lines."
PRINT "Substitutions are in file ";F2$
END
SUB Extension STATIC
SHARED F1$,F2$
Mark = INSTR(F1$,".")
IF Mark = 0 THEN
F2$ = F1$ + ".NEW"
ELSE
F2$ = LEFT$(F1$,Mark - 1) + ".NEW"
END IF
END SUB
SUB Search STATIC
SHARED Temp$,Old$,Nw$,Rep,Num,M
STATIC R
Mark = INSTR(Temp$,Old$)
WHILE Mark
Part1$ = LEFT$(Temp$,Mark - 1)
Part2$ = MID$(Temp$,Mark + M)
Temp$ = Part1$ + Nw$ + Part2$
R = R + 1
Mark = INSTR(Temp$,Old$)
WEND
IF Rep = R THEN
EXIT SUB
ELSE
Rep = R
Num = Num + 1
END IF
END SUB
STICK Function
────────────────────────────────────────────────────────────────────────────
Action
Returns joystick coordinates.
Syntax
STICK( n%)
Remarks
The argument n% is a numeric expression whose value is an unsigned integer
from 0 to 3 that indicates which joystick coordinate value to return:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Argument Value returned
────────────────────────────────────────────────────────────────────────────
0 Indicates the x coordinate of joystick A.
1 Indicates the y coordinate of joystick A.
2 Indicates the x coordinate of joystick B.
3 Indicates the y coordinate of joystick B.
Joystick coordinates range from 1 to 200 in both directions. You must use
STICK(0) before you use STICK(1), STICK(2), or STICK(3) because STICK(0) not
only returns the x coordinate of joystick A, but also records the other
joystick coordinates. These recorded coordinates are returned by calling
STICK(1), STICK(2), or STICK(3).
Note
The STICK function is not available in OS/2 protected mode.
Example
See the STRIG statements programming example, which uses the STICK
function.
STOP Statement
────────────────────────────────────────────────────────────────────────────
Action
Terminates the program.
Syntax
STOP n%
Remarks
The STOP statement halts a program and returns the value n% to the
operating system. The value n% can be used by DOS or OS/2 batch files or by
non-BASIC programs. If n% is omitted, the STOP statement returns a value
of 0. Untrapped errors and fatal errors set the value of n% to -1.
You can place a STOP statement anywhere in a program to terminate
execution.
In a stand-alone program, STOP closes all files and returns to the
operating system; in the QBX environment, STOP leaves files open and
returns to that environment.
If you use the /D, /E, or /X compiler option on the BC command line, the
STOP statement prints line numbers as follows:
╓┌──────────────────────────┌────────────────────────────────────────────────╖
If your program has: STOP prints:
────────────────────────────────────────────────────────────────────────────
Line numbers Number of the line where execution stopped.
No line number for STOP Most recent line number.
No line numbers 0
In the QBX environment, STOP always returns an error level of 0, even if
you specify a different error level.
In some previous versions of BASIC, STOP statements were used for
debugging. In the current version of BASIC, you do not have to use STOP for
debugging.
See Also
END, SYSTEM
Example
See the ON ERROR statement programming example, which uses the STOP
statement.
STR$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string representation of the value of a numeric expression.
Syntax
STR$( numeric-expression)
Remarks
If numeric-expression is positive, the string returned by the STR$
function contains a leading blank. The VAL function complements STR$.
See Also
VAL
Example
The following example uses the STR$ function to convert a number to its
string representation and strips out the leading and trailing blanks that
BASIC ordinarily prints with numeric output:
CLS ' Clear the screen.
PRINT "Enter 0 to end."
DO
INPUT "Find cosine of: ",Num
IF Num = 0 THEN EXIT DO
X$ = STR$(Num)
NumRemBlanks$ = LTRIM$(RTRIM$(X$))
PRINT "COS(" NumRemBlanks$ ") = " COS(Num)
LOOP
Output
Enter 0 to end.
Find cosine of: 3.1
COS(3.1) = -.9991351
Find cosine of: 0
STRIG Function
────────────────────────────────────────────────────────────────────────────
Action
Returns the status of a joystick trigger.
Syntax
STRIG( n%)
Remarks
The STRIG function is used to test the joystick trigger status.
The numeric expression n% is an unsigned integer between 0 and 7 that
indicates the joystick and trigger to check. The following list describes
the values returned by the STRIG( n%) function for different values of n%:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Value Returns
────────────────────────────────────────────────────────────────────────────
0 -1 if the lower trigger on
joystick A was pressed since the
last STRIG(0) call, 0 if not.
1 -1 if the lower trigger on
joystick A is currently down, 0 if
not.
2 -1 if the lower trigger on
joystick B was pressed since the
last STRIG(2) call, 0 if not.
3 -1 if the lower trigger on
joystick B is currently down, 0 if
not.
Value Returns
────────────────────────────────────────────────────────────────────────────
not.
4 -1 if the upper trigger on
joystick A was pressed since the
last STRIG(4) call, 0 if not.
5 -1 if the upper trigger on
joystick A is currently down, 0 if
not.
6 -1 if the upper trigger on
joystick B was pressed since the
last STRIG(6) call, 0 if not.
7 -1 if the upper trigger on
joystick B is currently down, 0 if
not.
For more information on joystick-event trapping, see the entry for ON
event. You cannot use the STRIG function inside a joystick-event trap
because the trigger information used by the STRIG function will not be
available for ON STRIG.
In previous versions of BASIC, the statement STRIG ON enabled testing of
the joystick triggers; STRIG OFF disabled joystick-trigger testing. The
current version of BASIC ignores these statements. (The old STRIG ON and
STRIG OFF statements are different from the STRIG( n%) ON, STRIG( n%)
OFF, and STRIG( n%) STOP statements. The STRIG statements enable,
disable, and inhibit trapping of joystick events.)
Note
The STRIG function is not available in OS/2 protected mode.
See Also
ON event, STRIG Statements
Example
See the STRIG statements programming example, which uses the STRIG
function.
STRIG Statements
────────────────────────────────────────────────────────────────────────────
Action
Enable, disable, or suspend trapping of joystick activity.
Syntax
STRIG( n%) ON
STRIG( n%) OFF
STRIG( n%) STOP
Remarks
The argument n% is the trigger number as defined in the following table:
╓┌──┌────────┌───────────────────────────────────────────────────────────────╖
n Trigger Joystick
────────────────────────────────────────────────────────────────────────────
0 Lower First
2 Lower Second
4 Upper First
6 Upper Second
STRIG( n%) ON enables joystick-event trapping. If joystick trigger n% is
pressed after a STRIG( n%) ON statement, the routine specified in the ON
STRIG statement is executed.
The STRIG( n%) OFF statement disables joystick-event trapping. No joystick
event trapping takes place until a STRIG( n%) ON statement is executed.
Events occurring while trapping is off are ignored. However, remembered
events are lost if STRIG( n%) OFF is executed.
The STRIG( n%) STOP statement suspends joystick-event trapping. No
joystick-event trapping takes place until a STRIG( n%) ON statement is
executed. Events occurring while trapping is suspended are remembered and
processed when the next STRIG( n%) ON statement is executed. However,
remembered events are lost if STRIG( n%) OFF is executed.
When a joystick-event trap occurs (that is, the GOSUB is performed), an
automatic STRIG STOP is executed so that recursive traps cannot take
place. The RETURN operation from the trapping routine automatically
performs a STRIG ON statement unless an explicit STRIG OFF was performed
inside the routine.
In previous versions of BASIC, the STRIG ON statement enabled testing of
the joystick triggers; STRIG OFF disabled joystick-trigger testing. The
current version of BASIC ignores the STRIG ON and STRIG OFF statements.
For more information, see Chapter 9, "Event Handling" in the Programmer's
Guide.
Note
The STRIG statement is not available for OS/2 protected mode.
See Also
ON event, STRIG Function
Example
The following example sets up joystick events for two triggers on each of
two joysticks. It also displays the current x and y coordinate position of
both joysticks. If any trigger is pressed, control is passed to a routine
that indicates the state of the trigger; that is, whether the trigger is
down or up. This example exercises the STRIG statements, the STRIG
function, the ON STRIG statement, the STICK function, and the EVENT
statements.
' Turn on event processing.
EVENT ON
' Enable the upper and lower triggers on both joysticks.
STRIG(0) ON 'Lower trigger, joystick A
STRIG(2) ON 'Lower trigger, joystick B
STRIG(4) ON 'Upper trigger, joystick A
STRIG(6) ON 'Upper trigger, joystick B
' Set up joystick-event processing for each trigger.
ON STRIG(0) GOSUB JoyTriggerHandler
ON STRIG(2) GOSUB JoyTriggerHandler
ON STRIG(4) GOSUB JoyTriggerHandler
ON STRIG(6) GOSUB JoyTriggerHandler
LOCATE 22, 6
PRINT "Press a trigger on either joystick to see a complete report."
LOCATE 23, 20
PRINT "Press ANY keyboard key to end the program."
' Infinite loop waiting for a joystick event or keyboard input.
DO
LOOP WHILE INKEY$ = ""
WrapItUp:
CLS
STRIG(0) OFF
STRIG(2) OFF
STRIG(4) OFF
STRIG(6) OFF
END
JoyTriggerHandler:
' Print a label on screen.
LOCATE 10, 14: PRINT "Joystick A"
LOCATE 10, 45: PRINT "Joystick B"
LOCATE 22, 1: PRINT STRING$(80, 32)
DO
IF STRIG(1) THEN ' Trigger 1, Joystick A.
TriggerStatus$ = "DOWN"
ELSE
TriggerStatus$ = "UP "
END IF
EVENT OFF
LOCATE 16, 10: PRINT "Trigger 1 is "; TriggerStatus$
EVENT ON
IF STRIG(3) THEN ' Trigger 1, Joystick B.
TriggerStatus$ = "DOWN"
ELSE
TriggerStatus$ = "UP "
END IF
EVENT OFF
LOCATE 16, 42: PRINT "Trigger 1 is "; TriggerStatus$
EVENT ON
IF STRIG(5) THEN ' Trigger 2, Joystick A.
TriggerStatus$ = "DOWN"
ELSE
TriggerStatus$ = "UP "
END IF
EVENT OFF
LOCATE 18, 10: PRINT "Trigger 2 is "; TriggerStatus$
EVENT ON
IF STRIG(7) THEN ' Trigger 2, Joystick B.
TriggerStatus$ = "DOWN"
ELSE
TriggerStatus$ = "UP "
END IF
EVENT OFF
LOCATE 18, 42: PRINT "Trigger 2 is "; TriggerStatus$
EVENT ON
GOSUB UpdateXY
LOOP WHILE INKEY$ = ""
RETURN WrapItUp
UpdateXY:
EVENT OFF
LOCATE 12, 10: PRINT USING "X Position = ###"; STICK(0)
LOCATE 14, 10: PRINT USING "Y Position = ###"; STICK(1)
LOCATE 12, 42: PRINT USING "X Position = ###"; STICK(2)
LOCATE 14, 42: PRINT USING "Y Position = ###"; STICK(3)
EVENT ON
RETURN
STRING$ Function
────────────────────────────────────────────────────────────────────────────
Action
Returns a string whose characters all have a given ASCII code or whose
characters are all the first character of a string expression.
Syntax 1
STRING$( m%, n%)
Syntax 2
STRING$( m%, stringexpression$)
Remarks
The STRING$ function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
m% A numeric expression indicating
the length of the string to return.
n% The ASCII code of the character to
Argument Description
────────────────────────────────────────────────────────────────────────────
n% The ASCII code of the character to
use to build the string. It is a
numeric expression that BASIC
converts to an integer value
between 0 and 255, inclusive.
stringexpression$ The string expression whose first
character is used to build the
return string.
Examples
The first example uses STRING$ to create part of a report heading:
Dash$ = STRING$(10,45)
PRINT Dash$;"MONTHLY REPORT";Dash$
Output
----------MONTHLY REPORT----------
This example uses STRING$ to generate a bar graph:
PRINT TAB(7);"Daily Mean Temperature in Seattle" : PRINT
' Read and graph data for each month.
FOR Month = 1 TO 12 STEP 2
READ Month$, Temp
' Print Temp-35 stars.
PRINT Month$;" +"; STRING$(Temp-35,"*")
PRINT " |"
NEXT Month
' Print horizontal line.
PRINT " +";
FOR X = 1 TO 7
PRINT "----+";
NEXT X
PRINT
' Print temperature labels.
FOR X = 4 TO 39 STEP 5
PRINT TAB(X); X+31;
NEXT X
PRINT
DATA Jan, 40, Mar, 46, May, 56
DATA Jul, 66, Sep, 61, Nov, 46
Output
Daily Mean Temperature in Seattle
Jan +*****
|
Mar +***********
|
May +*********************
|
Jul +*******************************
|
Sep +**************************
|
Nov +***********
|
+----+----+----+----+----+----+----+
35 40 45 50 55 60 65 70
StringAddress Routine
────────────────────────────────────────────────────────────────────────────
Action
Used in mixed-language programming to returns the far address of a
variable-length string.
Syntax
far-address = StringAddress( string-descriptor%);
Remarks
The syntax above is for the C language. For MASM, Pascal, and FORTRAN
examples, see Chapter 13, "Mixed-Language Programming with Far Strings" in
the Programmer's Guide.
StringAddress returns the far address of the variable-length string defined
by string-descriptor%. The argument string-descriptor% is the near address
of a string descriptor within a non-BASIC routine.
A non-BASIC routine uses StringAddress to find the far address of a BASIC
variable-length string. Calls to the StringAddress routine always are made
from a non-BASIC routine to find the address of a string that was
transferred to BASIC from the non-BASIC routine.
For example, assume that you have passed a string from a MASM routine to
BASIC's string space using StringAssign. The descriptor for the string
exists at offset descriptor. MASM can find the far address of the string
data using the following code:
leaax, descriptor ; offset of descriptor
pushax
extrnstringaddress: proc far
callstringaddress
The far address is returned in DX:AX. DX holds the segment and AX holds the
offset.
Note
If you are not doing mixed-language programming, there usually is no reason
to use StringAddress. Instead, use SSEGADD to find the far address of a
variable-length string.
For more information on mixed-language programming with strings, see Chapter
12, "Mixed-Language Programming" and Chapter 13, "Mixed-Language Programming
with Far Strings" in the Programmer's Guide.
See Also
SSEGADD, StringAssign, StringLength, StringRelease
Example
The following example shows how to use StringAddress and StringLength,
routines in the BASIC main library.
The program creates a string in BASIC, then passes it to MASM, which uses
StringAddress to find the data that needs to be printed. It uses
StringLength to tell the system the length of the string.
DEFINT A-Z
' Create a variable-length string.
Message1$ = "This string was sent to MASM for printing."
' Pass it to MASM to be printed.
CALL PrintMessage1(Message1$)
The following MASM procedure must be assembled and the .OBJ file linked to
the BASIC code listed above.
; *************************PrintMessage1************************
; Prints a string passed by BASIC.
.model medium, basic; Use same model as BASIC.
.code
; Define procedure with one-word argument.
PrintMessage1 procuses ds, descriptor
; Define external (BASIC library) procedures.
extrnStringAddress: proc far
extrnStringLength: proc far
mov ax, descriptor ; Find length of string.
pushax
callStringLength
pushax; Save length on stack.
mov ax, descriptor ; Go find out the
pushax; address of the string
CALLStringAddress; data.
mov ds, dx ; Address of string.
mov dx, ax
mov bx, 01 ; Handle of printer.
pop cx; Length of string.
mov ah, 40h ; Have DOS print it.
int 21h
ret
PrintMessage1 endp
end
StringAssign Routine
────────────────────────────────────────────────────────────────────────────
Action
Used in mixed-language programming to transfer string data from one
language's memory space to that of another.
Syntax
StringAssign( sourceaddress&, sourcelength%, destaddress&, destlength%);
Remarks
The syntax above is for the C language. However, the order of the arguments
in the syntax follows BASIC, Pascal and FORTRAN calling conventions rather
than the C calling convention. (In BASIC, Pascal and FORTRAN, the arguments
are passed in the order in which they appear in the source code. In C, the
arguments are passed in the reverse order.)
For MASM, Pascal, and FORTRAN examples, see Chapter 13, "Mixed-Language
Programming with Far Strings" in the Programmer's Guide.
The StringAssign routine uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
sourceaddress& The far address of the start of
string data (if the source is a
fixed-length string), or the far
address of the string descriptor
(if the source is a
variable-length string). The
sourceaddress& is a long integer.
sourcelength% The string length (if the source
is a fixed-length string), or 0
(if the source is a
variable-length string). The
Argument Description
────────────────────────────────────────────────────────────────────────────
variable-length string). The
sourcelength% is an integer.
destaddress& The far address of the start of
string data (if the destination is
a fixed-length string), or the far
address of the string descriptor
(if the destination is a
variable-length string). The
destaddress& is a long integer.
destlength% The string length (if the
destination is a fixed-length
string), or0 (if the destination
is a variable-length string). The
destlength% is an integer.
The StringAssign routine is used in mixed-language programming to transfer
a string from BASIC to a non-BASIC routine or from a non-BASIC routine to
BASIC. A typical use is to transfer a string from BASIC to a non-BASIC
routine, process the string using the non-BASIC routine, and then transfer
the modified string back to BASIC.
Calls to the StringAssign routine are usually made from a C, MASM, Pascal,
or FORTRAN routine. Seldom, if ever, would you call StringAssign from
inside a BASIC program.
StringAssign can be used to transfer both near and far strings. Using
StringAssign, you can write mixed-language programs that are
near-string/far-string independent.
MASM, C, Pascal, and FORTRAN deal only with fixed-length strings. When
programming in these languages you can use StringAssign to create a new
BASIC variable-length string and transfer fixed-length string data to it.
For example, to transfer a MASM fixed-length string containing the word
"Hello" to a BASIC variable-length string, you would use the following data
structure:
fixedstringdb "Hello" ; source of data
descriptor dd 0; descriptor for destination
The second data element, descriptor, is a 4-byte string descriptor
initialized to zero. BASIC interprets this to mean that it should create a
new variable-length string and associate it with the address labelled
descriptor.
To create a new BASIC variable-length string and transfer fixed-length data
to it, the StringAssign routine requires four arguments:
■ The far address of the fixed-length string in the MASM data
segment.
■ The length of the fixed-length string in the MASM data segment.
■ The far address of the string descriptor in the MASM data
segment.
■ 0 (to indicate that the string in the BASIC data segment will be
a variable-length string).
The following MASM code pushes these arguments on the stack and calls
StringAssign:
pushds; segment of fixed-length string
lea ax, fixedstring ; offset of fixed-length string
pushax
mov ax, 5; length of "Hello"
pushax
pushds; segment of descriptor
lea ax, descriptor ; offset of descriptor
pushax
mov ax, 0 ; 0 = variable-length string
pushax
extrnstringassign: proc far
callstringassign
When the call to StringAssign is made, BASIC will fill in the double-word
descriptor with the correct string descriptor.
Note
When creating a new variable-length string, you must allocate 4 bytes of
static data for a string descriptor as shown above. Allocating the data on
the stack will not work.
For more information on mixed-language programming with strings, see Chapter
12, "Mixed-Language Programming" and Chapter 13, "Mixed-Language Programming
with Far Strings" in the Programmer's Guide.
See Also
StringAddress, StringLength, StringRelease
Example
The following example shows how to use StringAssign and StringRelease,
routines in the BASIC main library. The program gets a MASM string and
prints it on the screen.
DEFINT A-Z
' Declare external MASM procedures.
DECLARE FUNCTION MakeString$
DECLARE SUB ReleaseIt
' Get string from MASM and print it.
PRINT MakeString
' Have MASM release the variable-length string it created.
CALL ReleaseIt
The following MASM procedure must be assembled and the .OBJ file linked to
the BASIC code listed above:
; ************************** MakeString ***************************
; Create a fixed-length string and assign it to a BASIC
; variable-length string. Release the string after BASIC uses it.
.model medium, basic ; Use same model as BASIC.
.data
; Create MASM string and a place for BASIC to create a
; variable-length string descriptor.
String2db "This is a string created by MASM."
Descriptor dd 0
.code
; Declare BASIC library routines to be used.
extrnStringAssign: proc far
extrnStringRelease: proc far
MakeString proc; Push arguments:
pushds; MASM string segment
lea ax, String2; MASM string offset
pushax
mov ax, 33; MASM string length
pushax
pushds; BASIC descriptor segment
lea ax, Descriptor
pushax; BASIC descriptor offset
xor ax, ax; Variable-length indicator
pushax
callStringAssign; Assign the string.
lea ax, descriptor ; Return with descriptor
ret ; address in AX.
MakeString endp
ReleaseIt proc; Routine to release
lea ax, Descriptor ; the string.
pushax
callStringRelease
ret
ReleaseIt endp
end
StringLength Routine
────────────────────────────────────────────────────────────────────────────
Action
Used in mixed-language programming to return the length of a variable-length
string.
Syntax
length = StringLength( string-descriptor%);
Remarks
The syntax above is for the C language. For MASM, Pascal, and FORTRAN
examples, see Chapter 13, "Mixed-Language Programming with Far Strings" in
the Programmer's Guide.
A non-BASIC routine uses StringLength to return the number of characters in
a BASIC variable-length string.
Calls to the StringLength routine are usually made from a non-BASIC
routine. The argument string-descriptor% is an integer that is the near
address of a string descriptor within a non-BASIC routine.
As an example, assume that a MASM routine takes a pointer to a string
descriptor as a parameter. MASM can find the length of the string data with
the following code:
movax, psdparm; offset of descriptor
pushax
extrnstringlength: proc far
callstringlength
The length of the string is returned in AX.
Note
If you are not doing mixed-language programming, there is usually no reason
to use StringLength. Instead, use LEN to find the length of a
variable-length string.
For more information on mixed-language programming with strings, see Chapter
12, "Mixed-Language Programming" and Chapter 13, "Mixed-Language Programming
with Far Strings" in the Programmer's Guide.
See Also
L EN, StringAddress, StringAssign, StringRelease
Example
See the StringAddress routine programming example, which uses the
StringLength routine.
StringRelease Routine
────────────────────────────────────────────────────────────────────────────
Action
Deallocates variable-length strings that have been transferred to BASIC's
string space from a non-BASIC routine.
Syntax
StringRelease( string-descriptor%);
Remarks
The syntax above is for the C language. For MASM, Pascal, and FORTRAN
examples, see Chapter 13, "Mixed-Language Programming with Far Strings" in
the Programmer's Guide.
StringRelease is used in mixed-language programming. StringRelease is used
by a non-BASIC routine to deallocate variable-length strings that have been
transferred to BASIC's string space from the non-BASIC routine.
Calls to the StringRelease routine are made from a non-BASIC routine to
free up space in BASIC's data area. The argument string-descriptor% is an
integer that is the near address of a string descriptor within a non-BASIC
routine.
BASIC automatically deallocates strings allocated by BASIC. However, strings
that have been transferred to BASIC from a non-BASIC routine should be
deallocated from the non-BASIC routine using the StringRelease routine.
(The reason for this is that StringAssign transfers strings but not string
descriptors. Without the string descriptor, BASIC cannot deallocate the
string; the deallocation has to be done from the non-BASIC routine with
StringRelease.)
As an example, assume that you have passed a string from a MASM routine to
BASIC's string space using StringAssign. To deallocate this string,
assuming a descriptor for the variable-length string exists at offset
descriptor, the code would be as follows:
leaax, descriptor ; offset of descriptor
pushax
extrnstringrelease: proc far
call stringrelease
Warning
Use the StringRelease routine only to deallocate variable-length strings
that have been transferred to BASIC's string space from a non-BASIC routine.
Never use it on strings created by BASIC. Doing so may cause unpredictable
results.
For more information on mixed-language programming with strings, see Chapter
12, "Mixed-Language Programming" and Chapter 13, "Mixed-Language Programming
with Far Strings" in the Programmer's Guide.
See Also
StringAddress, StringAssign, StringLength
Example
See the StringAssign routine programming example, which uses the
StringRelease routine.
SUB Statement
────────────────────────────────────────────────────────────────────────────
Action
Declares the name and the parameters of a SUB procedure.
Syntax
SUB globalname( parameterlist) STATIC
statementblock
EXIT SUB
statementblock
END SUB
Remarks
The SUB statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
globalname A variable name up to 40
characters long. This name cannot
appear in any other SUB or
FUNCTION statement in the same
program or the user library. The
name cannot include a
type-declaration character ( %, &,
!, #, @, or $).
parameterlist The list of variables,
representing parameters, that will
be passed to the SUB procedure
when it is called. Multiple
variables are separated by commas.
Parameters are passed by reference,
Argument Description
────────────────────────────────────────────────────────────────────────────
Parameters are passed by reference,
so any change to a parameter's
value inside the SUB procedure
changes its value in the calling
program.
STATIC Indicates that the SUB
procedure's local variables are to
be saved between calls. Without
STATIC, the local variables are
allocated each time the SUB
procedure is invoked, and the
variables' values are lost when
the SUB returns to the calling
program. The STATIC attribute
does not affect variables that are
used in a SUB procedure but
declared outside the procedure in
DIM or COMMON statements using
Argument Description
────────────────────────────────────────────────────────────────────────────
DIM or COMMON statements using
the SHARED statement.
EXIT Causes an immediate exit from a
SUB. Program execution continues
with the statement after the CALL
statement.
A SUB parameterlist argument has the following syntax:
variable( ) AS type , variable( ) AS type...
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
variable A BASIC variable name. Previous
Argument Description
────────────────────────────────────────────────────────────────────────────
variable A BASIC variable name. Previous
versions of BASIC required the
number of dimensions in
parentheses after an array name.
In the current version of BASIC,
the number of dimensions is not
required.
AS type The type of the variable: INTEGER,
LONG, SINGLE, DOUBLE, CURRENCY,
STRING, or a user-defined type.
You cannot use a fixed-length
string, or an array of
fixed-length strings, as a
parameter. However, you can use a
simple fixed-length string as an
argument in a CALL statement;
BASIC converts a simple
fixed-length string argument to a
Argument Description
────────────────────────────────────────────────────────────────────────────
fixed-length string argument to a
variable-length string argument
before passing the string to a
SUB procedure.
A SUB procedure is a separate procedure, like a FUNCTION procedure.
However, unlike a FUNCTION procedure, a SUB procedure cannot be used in an
expression.
SUB and END SUB mark the beginning and end of a SUB procedure. You also
can use the optional EXIT SUB statement to exit a SUB procedure.
SUB procedures are called by a CALL statement or by using the procedure
name followed by the argument list. See the entry for the CALL statement.
BASIC SUB procedures can be
recursive -- they can call themselves to perform a given task. See the
second example below.
The STATIC attribute indicates that all variables local to the SUB
procedure are static -- their values are saved between calls. Using the
STATIC keyword increases execution speed slightly. STATIC usually is not
used with recursive SUB procedures.
Any SUB procedure variables or arrays are considered local to that SUB
procedure, unless they are explicitly declared as shared variables in a
SHARED statement. You cannot define SUB procedures, DEF FN functions, or
FUNCTION procedures inside a SUB procedure.
Note
You cannot use GOSUB, GOTO, or RETURN to enter or exit a SUB procedure.
See Also
CALL (BASIC), DECLARE (BASIC), SHARED, STATIC Statement
Examples
See the CALL (BASIC) statement programming example, which uses the SUB
statement.
SWAP Statement
────────────────────────────────────────────────────────────────────────────
Action
Exchanges the values of two variables.
Syntax
SWAP variable1, variable2
Remarks
Any type of variable can be swapped (integer, long, single precision, double
precision, string, currency, or record). However, if the two variables are
not exactly the same data type, BASIC generates the error message Type
mismatch.
Example
The following example sorts the elements of a string array in descending
order using a shell sort. It uses SWAP to exchange array elements that are
out of order.
' Sort the word list using a shell sort.
Num% = 4
Array$(1) = "New York"
Array$(2) = "Boston"
Array$(3) = "Chicago"
Array$(4) = "Seattle"
Span% = Num% \ 2
DO WHILE Span% > 0
FOR I% = Span% TO Num% - 1
J% = I% - Span% + 1
FOR J% = (I% - Span% + 1) TO 1 STEP -Span%
IF Array$(J%) <= Array$(J% + Span%) THEN EXIT FOR
' Swap array elements that are out of order.
SWAP Array$(J%), Array$(J% + Span%)
NEXT J%
NEXT I%
Span% = Span% \ 2
LOOP
CLS
FOR I% = 1 TO Num%
PRINT Array$(I%)
NEXT I%
END
SYSTEM Statement
────────────────────────────────────────────────────────────────────────────
Action
Closes all open files and returns control to the operating system.
Syntax
SYSTEM n%
Remarks
The SYSTEM statement returns control to the operating system and returns
the value n% to the operating system. The value n% can be used by DOS or
OS/2 batch files or by non-BASIC programs. If n% is omitted, the SYSTEM
statement returns a value of 0. Untrapped errors and fatal errors set the
value of n% to -1.
In a stand-alone program, SYSTEM returns to the operating system and closes
all files; in the QBX environment, SYSTEM stops program execution and
closes all files.
Note
A program containing a SYSTEM statement exits to the operating system if
run from the QBX command line with the /RUN option. Entering a SYSTEM
statement in the Immediate window terminates BASIC.
BASICA
END and SYSTEM are distinct in BASICA, but act identically in the current
version of BASIC.
See Also
END, STOP
Example
See the ON ERROR statement programming example, which uses the SYSTEM
statement.
TAB Function
Action
Moves the text cursor to a specified print position when used in the PRINT,
PRINT USING, LPRINT, LPRINT USING, and PRINT # statements.
Syntax
────────────────────────────────────────────────────────────────────────────
TAB( column%)
Remarks
The argument column% is a numeric expression that is the column number of
the new print position.
The leftmost print position is always 1. The rightmost position is the
current line width of the output device (which can be set with the WIDTH
statement).
This is an example of using TAB in the PRINT function:
PRINT TAB(10); City$; TAB(40); State$; TAB(45); Zip$
The behavior of TAB depends on the relationship between three values:
column%, the current print position on the current output line when the TAB
function is executed, and the current output-line width:
■ If the current print position on the current line is greater than
column%, TAB skips to column% on the next output line.
■ If column% is less than 1, TAB moves the print position to column 1.
■ If column% is greater than the output-line width, TAB calculates:
■ print position = column% MOD width. ■ n
If the calculated print position is less than the current print
position, the cursor jumps to the next line at the calculated print
position. If the calculated print position is greater than the current
print position, the cursor moves to the calculated print position on
the same line.
See Also
LPRINT, PRINT, SPACE$, SPC
Example
In the following example TAB is also used with the PRINT statement to
center a text string on an 80-column screen.
CLS
INPUT "What is your full name "; Name$
PRINT
' Get the length of Name$, divide by 2, and subtract from screen
' center point.
PRINT TAB(40 - (LEN(Name$) \ 2)); Name$
END
TAN Function
Action
Returns the tangent of the angle x, where x is in radians.
Syntax
TAN( x)
Remarks
The tangent of an angle in a right triangle is the ratio between the length
of the side opposite an angle and the length of the side adjacent to it.
TAN is calculated in single precision if x is an integer or
single-precision value. If you use any other numeric data type, TAN is
calculated in double precision.
To convert values from degrees to radians, multiply the angle (in degrees)
times /180
(or .0174532925199433). To convert a radian value to degrees, multiply it by
180/
(or 57.2957795130824). In both cases, 3.141593.
BASICA
In BASICA, if TAN overflows, the interpreter generates an error message
that reads Overflow, returns machine infinity as the result, and continues
execution.
If TAN overflows, BASIC does not display machine infinity and execution
halts (unless the program has an error-handling routine).
See Also
ATN, COS, SIN
Example
The following example computes the height of an object using the distance
from the object and the angle of elevation. The program draws the triangle
produced by the base and the computed height.
SCREEN 2' CGA screen mode.
INPUT "LENGTH OF BASE: ",Baselen
INPUT "ANGLE OF ELEVATION (DEGREES,MINUTES): ",Deg,Min
Ang = (3.141593/180) * (Deg + Min/60)' Convert to radians.
Height = Baselen * TAN(Ang)' Calculate height.
PRINT "HEIGHT =" Height
Aspect = 4 * (200 / 640) / 3' Screen 2 is 640 x 200 pixels.
H = 180 - Height
B = 15 + (Baselen / Aspect)
LINE (15,180)-(B,180)' Draw triangle.
LINE -(B,H)
LINE -(10,180)
LOCATE 24,1 : PRINT "Press any key to continue...";
DO
LOOP WHILE INKEY$=""
TEXTCOMP Function
Action
Compares two strings as they would be compared by ISAM.
Syntax
TEXTCOMP( a$, b$)
Remarks
The arguments a$ and b$ are two strings. TEXTCOMP compares their relative
order as they would be sorted by an ISAM index and returns an integer value
of 1, 0, or -1:
■ -1 is returned when a$ compares less than b$.
■ 0 is returned when a$ compares equal to b$.
■ 1 is returned when a$ compares greater than b$.
Only the first 255 characters are considered in the comparison.
The comparison is not case sensitive ("A" is the same as "a"), and any
trailing spaces are removed. TEXTCOMP uses the International Sorting Tables
for sorting international characters. For more information, see Appendix E,
"International Sorting Tables."
See Also
SetFormatCC; Appendix E, "International Character Sort Order Tables"
Example
The BookLook program uses TEXTCOMP to compare titles in a table named
BookStock and then prints each title that begins with the word QuickBASIC.
Because the comparison performed by TEXTCOMP is not case-sensitive, all
variations of titles whose first word is QuickBASIC will be printed.
TIME$ Function
Action
Returns the current time from the operating system.
Syntax
TIME$
Remarks
The TIME$ function returns an eight-character string in the form hh: mm:
ss, where hh is the hour (00 - 23), mm is minutes (00 - 59), and ss is
seconds (00 - 59). A 24-hour clock is used; therefore, 8:00 P.M. is shown as
20:00:00.
To set the time, use the TIME$ statement.
See Also
TIME$ Statement, TIMER Function
Example
The following example converts the 24-hour clock used by TIME$ to 12-hour
output:
T$ = TIME$
Hr = VAL(T$)
IF Hr < 12 THEN Ampm$ = " AM" ELSE Ampm$ = " PM"
IF Hr > 12 THEN Hr = Hr - 12
PRINT "The time is" STR$(Hr) RIGHT$(T$,6) Ampm$
Output
The time is 11:26:31 AM
TIME$ Statement
Action
Sets the time.
Syntax
TIME$= stringexpression$
Remarks
The TIME$ statement changes the system time, which stays changed until you
change it again or reboot your computer.
The argument stringexpression$ must be in one of the following forms:
╓┌──────────────┌────────────────────────────────────────────────────────────╖
Form Description
Form Description
────────────────────────────────────────────────────────────────────────────
hh Sets the hour; minutes and seconds default to 00.
hh:mm Sets the hour and minutes; seconds default to 00.
hh:mm:ss Sets the hour, minutes, and seconds.
A 24-hour clock is used, so 8:00 P.M. would be entered as 20:00:00.
This statement complements the TIME$ function, which returns the current
time.
See Also
TIME$ Function
Example
The following statement sets the current time to 8:00 A.M.:
TIME$="08:00:00"
TIMER Function
Action
Returns the number of seconds elapsed since midnight.
Syntax
TIMER
Remarks
The TIMER function can be used with the RANDOMIZE statement to generate a
random number. It also can be used to time programs or parts of programs.
See Also
Randomize
Example
The following example searches for the prime numbers from 3 to 10,000 using
a variation of the Sieve of Eratosthenes. The TIMER function is used to
time the program.
DEFINT A-Z
CONST UNMARK = 0, MARKIT = NOT UNMARK
DIM Mark(10000)
CLS ' Clear screen.
Start! = TIMER
Num = 0
FOR N = 3 TO 10000 STEP 2
IF NOT Mark(N) THEN
'PRINT N, ' To print the primes, remove the
' remark delimiter in front of the
' PRINT statement.
Delta = 2 * N
FOR I = 3 * N TO 10000 STEP Delta
Mark(I) = MARKIT
NEXT
Num = Num + 1
END IF
NEXT
Finish! = TIMER
PRINT
PRINT "Program took"; Finish! - Start!;
PRINT "seconds to find the"; Num; "primes "
END
Output
Program took .28125 seconds to find the 1228 primes.
TIMER Statements
Action
Enable, disable, or suspend timer-event trapping.
Syntax
TIMER ON
TIMER OFF
TIMER STOP
Remarks
TIMER ON enables timer-event trapping. A timer event occurs when n
seconds have elapsed (as specified in the ON TIMER statement). If a timer
event occurs after a TIMER ON statement, the routine specified in the ON
TIMER statement is executed.
TIMER OFF disables timer-event trapping. No timer-event trapping takes
place until a TIMER ON statement is executed. Events occurring while
trapping is off are ignored.
TIMER STOP suspends timer-event trapping. No trapping takes place until a
TIMER ON statement is executed. Events occurring while trapping is off are
remembered and processed when the next TIMER ON statement is executed.
However, remembered events are lost if TIMER OFF is executed.
When a timer-event trap occurs (that is, the GOSUB is performed), an
automatic TIMER STOP is executed so that recursive traps cannot take
place. The RETURN operation from the trapping routine automatically
performs a TIMER ON statement unless an explicit TIMER OFF was performed
inside the routine.
For more information, see Chapter 9, "Event Handling" in the Programmer's
Guide.
See Also
ON event, TIMER Function
Example
This example uses the ON TIMER statement to trap timer events. It draws a
polygon every three seconds with a random shape (three to seven sides),
size, and location.
SCREEN 1
DEFINT A-Z
DIM X(6), Y(6)
TIMER ON' Enable timer-event trapping.
ON TIMER(3) GOSUB Drawpoly' Draw a new polygon every three seconds.
PRINT "Press any key to end program"
INPUT "Press <RETURN> to start",Test$
DO
LOOP WHILE INKEY$ = ""' End program if any key pressed.
END
Drawpoly:
CLS' Erase old polygon.
N = INT(5 * RND + 2)' N is random number from 2 to 6.
FOR I = 0 TO N
X(I) = INT(RND * 319)' Get coordinates of vertices of
Y(I) = INT(RND * 199)' polygon.
NEXT
PSET (X(N), Y(N))
FOR I = 0 TO N
LINE -(X(I), Y(I)),2' Draw new polygon.
NEXT
RETURN
TRON/TROFF Statements
Action
Trace the execution of program statements.
Syntax
TRON
TROFF
Remarks
In the QBX environment, executing a TRON statement has the same effect as
selecting
Trace On from the Debug menu -- each statement is highlighted on the screen
as it executes.
The TROFF statement turns off the program trace.
The TRON and TROFF statements display line numbers only when compiled with
the Debug option or the /D option on the BC command line.
Note
The debugging features of the QBX environment make these statements
unnecessary.
Example
There is no programming example for the TRON statement.
TYPE Statement
Action
Defines a data type or ISAM table type that contains one or more elements or
table columns.
Syntax
TYPE usertype
elementname AS typename
elementname AS typename .
.
.
END TYPE
Remarks
The TYPE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
usertype A user-defined data type or ISAM
table type. The argument usertype
follows the same rules as a BASIC
variable name. In the case of an
ISAM table, usertype identifies a
user-defined table structure.
elementname An element or table column of the
Argument Description
────────────────────────────────────────────────────────────────────────────
elementname An element or table column of the
user-defined type. For a data type,
elementname follows the same
rules as a BASIC variable name.
For a table type, elementname
follows the ISAM naming
conventions.
typename A user-defined data type, nested
user-defined type (databases only),
an array, or one of the following
data types: integer, long, single
(non-ISAM types only), double,
fixed-length string, or currency .
If usertype is a table type, any elementname arguments are the names of
columns in the table. The names must be exact matches to existing column
names and must follow the ISAM naming conventions.
Note
Line numbers and line labels aren't allowed in TYPE... END TYPE blocks.
ISAM names use the following conventions:
■ They have no more than 30 characters.
■ They use only alphanumeric characters (A-Z, a-z, 0-9).
■ They begin with an alphabetic character.
■ They include no BASIC special characters.
Note
BASIC now supports user-defined types for ISAM tables, the currency data
type for dollars-and-cents math and static arrays in user-defined types.
Before you can use an ISAM table, you must declare a record type for the
records that make up the table. Instances of this type are used to pass
records to and from the table.
The following TYPE statement illustrates the use of static arrays. The
record StateData includes the CityCode static array, and the record
Washington has the same structure
as StateData:
TYPE StateData
CityCode (1 TO 100) AS INTEGER ' Declare a static array.
County AS STRING * 30
END TYPE
DIM Washington(1 TO 100) AS StateData
When you declare a static array within a user-defined type, its dimensions
must be declared with numeric constants rather than variables. For
efficiency, make sure that arrays within a user-defined type start on even
offsets. You can create very large records when you include static arrays
within records. Putting one of these records within a SUB procedure can use
large amounts of stack space.
Strings in user types must be fixed-length strings. String lengths are
indicated by an asterisk and a numeric constant. For example, the following
line defines an element named Keyword in a user-defined type as a string
with length 40:
TYPE Keyword AS STRING * 40 END TYPE
A user-defined type must be declared in a type declaration before it can be
used in the program. Although a user-defined type can be declared only in
the module-level code, you can declare a variable to be of a user-defined
type anywhere in the module, even in a SUB or FUNCTION procedure.
Use the DIM, REDIM, COMMON, STATIC, or SHARED statements to declare a
variable to be of a user-defined type.
The keyword REM cannot be used as a field name in a TYPE statement. The
text that follows REM is treated as a comment.
Note
If you have defined a table to have columns A, B, C, and D, you can use a
user-defined type that has only the columns you need (any subset of A, B, C,
and D).
See Also
OPEN
Example
See the PUT statement (file I/O) programming example, which uses the TYPE
statement.
UBOUND Function
Action
Returns the upper bound (largest available subscript) for the indicated
dimension of an array.
Syntax
UBOUND( array , dimension%)
Remarks
The UBOUND function is used with the LBOUND function to determine the size
of an array. UBOUND takes the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
array The name of the array variable to
Argument Description
────────────────────────────────────────────────────────────────────────────
array The name of the array variable to
be tested.
dimension% An integer ranging from 1 to the
number of dimensions in array;
indicates which dimension's upper
bound is returned. Use 1 for the
first dimension, 2 for the second
dimension, and so on. This
argument is optional for
one-dimensional arrays.
UBOUND returns the values listed below for an array with the following
dimensions:
DIM A(1 TO 100, 1 TO 3, -3 TO 4)
╓┌───────────────────────────┌───────────────────────────────────────────────╖
Invocation Value returned
────────────────────────────────────────────────────────────────────────────
UBOUND(A,1) 100
UBOUND(A,2) 3
UBOUND(A,3) 4
You can use the shortened syntax UBOUND( array) for one-dimensional arrays
because the default value for dimension% is 1. Use the LBOUND function to
find the lower limit of an array dimension.
See Also
DIM, LBOUND, OPTION BASE
Example
The following example shows how LBOUND and UBOUND can be used together in
a SUB procedure to determine the size of an array passed to the procedure
by a calling program.
DECLARE SUB PRNTMAT (A!())
DIM A(0 TO 3, 0 TO 3)
FOR I% = 0 TO 3
FOR J% = 0 TO 3
A(I%, J%) = I% + J%
NEXT J%
NEXT I%
CALL PRNTMAT(A())
END
SUB PRNTMAT (A()) STATIC
FOR I% = LBOUND(A, 1) TO UBOUND(A, 1)
FOR J% = LBOUND(A, 2) TO UBOUND(A, 2)
PRINT A(I%, J%); " ";
NEXT J%
PRINT : PRINT
NEXT I%
END SUB
UCASE$ Function
Action
Returns a string expression with all letters in uppercase.
Syntax
UCASE$ ( stringexpression$)
Remarks
The UCASE$ function takes a string variable, string constant, or string
expression as its single argument. UCASE$ works with both variable- and
fixed-length strings.
UCASE$ and LCASE$ are helpful in making string comparisons that are not
case-sensitive.
See Also
LCASE$
Example
This example contains a FUNCTION procedure, YesQues, that returns a Boolean
value depending on how the user responds. The procedure uses UCASE$ to make
a non-
case-sensitive test of the user's response.
DEFINT A-Z
FUNCTION YesQues(Prompt$,Row,Col) STATIC
OldRow=CSRLIN
OldCol=POS(0)
' Print prompt at Row, Col.
LOCATE Row,Col : PRINT Prompt$ "(Y/N):";
DO
' Get the user to press a key.
DO
Resp$=INKEY$
LOOP WHILE Resp$=""
Resp$=UCASE$(Resp$)
' Test to see if it's yes or no.
IF Resp$="Y" OR Resp$="N" THEN
EXIT DO
ELSE
BEEP
END IF
LOOP
PRINT Resp$;' Print the response on the line.
LOCATE OldRow,OldCol' Move the cursor back to the old position.
YesQues=(Resp$="Y")' Return a Boolean value.
END FUNCTION
DO
LOOP WHILE NOT YesQues("Do you know the frequency?",12,5)
UEVENT Statements
Action
Enable, disable, or suspend a user-defined event.
Syntax
UEVENT ON
UEVENT OFF
UEVENT STOP
Remarks
The effects of the UEVENT statements are like those of other event-trapping
statements (such as COM or KEY). When UEVENT ON is executed, the
event-trapping routine is enabled. Occurrences of the event trigger
execution of the event-handling routine.
When UEVENT OFF is executed, the event-trapping routine is disabled. Any
occurrences of the event are ignored.
When UEVENT STOP is executed, the event-trapping routine is suspended. An
event occurrence is remembered, and the event-trapping routine performed as
soon as a UEVENT ON statement is executed.
When a user-defined event trap occurs (that is, the GOSUB is performed), an
automatic UEVENT STOP is executed so that recursive traps cannot take
place. The RETURN operation from the trapping subroutine automatically
performs a UEVENT ON statement unless an explicit UEVENT OFF was performed
inside the subroutine.
See Also
ON event, SetUEvent
Example
The following example shows a primitive use of the ON UEVENT statement.
PRINT "Entering an odd number causes a UEVENT to occur."
ON UEVENT GOSUB Event1
UEVENT ON
DO
PRINT "Enter a number --> ";
N = VAL(INPUT$(1)): PRINT N: PRINT
SELECT CASE N
CASE 1, 3, 5, 7, 9
CALL SetUevent 'Odd number was entered, causing UEVENT.
CASE ELSE
PRINT "No UEVENT occurred.": PRINT
END SELECT
LoopCount = LoopCount + 1
LOOP UNTIL LoopCount = 10
Event1:
PRINT "Now processing the UEVENT. The odd number was"; N
RETURN
UNLOCK Statement
Action
Releases locks applied to parts of a file.
Syntax
UNLOCK # filenumber% , { record& | start& TO end&}
Remarks
The UNLOCK statement is used only after a LOCK statement. See the entry
for the LOCK statement for a complete discussion.
The UNLOCK statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the file.
record& The number of the record or byte
to be locked. The argument
record& can be any number between
1 and 2,147,483,647 (equivalent to
231 -1), inclusive. A record can
be up to 32,767 bytes in length.
start& The number of the first record or
byte to be locked.
end& The number of the last record or
byte to be locked..
For binary-mode files, record&, start&, and end& represent the number of
a byte relative to the beginning of the file. The first byte in a file is
byte 1.
For random-access files, record&, start&, and end& represent the number
of a record relative to the beginning of the file. The first record is
record 1.
Warning
Be sure to remove all locks with an UNLOCK statement before closing a file
or terminating your program. Failing to remove locks produces unpredictable
results.
The arguments to LOCK and UNLOCK must match exactly.
Do not use LOCK and UNLOCK on devices or ISAM tables.
See Also
LOCK... UNLOCK
Example
See the LOCK... UNLOCK statement programming example, which uses the
UNLOCK statement.
UPDATE Statement
Action
Adds an updated record to an ISAM table, overwriting the current record.
Syntax
UPDATE # filenumber%, recordvariable
Remarks
The UPDATE statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
filenumber% The number used in the OPEN
statement to open the table.
recordvariable A variable of the user-defined
type tabletype that was specified
in the OPEN statement. It is the
record that will overwrite the
current record.
UPDATE replaces the current record with recordvariable. It remains the
current record.
Use the RETRIEVE statement to fetch the current record and place its data
into recordvariable. You can change the data in recordvariable, then use
the UPDATE statement to update the current record with the changes you've
made. Use INSERT to add a record to a table without overwriting the current
record.
If the values passed to recordvariable do not match the record strucure in
the user-defined type, BASIC generates the error message Type Mismatch.The
record structure includes the names and types of columns or fields.
BASIC removes trailing spaces from strings used in an update.
See Also
INSERT; RETRIEVE; SEEKGT, SEEKGE, SEEKEQ
Example
See the programming example for the SEEKGT, SEEKGE, and SEEKEQ
statements, which uses the UPDATE statement.
VAL Function
Action
Returns the numeric value of a string of digits.
Syntax
VAL( stringexpression$)
Remarks
The argument stringexpression$ is a sequence of characters that can be
interpreted as a numeric value. The VAL function stops reading the string
at the first character that it cannot recognize as part of a number. The
VAL function also strips blanks, tabs, and line feeds from the argument
string. For example, the code below returns the value 1615198:
VAL(" 1615 198th Street")
See Also
STR$
Example
The following example prints the names and addresses of people with specific
telephone area codes:
' This part of the program builds a sample data file.
OPEN "PHONE.DAT" FOR OUTPUT AS #1
CLS
RESTORE
READ FuName$, ACPhone$
I = 0
DO WHILE UCASE$(FuName$) <> "END"
I = I + 1
WRITE #1, FuName$, ACPhone$
READ FuName$, ACPhone$
IF FuName$ = "END" THEN EXIT DO
LOOP
CLOSE #1
DATA "Bob Hartzell ","206-378-3223"
DATA "Alice Provan ","213-884-9700"
DATA "Alex Landow ","213-456-3111"
DATA "Walt Riley ","503-248-0048"
DATA "Georgette Gump ","213-222-2222"
DATA "END",0,0,0,0,0
' This part of the program demonstrates the VAL function.
INPUT "Search for which area (206, 213, or 503): ", Targetarea
OPEN "PHONE.DAT" FOR INPUT AS #1
DO WHILE NOT EOF(1)
INPUT #1, Nm$, Phonenum$
'VAL reads everything up to the first non-numeric
'character ("-" in this case).
Area = VAL(Phonenum$)
IF Area = Targetarea THEN
PRINT
PRINT Nm$;
PRINT Phonenum$
END IF
LOOP
CLOSE
KILL "PHONE.DAT"
END
VARPTR$ Function
Action
Returns a string representation of a variable's address for use in DRAW and
PLAY statements.
Syntax
VARPTR$( variablename)
Remarks
The argument variablename is the name of a variable in the program. If
variablename is an array element, dimensions for the array must be specified
before VARPTR$ is used. The array must consist of variable-length strings.
Note
To guarantee correct results, use the value returned by VARPTR$ immediately
after invoking the function.
BASICA
In this version of BASIC, VARPTR$ must be used in the DRAW and PLAY
statements to execute substrings containing variables. BASICA supports both
the VARPTR$ syntax and the syntax containing just the variable name.
See Also
DRAW; PLAY Statement (Music); VARPTR, VARSEG
Example
See the PLAY function programming example, which uses the VARPTR$
function.
VARPTR, VARSEG Functions
Action
Return the address of a variable or string descriptor.
Syntax
VARPTR( variablename)
VARSEG( variablename)
Remarks
The argument variablename can be any BASIC variable, including a record
variable or record element.
VARPTR and VARSEG return the address of a variable (for numeric variables)
or the address of a string descriptor (for string variables) as indicated in
the following table:
╓┌────────────────────────┌────────────────────────┌─────────────────────────╖
For a variable of type: VARSEG returns: VARPTR returns:
────────────────────────────────────────────────────────────────────────────
Numeric Segment address of Offset address of
variable variable
String Segment address of Offset address of string
string descriptor descriptor (near strings)
(near strings)
Name not previously Segment address of new Offset address of new
defined variable ( VARSEG also variable ( VARPTR also
creates the new creates the new
variable) variable)
When variablename is a numeric variable, the VARPTR function returns an
unsigned integer (the offset of the variable within its segment). When
variablename is a numeric variable, the VARSEG function returns an unsigned
integer (the segment address of the variable). When variablename is a
near-string variable, VARSEG and VARPTR return a string-descriptor address
that contains the length of the string and the address at which it is
stored.
If variablename is not defined before VARPTR or VARSEG is called, the
variable is created and its address is returned.
VARPTR and VARSEG are often used with Absolute, BLOAD, BSAVE,
Interrupt, PEEK, POKE, or when passing arrays to procedures written in
other languages. When using VARPTR or VARSEG to get the address of an
array, use the first element of the array as the argument:
DIM A(150)
.
.
.
ArrAddress=VARPTR(A(1))
You can use VARPTR alone to get the address of a variable stored in DGROUP.
You must use both VARPTR and VARSEG to get the complete address of a
variable stored in far memory.
When programming with OS/2 protected mode, the VARSEG function returns the
selector of the specified variable or array.
Note
Because many BASIC statements move variables in memory, use the values
returned by VARPTR and VARSEG immediately after the functions are used.
It is not meaningful to use VARSEG and VARPTR for far strings, since the
format of the far strings' string descriptor is different from the string
descriptor for near strings. See the entry for StringAddress for
information on locating the address of a far string's string descriptor. See
the entries for SSEG, SADD, and SSEGADD for information on locating the
segment and offset addresses of far strings.
You can no longer use VARPTR to get the address of a file's buffer. Use the
FILEATTR function to get information about a file.
Programs written in earlier versions of BASIC that used VARPTR to access
numeric arrays may no longer work. You must now use a combination of VARPTR
and VARSEG. For example, the following QuickBASIC Version 3.0 fragment no
longer works correctly:
DIM Cube(675)
.
.
.
BSAVE "graph.dat",VARPTR(Cube(1)),2700
The fragment could be rewritten as follows to work with the current version
of BASIC:
DIM Cube(675)
.
.
.
' Change segment to segment containing Cube.
DEF SEG=VARSEG(Cube(1))
BSAVE "graph.dat",VARPTR(Cube(1)),2700
DEF SEG' Restore BASIC segment.
The VARSEG function, combined with VARPTR, replaces the PTR86 subprogram
used in previous versions of BASIC.
VARPTR and VARSEG and Expanded Memory Arrays
Do not pass expanded memory arrays to non-BASIC procedures. If you start QBX
with the /Ea switch, any of these arrays may be stored in expanded memory:
■ Numeric arrays less than 16K in size.
■ Fixed-length string arrays less than 16K in size.
■ User-defined-type arrays less than 16K in size.
If you want to pass expanded memory arrays to non-BASIC procedures, first
start QBX without the /Ea switch. (Without the /Ea switch, no arrays are
stored in expanded memory.)
For more information on using expanded memory, see "Memory Management for
QBX" in Getting Started.
See Also
DEF SEG, PEEK, POKE, SADD, VARPTR$
Example
The following example illustrates how to use the VARPTR and VARSEG
functions in a CALL statement to pass a BASIC array to a C routine.
DEFINT A-Z
DECLARE SUB AddArr CDECL (BYVAL Offs, BYVAL Segm, BYVAL Num)
DIM A(1 TO 100) AS INTEGER
' Fill the array with the numbers 1 to 15.
FOR I = 1 TO 15
A(I) = I
NEXT I
'
' Call the C function. AddArr expects a far address (segment
' and offset). Because CDECL puts things on the stack from
' right to left, put the offset ( VARPTR(A(1)) ) first in the
' list, followed by the segment ( VARSEG(A(1)) ).
'
CALL AddArr(VARPTR(A(1)), VARSEG(A(1)), 15)
'
' Print the modified array.
FOR I = 1 TO 15
PRINT A(I)
NEXT I
END
This C routine increments values of a BASIC array. It must be compiled and
the .OBJ file linked to the BASIC code above.
/* Add one to the first num elements of array arr.*/
void far addarr(arr,num)
int far *arr;
int num;
{
int i;
for(i=0;i<num;i++) arr[i]++;
}
VIEW Statement
Action
Defines screen limits for graphics output.
Syntax
VIEW SCREEN ( x1!, y1!)-( x2!, y2!) , color& , border&
Remarks
The list below describes the parts of the VIEW statement:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
SCREEN Specifies that coordinates of
subsequent graphics statements are
absolute to the screen, not
relative to the viewport. Only
graphics within the viewport are
plotted. When SCREEN is omitted,
all points are plotted relative to
the viewport ( x1! and y1! are
added to the coordinates before
Part Description
────────────────────────────────────────────────────────────────────────────
added to the coordinates before
plotting the point).
( x1!, y1!)-( x2!, y2!) Indicates a rectangular area on
the screen. The arguments x1!,
y1!, x2!, and y2! are numeric
expressions that are the
coordinates of diagonally opposite
corners of the viewport. The
argument ( x1!, y1!)-( x2!, y2!)
must be within the physical bounds
of the screen in the current
screen mode.
color& A numeric expression that
specifies the color with which to
fill the viewport. If you omit
color&, the viewport area is not
filled (it has the same color as
Part Description
────────────────────────────────────────────────────────────────────────────
filled (it has the same color as
the screen background color).
border& Any numeric expression for
border& causes a line to be drawn
around the viewport. The value of
border determines the color of the
line. If you omit border&, no
line is drawn around the viewport.
The VIEW statement defines a viewport or "clipping region," which is a
rectangular section of the screen to which graphics output is limited. If
VIEW is used with no arguments, the entire screen is defined as the
viewport. RUN and SCREEN also define the entire screen as the viewport.
See Also
PRINT, SCREEN Statement, WINDOW
Examples
See the WINDOW statement programming example, which uses the VIEW
statement.
VIEW PRINT Statement
Action
Sets the boundaries of the screen text viewport.
Syntax
VIEW PRINT topline% TO bottomline%
Remarks
The argument topline% is the number of the upper line in the text viewport;
bottomline% is the number of the lower line.
Without topline% and bottomline% parameters, the VIEW PRINT statement
initializes the whole screen area as the text viewport. The number of lines
in the screen depends on the screen mode and whether or not the /H option
was used when BASIC was started. For more information, see the entry for the
WIDTH statement, and Chapter 3, "File and Device I/O" in the Programmer's
Guide.
Statements and functions that operate within the defined text viewport
include CLS, INPUT, LOCATE, PRINT, the SCREEN function, and WRITE.
See Also
CLS, LOCATE, PRINT, SCREEN Function, SCREEN Statement, WIDTH
Example
The following example draws random circles in a graphics viewport and prints
in a text viewport. The graphics viewport is cleared after 30 circles have
been drawn. The program clears the text viewport after printing to it 45
times.
RANDOMIZE TIMER
SCREEN 1
' Set up a graphics viewport with a border.
VIEW (5, 5)-(100, 80), 3, 1
' Set up a text viewport.
VIEW PRINT 12 TO 24
' Print a message on the screen outside the text viewport.
LOCATE 25, 1: PRINT "Press any key to stop."
Count = 0
DO
' Draw a circle with a random radius.
CIRCLE (50, 40), INT((35 - 4) * RND + 5), (Count MOD 4)
' Clear the graphics viewport every 30 times.
IF (Count MOD 30) = 0 THEN CLS 1
PRINT "Hello. ";
' Clear the text viewport every 45 times.
IF (Count MOD 45) = 0 THEN CLS 2
Count = Count + 1
LOOP UNTIL INKEY$ <> ""
WAIT Statement
Action
Suspends program execution while monitoring the status of a machine input
port.
Syntax
WAIT portnumber, and-expression% , xor-expression%
Remarks
The WAIT statement uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
Argument Description
────────────────────────────────────────────────────────────────────────────
portnumber An unsigned integer expression
between 0 and 65,535, inclusive,
that is the number of the machine
input port.
and-expression% An integer expression that is
repeatedly combined with the bit
pattern received at the port,
using an AND operator; when the
result is nonzero, the WAIT
statement stops monitoring the
port, and program execution
resumes with the next program
statement.
xor-expression% Can be used to turn bits on and
off in the received bit pattern
before the AND operation is
applied.
Argument Description
────────────────────────────────────────────────────────────────────────────
applied.
The WAIT statement is an enhanced version of the INP function; it suspends
execution until a specified bit pattern is input from an input port, using
the following four steps:
■ 1. The data byte read from the port is combined, using an XOR
operation, with
xor-expression%. If xor-expression% is omitted, it is assumed to be
0.
■ 2. The result is combined with and-expression% using an AND
operation.
■ 3. If the result is zero, the first two steps are repeated.
■ 4. If the result is nonzero, execution continues with the next program
statement.
It is possible to enter an infinite loop with the WAIT statement if
the input port fails to develop a non-zero bit pattern. In this case,
you must manually restart the machine.
■ The following example program line illustrates the syntax of the WAIT
statement:
WAIT HandShakePort, 2
This statement will cause BASIC to do an AND operation on the bit pattern
received at the DOS I/O port HandShakePort with the bit pattern represented
by 2 (00000010).
Note
The WAIT statement is not available in OS/2 protected mode.
See Also
INP, OUT
Example
The following example demonstrates the use of the WAIT statement.
' Open and close the port at the proper baud rate.
OPEN "COM1:9600,N,8,1,BIN" FOR RANDOM AS #1
CLOSE #1
PortNum% = &H3F8 'COM1
NonPrintCharMask% = 96
' Wait until there's some activity on COM1.
' Mask out characters less than 32 for the first input character.
LOCATE 12, 15: PRINT "Waiting for a printable input character. "
WAIT PortNum%, NonPrintCharMask%
' Once a printable character comes in, execution continues.
DO
'Get a character from the port and evaluate.
A% = INP(PortNum%)
SELECT CASE A%
CASE 7
Character$ = " BELL "
CASE 8
Character$ = "BACK SPACE "
CASE 9
Character$ = " TAB "
CASE 13
Character$ = " CR "
CASE 32
Character$ = " SPACE "
CASE 127
Character$ = " DEL "
CASE IS < 31, IS > 127
Character$ = "unprintable"
CASE ELSE
Character$ = SPACE$(5) + CHR$(A%) + SPACE$(5)
END SELECT
LOCATE 12, 15
' Report the input character.
PRINT "Numeric Value ASCII Character"
LOCATE 14, 20
PRINT A%; TAB(50); Character$
IF A% > 127 THEN STOP
LOCATE 23, 25
PRINT "Press ANY key to quit."
LOOP WHILE INKEY$ = ""
END
WHILE...WEND Statement
Action
Executes a series of statements in a loop, as long as a given condition is
true.
Syntax
WHILE condition
.
.
.
WEND
Remarks
The argument condition is a numeric expression that BASIC evaluates as
true (nonzero) or
false (zero).
If condition is true (that is, if it does not equal zero), then any
intervening statements are executed until the WEND statement is
encountered. BASIC then returns to the WHILE statement and checks
condition. If it is still true, the process is repeated. If it is not true
(or if it equals zero), execution resumes with the statement following the
WEND statement.
Note
BASIC's DO... LOOP statement provides a more powerful and flexible
loop-control structure.
WHILE... WEND loops can be nested to any level. Each WEND matches the most
recent WHILE. When BASIC encounters an unmatched WHILE statement, it
generates the error message WHILE without WEND. If BASIC encounters an
unmatched WEND statement, it generates the error message WEND without
WHILE.
Note
Do not branch into the body of a WHILE... WEND loop without executing the
WHILE statement. This may cause run-time errors or program problems that are
difficult to locate.
See Also
DO... LOOP
Example
The following example performs a bubble sort on the array A$. Assigning the
variable Exchange a non-zero value (true) forces one pass through the
WHILE... WEND loop (this construction is unnecessary with DO... LOOP). When
there are no more swaps, all elements of A$ are sorted, Exchange is false
(equal to zero), and the program continues execution with the line following
the WEND statement.
' Bubble sort of array A$.
CONST FALSE = 0, TRUE = -1
DIM I AS INTEGER
DIM A$(4)
A$(1) = "New York"
A$(2) = "Boston"
A$(3) = "Chicago"
A$(4) = "Seattle"
Max = UBOUND(A$)
Exchange = TRUE ' Force first pass through the array.
WHILE Exchange ' Sort until no elements are exchanged.
Exchange = FALSE
' Compare the array elements by pairs. When two are exchanged,
' force another pass by setting Exchange to TRUE.
FOR I = 2 TO Max
IF A$(I - 1) > A$(I) THEN
Exchange = TRUE
SWAP A$(I - 1), A$(I)
END IF
NEXT
WEND
CLS
FOR I = 1 TO 4
PRINT A$(I)
NEXT I
END
WIDTH Statements
Action
Assign an output-line width to a device (such as a printer) or to a file, or
change the number of columns and lines displayed on the screen.
Syntax
WIDTH screenwidth% , screenheight%
WIDTH { #filenumber% | device$}, width%
WIDTH LPRINT width%
Remarks
The different forms of the WIDTH statements are explained in the following
list:
WIDTH screenwidth% , screenheight%
Sets number of columns and lines to display on the screen. The value of
screenwidth% must be either 40 or 80; default is 80. The table below has
details about the value of screenheight%.
WIDTH # filenumber%, width%
Sets to width% the output-line width of an output device already opened as
a file (for example, LPT1 or CONS). The argument filenumber% is the number
used to open the file with the OPEN statement. The number sign (#) in front
of filenumber% is not optional.This form permits altering the width while a
file is open, because the statement takes effect immediately.
WIDTH device$, width%
Sets to width% the line width of device (a device filename). The device
should be a string expression (for example, "LPT1:"). Note that he width%
assignment is deferred until the next OPEN statement affecting the device.
The assignment does not affect output for an already open file.
WIDTH LPRINT width%
Sets to width% the line width of the line printer, for use by subsequent
LPRINT statements. Equivalent to the statement form:WIDTH "LPT1:",
width%Not all of the argument values are valid in every case; it depends on
the installed display adapter and the screen mode established by the most
recently executed SCREEN statement. The value of screenheight% may be 25,
30, 43, 50, or 60, depending on the display adapter used and the screen
mode.
Table 1.21 lists the number of lines that can be displayed when a program is
started.
See Also
SCREEN Statement, VIEW PRINT
Example
The following example demonstrates the effect of the WIDTH statement on
output:
CLS
' Open the port at the proper baud rate.
OPEN "COM1:9600,N,8,1,ASC,LF" FOR OUTPUT AS #1
Test$ = "1234567890"' Set up a test string.
WIDTH #1, 3' Change width to 3.
PRINT #1, Test$
Output
123
456
789
0
WINDOW Statement
Action
Defines the dimensions of the current graphics viewport window.
Syntax
WINDOW SCREEN ( x1!, y1!) - ( x2!, y2!)
Remarks
The WINDOW statement allows the user to create a customized coordinate
system to draw lines, graphs, or objects without being constrained by the
physical coordinate values and orientation of the graphics viewport. This is
done by redefining the graphics viewport coordinates with the "view
coordinates" ( x1!, y1!) and ( x2!, y2!). These view coordinates are
single-precision numbers.
WINDOW defines a coordinate system that is mapped to the physical
coordinates of the viewport. All subsequent graphics statements use the
window coordinates and are displayed within the current viewport. (The size
of the viewport can be changed with the VIEW statement.)
The RUN statement, or WINDOW with no arguments, disables the window
transformation. (The window coordinates are the same as the viewport
coordinates.) The WINDOW SCREEN variant inverts the normal Cartesian
direction of the y coordinate, so y values go from negative to positive from
top to bottom.
Figure 1.1 shows the effects of WINDOW and WINDOW SCREEN on a line drawn
in screen mode 2. Notice the change in the coordinates of the screen
corners.
See Also
SCREEN Statement, VIEW, WIDTH
Example
The following example uses BASIC graphics statements to generate a fractal.
This fractal shows a subset of a class of numbers known as complex numbers;
this subset is called the "Mandelbrot Set," named after an IBM researcher.
The program uses the VIEW, WINDOW, PMAP, and PSET statements.
DEFINT A-Z ' Default variable type is integer.
DECLARE SUB ScreenTest (EM%, CR%, VL%, VR%, VT%, VB%)
' Set maximum number of iterations per point.
CONST MAXLOOP = 30, MAXSIZE = 1000000
CONST FALSE = 0, TRUE = NOT FALSE ' Boolean constants.
' Set window parameters.
CONST WLeft = -1000, WRight = 250, WTop = 625, WBottom = -625
' Call ScreenTest to find out if this is an EGA machine,
' and get coordinates of viewport corners.
ScreenTest EgaMode, ColorRange, VLeft, VRight, VTop, VBottom
' Define viewport and corresponding window.
VIEW (VLeft, VTop)-(VRight, VBottom), 0, ColorRange
WINDOW (WLeft, WTop)-(WRight, WBottom)
LOCATE 24, 10: PRINT "Press any key to quit.";
XLength = VRight - VLeft
YLength = VBottom - VTop
ColorWidth = MAXLOOP \ ColorRange
' Loop through each pixel in viewport and calculate
' whether or not it is in the Mandelbrot Set.
FOR Y = 0 TO YLength ' Loop through every line in the viewport.
LogicY = PMAP(Y, 3) ' Get the pixel's logical y coordinate.
PSET (WLeft, LogicY) ' Plot leftmost pixel in the line.
OldColor = 0 ' Start with background color.
FOR X = 0 TO XLength ' Loop through every pixel in the line.
LogicX = PMAP(X, 2) ' Get the pixel's logical x coordinate.
MandelX& = LogicX
MandelY& = LogicY
' Do the calculations to see if this point is in
' the Mandelbrot Set.
FOR I = 1 TO MAXLOOP
RealNum& = MandelX& * MandelX&
ImagNum& = MandelY& * MandelY&
IF (RealNum& + ImagNum&) >= MAXSIZE THEN EXIT FOR
MandelY& = (MandelX& * MandelY&) \ 250 + LogicY
MandelX& = (RealNum& - ImagNum&) \ 500 + LogicX
NEXT I
' Assign a color to the point.
PColor = I \ ColorWidth
' If color has changed, draw a line from the
' last point referenced to the new point,
' using the old color.
IF PColor <> OldColor THEN
LINE -(LogicX, LogicY), (ColorRange - OldColor)
OldColor = PColor
END IF
IF INKEY$ <> "" THEN END
NEXT X
' Draw the last line segment to the right edge of
' the viewport.
LINE -(LogicX, LogicY), (ColorRange - OldColor)
NEXT Y
DO : LOOP WHILE INKEY$ = ""
SCREEN 0, 0 ' Restore the screen to text mode,
WIDTH 80 ' 80 columns.
END
BadScreen: ' Error handler that is invoked if
EgaMode = FALSE ' there is no EGA graphics card.
RESUME NEXT
' The ScreenTest SUB procedure tests to see if user has EGA hardware
' EGA hardware with SCREEN 8. If this causes an error, the EM flag
' is set to FALSE, and the screen is set with SCREEN 1. ScreenTest
' also sets values for corners of viewport (VL = left, VR = right,
' VT = top, VB = bottom), scaled with the correct aspect ratio so
' that the viewport is a perfect square.
SUB ScreenTest (EM, CR, VL, VR, VT, VB) STATIC
EM = TRUE
ON ERROR GOTO BadScreen
SCREEN 8, 1
ON ERROR GOTO 0
IF EM THEN ' No error, so SCREEN 8 is OK.
VL = 110: VR = 529
VT = 5: VB = 179
CR = 15 ' 16 colors (0 - 15).
ELSE ' Error, so use SCREEN 1.
SCREEN 1, 1
VL = 55: VR = 264
VT = 5: VB = 179
CR = 3 ' 4 colors (0 - 3).
END IF
END SUB
WRITE Statement
Action
Sends data to the screen.
Syntax
WRITE expressionlist
Remarks
The argument expressionlist specifies one or more values to be written on
the screen, separated by commas, with double quotation marks around the
strings and no spaces around numbers.
If expressionlist is omitted, a blank line is written. If expressionlist
is included, the values of the expressions are written to the screen. The
expressions in the list can be numeric and/or string expressions. They must
be separated by commas.
When the printed items are written, each item is separated from the last by
a comma. Printed strings are delimited by quotation marks. After the last
item in the list is printed, BASIC inserts a carriage-return-and-line-feed
sequence. The WRITE statement writes numeric values without leading or
trailing spaces.
See Also
PRINT, PRINT USING
Example
The following example shows the difference between the PRINT and WRITE
statements:
CLS ' Clear screen.
A=80 : B=90 : C$="That's all." : D=-1.0E-13
WRITE A,B,C$,D
PRINT A,B,C$,D
Output
80,90,"That's all.",-1E-13
80 90 That's all. -1E-13
WRITE # Statement
Action
Writes data to a sequential file.
Syntax
WRITE #filenumber%, expressionlist
Remarks
The filenumber% is the number used in the OPEN statement to open the file
that will contain the data being written. The file must be opened in output
or append mode. The expressions in the argument expressionlist are string
and/or numeric expressions, separated by commas. If you omit
expressionlist, the WRITE # statement writes a blank line to the file.
The WRITE # statement, unlike the PRINT # statement, inserts commas
between items and quotation marks around strings as they are written to the
file. You do not have to put explicit delimiters in the list. A new line is
inserted once the last item in the list has been written to
the file.
If you use WRITE # in an attempt to write data to a sequential file
restricted by a LOCK statement, BASIC generates the error message
Permission denied unless the error is trapped by the program. All of BASIC's
usual error-handling routines can trap and examine this error.
See Also
LOCK, OPEN, PRINT #, WRITE
Example
See the LINE INPUT # statement programming example, which uses the WRITE #
statement.
♀Part 2: Date/Time, Financial, Format Functions
Part 2 is an alphabetical reference for each function found in the
Date/Time, Financial, and Format add-on libraries. The syntax, options, and
action performed by each are described, as well as examples of how to use
each in a BASIC program.
Leading off Part 2 is a set of summary tables for the add-on libraries. Each
table lists the names of the functions to use for specific tasks, along with
the results.
The following groups of functions are included:
■ Date/time functions
■ Financial functions
■ Format functions
DateSerial# Function
Action
Returns a serial number that represents the date of the arguments.
Syntax
DateSerial# ( year%, month%, day%)
Remarks
The DateSerial# function uses the following arguments:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
Argument Description
────────────────────────────────────────────────────────────────────────────
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
DateSerial#, Day&, Month&, Now#, Serial Numbers, Weekday&, Year&
Day& Function
Action
Takes a date/time serial number and returns the day of the month.
Syntax
Day& ( serial#)
Remarks
The Day& function returns an integer between 1 and 31, inclusive, that
represents the day of the month corresponding to the argument.
The argument serial# is a serial number that represents a date and/or
time. For more information, see the topic "Serial Numbers" in this section.
To use Day& in the QBX environment, use the DTFMTER.QLB Quick library. To
use Day& outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Hour&, Minute&, Month&, Now#, Second&, Serial Numbers, Weekday&,
Year&
DDB# Function
Action
Returns depreciation of an asset for a specific period using the
double-declining-balance method.
Syntax
DDB# ( cost#, salvage#, life#, period#, status%)
Remarks
The double-declining-balance method computes depreciation at an accelerated
rate. Depreciation is highest in the first period and decreases in
successive periods.
The DDB# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
cost# The initial cost of the asset.
Argument Description
────────────────────────────────────────────────────────────────────────────
cost# The initial cost of the asset.
salvage# The value at the end of the useful
life of the asset.
life# The useful life of the asset.
period# The period for which asset
depreciation is desired.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
Note
All numeric arguments must be positive values.
The arguments life# and period# must use the same units. If life# is
given in months, period# also must be given in months.
DDB# uses the formula:
Depreciation for a period = (( cost - total depreciation from prior periods)
* 2) / life
To use DDB# in the QBX environment, use the FINANCER.QLB Quick library. To
use DDB# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header
file contains the necessary function declarations for using the financial
functions. For more information on using libraries, see Chapter 18, "Using
LINK and LIB" and Chapter 19, "Creating and Using Quick Libraries" in the
Programmer's Guide.
See Also
SLN #, SYD#
FormatX$ Functions
Action
Formats a numeric value.
Syntax
FormatI$ ( expression#, fmt$)
FormatL$ ( expression#, fmt$)
FormatS$ ( expression#, fmt$)
FormatD$ ( expression#, fmt$)
FormatC$ ( expression#, fmt$)
Remarks
The Format X $ functions return a string that contains the formatted
expression. The functions use the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
Argument Description
────────────────────────────────────────────────────────────────────────────
expression# A numeric expression to be
formatted.
fmt$ A string expression comprising
BASIC display-format characters
that detail how the expression is
to be displayed.
There are five separate add-on-library functions, depending on the data type
of expression#. Use the appropriate function as shown below:
╓┌──────────────────────┌────────────────────────────────────────────────────╖
Function Data type of expression
────────────────────────────────────────────────────────────────────────────
FormatI$ Integer
FormatL$ Long integer
Function Data type of expression
────────────────────────────────────────────────────────────────────────────
FormatL$ Long integer
FormatS$ Single precision
FormatD$ Double precision
FormatC$ Currency
If fmt$ is a null string, BASIC uses the general format (which gives output
identical to output with no formatting).
To use the Format X $ functions in the QBX environment, use the DTFMTER.QLB
Quick library. To use the Format X $ functions outside of the QBX
environment, link your program with the appropriate DTFMT xx.LIB file.
Depending on the compiler options you chose when you installed BASIC, one or
more of the following files will be available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The FORMAT.BI header
file contains the necessary function declarations for using the Format X $
functions. For more information on using libraries, see Chapter 18, "Using
LINK and LIB" and Chapter 19, "Creating and Using Quick Libraries" in the
Programmer's Guide.
Available Formats
The Format X $ functions provide a wide range of formats for numeric and
date/time data. The following symbols are used to create the formats:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
Null string Display the number in general
format.
0 Digit placeholder.
If the number has fewer digits on
either side of the decimal point
than there are zeros on either
side of the decimal point in the
format, the extra zeros are
displayed. If the number has more
digits to the right of the decimal
point than there are zeros to the
right in the format, the number is
rounded to as many decimal places
as there are zeros to the right.
If the number has more digits to
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
If the number has more digits to
the left of the decimal point than
there are zeros to the left in the
format, the extra digits are
displayed.
# Digit placeholder.
Follows the same rules as for the
0 digit placeholder, except that
extra zeros are not displayed if
the number has fewer digits on
either side of the decimal point
than there are number signs (#) on
either side of the decimal point.
. Decimal point.
This symbol determines how many
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
This symbol determines how many
digits BASIC displays to the right
and left of the decimal point.
Depending on the country code set
using the SetFormatCC routine,
BASIC may use the comma as the
decimal point. If the format
contains only number signs (#) to
the left of this symbol, numbers
smaller than 1 are begun with a
decimal point. To avoid this, you
should use 0 as the first digit
placeholder to the left of a
decimal point instead of #.
% Percentage.
The expression is multiplied by
100 and the percent character (%)
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
100 and the percent character (%)
is inserted.
╓┌───────────────────────────────────────┌───────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
, Thousands separator.
BASIC separates thousands by
commas (or by periods, depending
on the country code set using the
SetFormatCC routine) if the format
contains a comma surrounded by
digit placeholders (0 or #). Two
adjacent commas, or a comma
────────────────────────────────────────────────────────────────────────────
adjacent commas, or a comma
immediately to the left of the
decimal point location (whether
there is a decimal specified or
not) means "Omit the three digits
that fall between these commas, or
between the comma and the decimal
point, rounding as needed."
E- E+ e- e+ Scientific format.
If a format contains one digit
placeholder (0 or #) to the right
of an E-, E+, e-, or e+, BASIC
displays the number in scientific
format and inserts an E or e. The
number of digit placeholders to
the right determines the number of
digits in the exponent. Use E- or
e- to place a minus sign next to
────────────────────────────────────────────────────────────────────────────
e- to place a minus sign next to
negative exponents. Use E+ or e+
to place a minus sign next to
negative exponents and a plus sign
next to positive exponents.
: - + $ ( ) Space Display that literal character.
To display characters other than
one of these, precede each
character with a backslash( \ ) or
enclose the character(s) in double
quotation marks ("").
\ Display the next character in the
format string.
Many characters in the format
string have a special meaning and
cannot be displayed as literal
────────────────────────────────────────────────────────────────────────────
cannot be displayed as literal
characters unless they are
preceded by a backslash. The
backslash is not displayed. This
is the same as enclosing the next
character in double quotation
marks.
Examples of such characters are
the date- and time-formatting
characters (y, m, d, h, s, a, and
p) and the numeric-formatting
characters (#, 0, %, E, e, comma,
and period).
" abc" Display whatever text is inside
the double quotation marks.
To include a text string in fmt$,
you must use CHR$(34) to enclose
────────────────────────────────────────────────────────────────────────────
you must use CHR$(34) to enclose
the text (34 is the ASCII code for
double quotation mark).
The Format X $ functions have the following general syntax: Format X $ (
expression#, fmt$). Some sample numeric formats are shown below for
different values of fmt $ and expression#. (These examples all assume the
country code is set to 1, United States.)
The following example has two sections: the first section defines the format
for positive numbers and zeros; the second section defines the format for
negative numbers.
$#,##0;($#,##0)
You can use from one to three sections:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
One section only The format applies to all numbers.
Two sections The first section applies to
positive numbers and zeros; the
second to negative numbers.
Three sections The first section applies to
positive numbers, the second to
negative numbers, and the third to
zeros.
If you have semicolons with nothing between them, the missing section is
printed using the format of the positive value. For example, the following
format will display positive and negative numbers using the format in the
first section, and "Zero" if the value is zero:
"$#,##0;;Z\ero"
Date/Time Formats
Date/time serial numbers can be formatted with date/time or numeric formats
(since date/time serial numbers are stored as floating-point values).
Date/time formats have the following meanings:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
d dd ddd dddd Display the day as a number
without leading zeros (1-12), as a
number with leading zeros (01-12),
as an abbreviation (Sun-Sat), or
as a full name (Sunday-Saturday).
m mm mmm mmmm Display the month as a number
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
m mm mmm mmmm Display the month as a number
without leading zeros (1-12), as a
number with leading zeros (01-12),
as an abbreviation (Jan-Dec), or
as a full month name
(January-December). If you use m
or mm immediately after the h or
hh symbol, the minute rather than
the month is displayed.
yy yyyy Display the year as a two-digit
number (00 - 99), or as a
four-digit number (1900 - 2040).
h hh Display the hour as a number
without leading zeros (0 - 23), or
as a number with leading zeros (00
- 23). If the format contains an
AM or PM, the hour is based on the
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
AM or PM, the hour is based on the
12-hour clock. Otherwise, the hour
is based on the 24-hour clock.
m mm Display the minute as a number
without leading zeros (0 - 59),
or as a number with leading zeros
(00 - 59). The m or mm must appear
after an h or hh, or the month is
displayed rather than the minute.
s ss Display the second as a number
without leading zeros (0 - 59), or
as a number with leading zeros (00
- 59)..
AM / PM am / pm A / P a / p Display the hour using the 12-hour
clock. AM, am, A, or a is
displayed with any time before
Symbol Meaning
────────────────────────────────────────────────────────────────────────────
displayed with any time before
noon. PM, pm, P, or p is displayed
with any time between noon and
11:59 P.M.
The following are examples of date and time formats:
d-mmmm-yy 7-December-58
d-mmmm 7-December
mmmm-yy December-58
h:mm AM/PM 8:50 PM
h:mm:ss AM/PM 8:50:35 PM
h:mm 20:50
h:mm:ss 20:50:35
m/d/yy h:mm 12/7/58 20:50
See Also
PRINT, PRINT USING, STR$
FV# Function
Action
Returns the future value of an annuity based on periodic, constant payments
and a constant interest rate.
Syntax
FV# ( rate#, nper#, pmt#, pv#, type%, status%)
Remarks
An annuity is a series of constant cash payments made over a continuous
period of time. An annuity can be a loan (such as a home mortgage) or an
investment (such as a monthly savings plan).
The FV# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The interest rate per period. For
example, if you get a car loan at
an annual rate of 10 percent and
make monthly payments, the rate
per period would be .10/12, or
.0083.
nper# The number of payment periods in
the annuity. For example, if you
get a four-year car loan and make
monthly payments, your loan has a
total number of 4 times 12, or 48,
payment periods.
pmt# The payment to be made each period.
It usually contains principal and
interest and does not change over
Argument Description
────────────────────────────────────────────────────────────────────────────
interest and does not change over
the life of the annuity.
pv# The present value or a lump sum
that a series of payments to be
paid in the future is worth now.
For example, when you borrow money
to buy a car, the loan amount is
the present value to the lender of
the monthly car payments you will
make.
type% An integer expression that
indicates when payments are due.
Use 0 as the value for type if
payments are due at the end of the
period; use 1 if due at the
beginning of the period.
Argument Description
────────────────────────────────────────────────────────────────────────────
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
The arguments rate# and nper# must use consistent units. For example:
Note
For all arguments, cash you pay out, such as deposits to savings, is
represented by negative numbers; cash you receive, such as dividend checks,
is represented by positive numbers.
A number of other functions are related to FV#:
■ IPmt# returns the interest payment for an annuity for a given period.
■ NPer# returns the number of periods (payments) for an annuity.
■ Pmt# returns the periodic total payment for an annuity.
■ PPmt# returns the principal payment for an annuity for a given
period.
■ PV# returns the present value of an annuity.
■ Rate# returns the interest rate per period of an annuity.
To use FV# in the QBX environment, use the FINANCER.QLB Quick library. To
use FV# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
IPmt#, NPer#, Pmt#, P Pmt#, PV#, R ate#
Hour& Function
Action
Takes a date/time serial number and returns the hour.
Syntax
Hour& ( serial#)
Remarks
The Hour& function returns an integer between 0 (12:00 A.M.) and 23 (11:00
P.M.) that represents the hour of the day corresponding to the argument.
The argument serial# is a serial number that represents a date and/or
time. For more information, see the topic "Serial Numbers" in this section.
To use Hour& in the QBX environment, use the DTFMTER.QLB Quick library. To
use Hour& outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Day&, Minute&, Month&, Second&, Serial Numbers, Weekday&, Year&
IPmt# Function
Action
Returns the interest payment for a given period of an annuity based on
periodic, constant payments and a constant interest rate.
Syntax
IPmt# ( rate#, per#, nper#, pv#, fv#, type%, status%)
Remarks
An annuity is a series of constant cash payments made over a continuous
period of time. An annuity can be a loan (such as a home mortgage) or an
investment (such as a monthly savings plan).
The IPmt# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The interest rate per period. For
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The interest rate per period. For
example, if you get a car loan at
an annual rate of 10 percent and
make monthly payments, the rate
per period would be .10 divided by
12, or .0083.
per# The payment period; must be in the
range from 1 to nper#.
nper# The number of payment periods in
the annuity. For example, if you
get a four-year car loan and make
monthly payments, your loan has a
total number of 4 times 12, or 48,
payment periods.
pv# The present value or a lump sum
that a series of payments to be
Argument Description
────────────────────────────────────────────────────────────────────────────
that a series of payments to be
paid in the future is worth now.
For example, when you borrow money
to buy a car, the loan amount is
the present value to the lender of
the monthly car payments you will
make.
fv# The future value or the cash
balance you want sometime in the
future after the last payment is
made. The future value of a loan,
for instance, is 0. As another
example, if you think you will
need $50,000 in 18 years to pay
for your child's education, then
$50,000 is the future value.
type% An integer expression that
Argument Description
────────────────────────────────────────────────────────────────────────────
type% An integer expression that
indicates when payments are due.
Use 0 as the value for type% if
payments are due at the end of the
period; use 1 if due at the
beginning of the period.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
The arguments rate# and nper# must use
consistent units.
Note
For all arguments, negative numbers equal cash you pay out, and positive
numbers equal cash you receive.
A number of other functions are related to IPmt#:
■ FV# returns the the future value of an annuity.
■ NPer# returns the number of periods (payments) for an annuity.
■ Pmt# returns the periodic total payment for an annuity.
■ PPmt# returns the principal payment for an annuity for a given
period.
■ PV# returns the present value of an annuity.
■ Rate# returns the interest rate per period of an annuity.
To use IPmt# in the QBX environment, use the FINANCER.QLB Quick library. To
use IPmt# outside of the QBX environment, link your program with the
appropriate FINANCxx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
FV#, NPer#, Pmt#, PPmt#, PV#, Rate#
Example
This example uses the IPmt# function to calculate how much you will pay
over the lifetime of a loan where all the payments are of equal value.
To run this example, you must link it with the appropriate FINANC xx.LIB and
DTFMT xx.LIB files or use the FINANCER.QLB and DTFMTER.QLB Quick libraries.
The following include files must also be present:
' $INCLUDE: 'FINANC.BI'
' $INCLUDE: 'FORMAT.BI'
CONST YEARMONTHS = 12
CONST ENDPERIOD = 0
CONST BEGINPERIOD = 1
CONST DOLLARFORMAT$ = "$###,###,###.00"
FutureVal = 0
DEFDBL A-Z
DIM Status AS INTEGER
' Get user input.
CLS
INPUT "Enter the annual percentage rate of your loan"; APR
PRINT
INPUT "What is the principal amount of your loan"; PresentVal
PRINT
INPUT "How many monthly payments do you have to make"; NumPeriods
PRINT
DO WHILE PaymentTypeString$ <> "B" AND PaymentTypeString$ <> "E"
PRINT "Payments due at the beginning or end of the month? ";
PaymentTypeString$ = UCASE$(INPUT$(1))
LOOP
' Set up the correct payment type.
IF PaymentTypeString$ = "B" THEN
PaymentType = BEGINPERIOD
PRINT "Beginning"
ELSE
PaymentType = ENDPERIOD
PRINT "End"
END IF
PRINT
' Put APR in proper form.
IF APR > 1 THEN APR = APR / 100
FOR Period = 1 TO
NumPeriods
' Calculate the Interest paid each month.
InterestPmt = ABS(IPmt#(APR / YEARMONTHS, Period, NumPeriods,_
-PresentVal, FutureVal, PaymentType, Status))
' Check for an error.
IF Status THEN
PRINT "There was a calculation error."
END
END IF
' Accumulate a total.
TotalInterest = TotalInterest + InterestPmt
NEXT Period
' Format and display results.
TotalInterest$ = FormatD$(TotalInterest, DOLLARFORMAT$)
PresentVal$ = FormatD$(PresentVal, DOLLARFORMAT$)
TotalPaid$ = FormatD$(TotalInterest + PresentVal, DOLLARFORMAT$)
PRINT
PRINT "You'll pay a total of "; TotalPaid$; " on your "; PresentVal$;
PRINT " loan, of which "; TotalInterest$; " is interest."
IRR# Function
Action
Returns the internal rate of return for a series of periodic cash flows
(payments and receipts).
Syntax
IRR# ( valuearray# ( ), valuecount%, guess#, status%)
Remarks
The internal rate of return is the interest rate received for an investment
that consists of payments and receipts that occur at regular intervals.
The IRR# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
valuearray#( ) An array of cash-flow values. The
argument must contain at least one
negative value (a payment) and one
positive value (a receipt).
valuecount% The total number of items in the
cash-flow array.
guess# A value you guess is close to the
result of IRR#. In most cases you
can assume guess# to be 0.1 (10
percent). However, if IRR#
returns a status of 1 (failure),
or if the result is not close to
what you expected, try different
Argument Description
────────────────────────────────────────────────────────────────────────────
what you expected, try different
values of guess#.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
■ MIRR# gives the internal rate of return where positive and negative
cash flows are financed at different rates.
■ NPV# gives the net present value of an investment based on cash flows
that do not have to be constant.
■ Rate# gives the interest rate per period of an investment.
To use IRR# in the QBX
environment, use the FINANCER.QLB Quick library. To use IRR# outside of the
QBX environment, link your program with the appropriate FINANC xx.LIB file.
Depending on the compiler options you chose when you installed BASIC, one or
more of the following files will be available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
MIRR#, NPV#, Rate#
Minute& Function
Action
Takes a date/time serial number and returns the minute.
Syntax
Minute& ( serial# )
Remarks
The Minute& function returns an integer between 0 and 59, inclusive, that
represents the minute corresponding to the argument.
The argument serial# is a serial number that represents a date and/or
time. For more information, see the topic "Serial Numbers" in this section.
To use Minute& in the QBX environment, use the DTFMTER.QLB Quick library.
To use Minute& outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Day&, Hour&, Month&, Now#, Second&, Serial Numbers, Weekday&, Year&
MIRR# Function
Action
Returns the modified internal rate of return for a series of periodic cash
flows (payments and receipts).
Syntax
MIRR# ( valuearray# ( ), valuecount%, fin-rate#, reinv-rate#,
status%)
Remarks
The modified internal rate of return is the internal rate of return where
payments and receipts are financed at different rates. MIRR# considers both
the cost of the investment ( fin-rate#) and the interest received on
reinvestment of cash ( reinv-rate#).
The MIRR# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
valuearray# ( ) An array of cash-flow values. The
argument must contain at least one
negative value (a payment) and one
positive value (a receipt).
valuecount% The total number of items in the
cash-flow array.
fin-rate# The interest rate paid as the cost
of financing..
Argument Description
────────────────────────────────────────────────────────────────────────────
of financing..
reinv-rate# The interest rate received on
gains from cash reinvestment.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
The arguments fin-rate# and reinv-rate# are percentages expressed as
decimal values. For example, 12 percent is expressed as .12.
MIRR# uses the order of values within the array to interpret the order of
payments and receipts. Be sure to enter your payment and receipt values in
the correct sequence.
Two other functions are related to MIRR#:
■ IRR# returns the internal rate of return for an investment.
■ Rate# returns the interest rate per period of an annuity.
To use MIRR# in the QBX environment, use the FINANCER.QLB
Quick library. To use MIRR# outside of the QBX environment,
link your program with the appropriate FINANC xx.LIB file.
Depending on the compiler options you chose when you installed BASIC,
one or more of the following files will be available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
IRR#, Rate#
Month& Function
Action
Takes a date/time serial number and returns the month.
Syntax
Month& ( serial# )
Remarks
The Month& function returns an integer between 1 and 12, inclusive, that
represents the month corresponding to the argument.
The argument serial# is a serial number that represents a date and/or time.
For more information, see the topic "Serial Numbers" in this section.
To use Month& in the QBX environment, use the DTFMTER.QLB Quick library. To
use Month& outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Day&, Hour&, Minute&, Now#, Second&, Serial Numbers, Weekday&, Year&
Now# Function
Action
Returns a serial number that represents the current date and time according
to your computer's system date and time.
Syntax
Now#
Remarks
For more information, see the topic "Serial Numbers" in this section.
To use Now# in the QBX environment, use the DTFMTER.QLB Quick library. To
use Now# outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Day&, Hour&, Minute&, Month&, Second&, Serial Numbers, Weekday&,
Year&
Example
The following example examines the current date and time information
contained by the operating system and displays a formatted version of the
date and time as returned by the Now# function.
To run this example, you must link it with the appropriate DTFMT xx.LIB file
or use the DTFMTER.QLB Quick library. The following include files must also
be present.
' $INCLUDE: 'DATIM.BI'
' $INCLUDE: 'FORMAT.BI'
CLS
PRINT "Today's date is "; FormatD$(Now#, "dd-mmm-yy"); "."
PRINT "The current time is "; FormatD$(Now#, "hh:mm:ss AM/PM"); "."
Output
Today's date is 02-May-1989.
The current time is 2:22:14 PM.
NPer# Function
Action
Returns the number of periods for an annuity based on periodic, constant
payments and a constant interest rate.
Syntax
NPer# ( rate#, pmt#, pv#, fv#, type%, status%)
Remarks
An annuity is a series of constant cash payments made over a continuous
period of time. An annuity can be a loan (such as a home mortgage) or an
investment (such as a monthly savings plan).
The NP er# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The interest rate per period. For
example, if you get a car loan at
an annual rate of 10 percent and
make monthly payments, the rate
per period would be .10 divided by
12, or .0083.
pmt# The payment to be made each period.
It usually contains principal and
interest and does not change over
the life of the annuity.
pv# The present value or a lump sum
that a series of payments to be
paid in the future is worth now.
For example, when you borrow money
to buy a car, the loan amount is
the present value to the lender of
the monthly car payments you will
Argument Description
────────────────────────────────────────────────────────────────────────────
the monthly car payments you will
make.
fv# The future value or the cash
balance you want to be attained
sometime in the future after the
last payment is made. The future
value of a loan, for example is
zero. As another example, if you
think you will need $50,000 in 18
years to pay for your child's
education, the future value is
$50,000.
type% An integer expression that
indicates when payments are due.
Use 0 as the value for type% if
payments are due ar the end of the
period; use 1 if at the beginning
Argument Description
────────────────────────────────────────────────────────────────────────────
period; use 1 if at the beginning
of the period.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
Note
For all arguments, cash you pay out, such as deposits to savings, is
represented by negative numbers; cash you receive, such as dividend checks,
is represented by positive numbers.
A number of other functions are related to NPer#:
■ FV# returns the the future value of an annuity.
■ IPmt# returns the interest payment for an annuity for a given period.
■ Pmt# returns the periodic total payment for an annuity.
■ PPmt# returns the principal payment for an annuity for a given
period.
■ PV# returns the present value of an annuity.
■ Rate# returns the interest rate per period of an annuity.
To use NPer# in the QBX environment, use the FINANCER.QLB Quick library. To
use NPer# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
FV#, IPmt#, Pmt#, PPmt#, PV#, Rate#
NPV# Function
Action
Returns the net present value of an investment based on a series of periodic
cash flows (payments and receipts) and a discount rate.
Syntax
NPV# ( rate#, valuearray#( ), valuecount%, status%)
Remarks
The net present value of an investment is today's value of a future series
of payments and receipts.
The NPV# function uses the following arguments:
╓┌─────────────────────────────────────┌─────────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The discount rate over the length of
the period, expressed as a decimal.
Argument Description
────────────────────────────────────────────────────────────────────────────
valuearray#( ) An array of cash-flow values. The
argument must contain at least one
negative value (a payment) and one
positive value (a receipt).
valuecount% The total number of items in the
cash-flow array.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
Several other functions are related to NPV#:
■ FV# returns the the future value of an annuity.
■ IRR# returns the internal rate of return for an investment.
■ PV# returns the present value of an annuity.
To use NPV# in the QBX environment, use the FINANCER.QLB Quick library. To
use NPV# outside of the QBX environment, link your program with the
appropriate FINANCxx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
FV#, IRR#, PV#
Pmt# Function
Action
Returns the payment for an annuity based on periodic, constant payments and
a constant interest rate.
Syntax
Pmt# ( rate#, nper#, pv#, fv#, type%, status%)
Remarks
An annuity is a series of constant cash payments made over a continuous
period of time. An annuity can be a loan (such as a home mortgage) or an
investment (such as a monthly savings plan).
The Pmt# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The interest rate per period. For
example, if you get a car loan at
an annual rate of 10 percent and
make monthly payments, the rate
per period would be .10 divided by
12, or .0083.
nper# The number of payment periods in
the annuity. For example, if you
Argument Description
────────────────────────────────────────────────────────────────────────────
the annuity. For example, if you
get a four-year car loan and make
monthly payments, your loan has a
total number of 4 times 12, or 48,
payment periods.
pv# The present value or a lump sum
that a series of payments to be
paid in the future is worth now.
For example, when you borrow money
to buy a car, the loan amount is
the present value to the lender of
the monthly car payments you will
make.
fv# The future value or the cash
balance you want to be attained
sometime in the future after the
last payment is made. The future
Argument Description
────────────────────────────────────────────────────────────────────────────
last payment is made. The future
value of a loan, for example is
zero. As another example, if you
think you will need $50,000 in 18
years to pay for your child's
education, the future value is
$50,000.
type% An integer expression that
indicates when payments are due.
Use 0 as the value for type% if
payments are due at the end of the
period; use 1 if due at the
beginning of the period.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
Argument Description
────────────────────────────────────────────────────────────────────────────
will be 0 if the calculation was
successful, and 1 if it was not.
The arguments rate# and nper# must use consistent units. For example:
Note
For all arguments, cash you pay out, such as deposits to savings, is
represented by negative numbers; cash you receive, such as dividend checks,
is represented by positive numbers.
A number of other functions are related to Pmt#:
■ FV# returns the the future value of an annuity.
■ IPmt# returns the interest payment for an annuity for a given period.
■ NPer# returns the number of periods (payments) for an annuity.
■ PPmt# returns the principal payment for an annuity for a given
period.
■ PV# returns the present value of an annuity.
■ Rate# returns the interest rate per period of an annuity.
To use Pmt# in the QBX environment, use the FINANCER.QLB Quick library. To
use Pmt# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
FV#, IPmt#, NPer#, PPmt#, PV#, Rate#
PPmt# Function
Action
Returns payment on the principal for a given period of an annuity based on
periodic, constant payments and a constant interest rate.
Syntax
PPmt# ( rate#, per#, nper#, pv#, fv#, type%, status%)
Remarks
An annuity is a series of constant cash payments made over a continuous
period of time. An annuity can be a loan (such as a home mortgage) or an
investment (such as a monthly savings plan).
The PPmt# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The interest rate per period. For
example, if you get a car loan at
an annual rate of 10 percent and
make monthly payments, the rate
per period would be .10 divided by
12, or .0083.
per# The payment period; must be
between 1 and nper#, inclusive.
If it is not in that range, BASIC
Argument Description
────────────────────────────────────────────────────────────────────────────
If it is not in that range, BASIC
generates the error message
Overflow.
nper# The number of payment periods in
the annuity. For example, if you
get a four-year car loan and make
monthly payments, your loan has a
total number of 4 times 12, or 48,
payment periods.
pv# The present value or a lump sum
that a series of payments to be
paid in the future is worth now.
For example, when you borrow money
to buy a car, the loan amount is
the present value to the lender of
the monthly car payments you will
make.
Argument Description
────────────────────────────────────────────────────────────────────────────
make.
fv# The future value or the cash
balance you want to be attained
sometime in the future after the
last payment is made. The future
value of a loan, for example is
zero. As another example, if you
think you will need $50,000 in 18
years to pay for your child's
education, the future value is
$50,000.
type% An integer expression that
indicates when payments are due.
Use 0 as the value for type% if
payments are due at the end of the
period; use 1 if due at the
beginning of the period.
Argument Description
────────────────────────────────────────────────────────────────────────────
beginning of the period.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
The arguments rate# and nper# must use consistent units.
Note
For all arguments, cash you pay out, such as deposits to savings, is
represented by negative numbers; cash you receive, such as dividend checks,
is represented by positive numbers.
A number of other functions are related to PPmt#:
■ FV# returns the the future value of an annuity.
■ IPmt# returns the interest payment for an annuity for a given period.
■ NPer# returns the number of periods (payments) for an annuity.
■ Pmt# returns the periodic total payment for an annuity.
■ PV# returns the present value of an annuity.
■ Rate# returns the interest rate per period of an annuity.
To use PPmt# in the QBX environment, use the FINANCER.QLB Quick library. To
use PPmt# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
FV#, IPmt#, NPer#, Pmt#, PV#, Rate#
PV# Function
Action
Returns the present value, or lump sum, that a series of payments to be paid
in the future is worth now.
Syntax
PV# ( rate#, nper#, pmt#, fv#, type%, status%)
Remarks
The PV# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
rate# The interest rate per period. For
example, if you get a car loan at
an annual rate of 10 percent and
make monthly payments, the rate
per period would be .10 divided by
12, or .0083.
Argument Description
────────────────────────────────────────────────────────────────────────────
12, or .0083.
nper# The number of payment periods in
the annuity. For example, if you
get a four-year car loan and make
monthly payments, your loan has a
total number of 4 times 12, or 48,
payment periods.
pmt# The payment to be made each period.
It usually contains principal and
interest and does not change over
the life of the annuity.
fv# The future value or the cash
balance you want to be attained
sometime in the future after the
last payment is made. The future
value of a loan, for example is
Argument Description
────────────────────────────────────────────────────────────────────────────
value of a loan, for example is
zero. As another example, if you
think you will need $50,000 in 18
years to pay for your child's
education, the future value is
$50,000.
type% An integer expression that
indicates when payments are due.
Use 0 as the value for type% if
payments are due at the end of the
period; use 1 if due at the
beginning of the period.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
Argument Description
────────────────────────────────────────────────────────────────────────────
successful, and 1 if it was not.
Two other functions are related to PV#:
■ IPmt# returns the interest payment for an annuity for a given period.
■ PPmt# returns the principal payment for an annuity for a given
period.
To use PV# in the QBX environment, use the FINANCER.QLB Quick library. To
use PV# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
IPmt#, PPmt#
Rate# Function
Action
Returns the interest rate per period for an annuity.
Syntax
Rate# ( nper#, mt#, pv#, fv#, type%, guess#, status%)
Remarks
An annuity is a series of constant cash payments made over a continuous
period of time. An annuity can be a loan (such as a home mortgage) or an
investment (such as a monthly savings plan).
The Rate# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
nper# The number of payment periods in
the annuity. For example, if you
Argument Description
────────────────────────────────────────────────────────────────────────────
the annuity. For example, if you
get a four-year car loan and make
monthly payments, your loan has a
total number of 4 times 12, or 48,
payment periods.
pmt# The payment to be made each period.
It usually contains principal and
interest and does not change over
the life of the annuity.
pv# The present value or a lump sum
that a series of payments to be
paid in the future is worth now.
For example, when you borrow money
to buy a car, the loan amount is
the present value to the lender of
the monthly car payments you will
make.
Argument Description
────────────────────────────────────────────────────────────────────────────
make.
fv# The future value or the cash
balance you want to be attained
sometime in the future after the
last payment is made. The future
value of a loan, for example is
zero. As another example, if you
think you will need $50,000 in 18
years to pay for your child's
education, the future value is
$50,000.
type% An integer expression that
indicates when payments are due.
Use 0 as the value for type% if
payments are due at the end of the
period; use 1 if due at the
beginning of the period.
Argument Description
────────────────────────────────────────────────────────────────────────────
beginning of the period.
guess# A value you guess is close to the
result of Rate#.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
Note%
For all arguments, cash you pay out, such as deposits to savings, is
represented by negative numbers; cash you receive, such as dividend checks,
is represented by positive numbers.
Rate# is calculated by iteration. Starting with
the value of guess#, Rate# cycles
through the calculation until the result is accurate within .00001 percent.
If after 20 tries it can't find a result that works, Rate
# returns a status of 1. In most cases you can assume the
guess# argument to be 0.1 (10 percent). However, if Rate%# returns a status
A number of other functions are related to Rate#:
■ FV# returns the the future value of an annuity.
■ IPmt# returns the interest payment for an annuity for a given period.
■ NPer# returns the number of periods (payments) for an annuity.
■ Pmt# returns the periodic total payment for an annuity.
■ PPmt# returns the principal payment for an annuity for a given
period.
■ PV# returns the present value of an annuity.
To use Rate# in the QBX environment, use the FINANCER.QLB Quick library. To
use Rate# outside of the QBX environment, link your program with the
appropriate FINANCxx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
FV#, IPmt#, NPer#, Pmt#, PPmt#, PV#
Second& Function
Action
Takes a date/time serial number and returns the second.
Syntax
Second& ( serial#)
Remarks
The Second& function returns an integer between 0 and 59, inclusive, that
represents the second corresponding to the argument.
The argument serial# is a serial number that represents a date and/or time.
For more information, see the topic "Serial Numbers" in this section.
To use Second& in the QBX environment, use the DTFMTER.QLB Quick library.
To use Second& outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Day&, Hour&, Minute&, Month&, Now#, Serial Numbers, Weekday&, Year&
Serial Numbers
A serial number is a date/time code used by BASIC to represent dates and
times between
Jan. 1, 1753 and Dec. 31, 2078.
Serial-Number Format
Numbers to the left of the decimal point represent the date; numbers to the
right of the decimal point represent the time. For example:
╓┌────────────────────────┌──────────────────────────────────────────────────╖
Serial number Date and time represented
────────────────────────────────────────────────────────────────────────────
20323.25 August 22, 1955 6:00 A.M.
Serial number Date and time represented
────────────────────────────────────────────────────────────────────────────
20323.25 August 22, 1955 6:00 A.M.
20324.25 August 23, 1955 6:00 A.M.
367.5 January 1, 1901 12:00 P.M.
367.75 January 2, 1901 6:00 P.M.
A serial number with no fractional part represents a date only. A serial
number with only a fractional part represents a time only.
The date portion of the serial number (to the left of the decimal point) can
represent dates ranging from January 1, 1753, through December 31, 2078.
Dates before December 30, 1899 are represented by negative numbers; dates
after December 30, 1899 are represented by positive numbers:
╓┌───────────────────────────┌───────────────────────────────────────────────╖
Serial number Date represented
────────────────────────────────────────────────────────────────────────────
-1 December 29, 1899
Serial number Date represented
────────────────────────────────────────────────────────────────────────────
-1 December 29, 1899
0 December 30, 1899
1 December 31, 1899
2 January 1, 1900
The time portion of the serial number (to the right of the decimal point)
can represent times that range from 0 (12:00:00 A.M.) to .99999 (11:59:59
P.M. or 23:59:59).
SetFormatCC Routine
Action
Sets the country code for the Format X $ functions.
Syntax
SetFormatCC ( countrycode%)
Remarks
The argument countrycode% is the international telephone dialing prefix for
the country chosen as the target audience when using the Format X $
functions.
The only reason to use SetFormatCC is to change what the Format X $
functions expect as thousands-separator and decimal-point formatting
characters.
The default setting for the country code is the United States (1). If you
set the country code to France (33), the following statement would display
the number 1,000 (U.S.) as 1.000,00:
PRINT FormatD$ (1000, "#.##0,00")
The format you use with the Format X $ functions must be compatible with
the current country code in order for formatted numbers to display properly.
If you set the country code to one of the following countries, the Format X
$ functions expect alternative formatting characters: Austria, Belgium,
Brazil, Denmark, France, Germany, Italy, Netherlands, Norway, Spain, Sweden,
or Switzerland. Canada uses one country code for French Canada (2) and
another for the remainder of Canada (1).
To use SetFormatCC in the QBX environment, use the DTFMTER.QLB Quick
library. To use SetFormatCC outside of the QBX environment, link your
program with the appropriate DTFMT xx.LIB file. Depending on the compiler
options you chose when you installed BASIC, one or more of the following
files will be available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The FORMAT.BI header file contains the necessary function declarations for
using the formatting functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Format X $; StringAddress Routine, StringLength Routine (in Part 1).
SLN# Function
Action
Returns straight-line depreciation of an asset for a single period.
Syntax
SLN# ( cost#, salvage#, life#, status%)
Remarks
The SLN# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
cost# The initial cost of the asset.
salvage# The value at the end of the useful
life of the asset.
life# The useful life of the asset (or
the number of periods over which
the asset is being depreciated).
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
successful, and 1 if it was not.
To use SLN# in the QBX environment, use the FINANCER.QLB Quick library. To
use SLN# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
DDB#, SYD#
SYD# Function
Action
Returns the sum-of-years' digits depreciation of an asset for a specified
period.
Syntax
SYD# ( cost#, salvage#, life#, period#, status%)
Remarks
The SYD# function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
cost# The initial cost of the asset.
salvage# The value at the end of the useful
life of the asset.
life# The useful life of the asset (or
the number of periods over which
the asset is being depreciated).
period# Period for which asset
depreciation is desired.
status% A BASIC variable that indicates
whether calculation succeeded or
failed. The value of the variable
will be 0 if the calculation was
Argument Description
────────────────────────────────────────────────────────────────────────────
will be 0 if the calculation was
successful, and 1 if it was not.
The arguments life# and period# must use the same units. For example, if
life# is given in months, period# also must be given in months.
To use SYD# in the QBX environment, use the FINANCER.QLB Quick library. To
use SYD# outside of the QBX environment, link your program with the
appropriate FINANC xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌─────────────────┌─────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
FINANCER.LIB 80x87 or emulator math; DOS or OS/2 real mode
FINANCAR.LIB Alternate math; DOS or OS/2 real mode
FINANCEP.LIB 80x87 or emulator math; OS/2 protected mode
FINANCAP.LIB Alternate math; OS/2 protected mode
The FINANC.BI header file contains the necessary function declarations for
using the financial functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
DDB#, SLN#
TimeSerial# Function
Action
Returns a serial number that represents the time of the arguments.
Syntax
TimeSerial# ( hour%, minute%, second%)
Remarks
The TimeSerial# function uses the following arguments:
╓┌──────────┌────────────────────────────────────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
hour% An hour between 0 (12:00 A.M.) and 23 (11:00 P.M.), inclusive.
minute% A minute between 0 and 59, inclusive.
second% A second between 0 and 59, inclusive.
You can use negative numbers as arguments, as long as the resulting serial
number is positive. For example, to find the serial number for the time 50
seconds before 2:00:02, you could use:
TimeSerial#(2,0,2-50)
For more information, see the topic "Serial Numbers" in this section.
To use TimeSerial# in the QBX environment, use the DTFMTER.QLB Quick
library. To use TimeSerial# outside of the QBX environment, link your
program with the appropriate DTFMT xx.LIB file. Depending on the compiler
options you chose when you installed BASIC, one or more of the following
files will be available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
"Creating and Using Quick Libraries" and "Using LINK and LIB" in the
Programmer's Guide.
See Also
Hour&, Minute&, Now#, Second&, Serial Numbers, TimeValue#
Example
The following example calculates the time between now and midnight tonight.
The results of the calculations are shown as a total number of seconds, as a
combination of hours, minutes, and seconds, and also as a standard time
format. The time information is displayed using the TimeValue#,
TimeSerial#, Hour&, Minute&, and Second& functions.
To run this example, you must link it with the appropriate DTFMT xx.LIB file
or use the DTFMTER.QLB Quick library. The following include files must also
be present.
' $INCLUDE: 'DATIM.BI'
' $INCLUDE: 'FORMAT.BI'
' Get a time value for midnight tonight -1 second.
Midnight# = TimeValue#("23:59:59")
' Get a time value for right now.
Instant# = Now#
' Get the difference in hours, minutes, seconds.
HourDiff% = Hour&(Midnight#) - Hour&(Instant#)
MinuteDiff% = Minute&(Midnight#) - Minute&(Instant#)
' Add in the odd second between 23:59:59 and midnight.
SecondDiff% = Second&(Midnight#) - Second&(Instant#) + 1
' Adjust so that seconds and minutes are less than 60.
IF SecondDiff% = 60 THEN
MinuteDiff% = MinuteDiff% + 1
SecondDiff% = 0
END IF
IF MinuteDiff% = 60 THEN
HourDiff% = HourDiff% + 1
MinuteDiff% = 0
END IF
' Calculate seconds between now and midnight.
TotalMinDiff# = (HourDiff% * 60) + MinuteDiff%
TotalSecDiff# = (TotalMinDiff# * 60) + SecondDiff%
' Put the difference back into a standard time format.
TotalDiff# = TimeSerial#(HourDiff%, MinuteDiff%, SecondDiff%)
' Display results.
CLS
PRINT "There are a total of"; TotalSecDiff#; "seconds until midnight."
PRINT "That translates to"; HourDiff%; "hours,"; MinuteDiff%;
PRINT "minutes, and"; SecondDiff%; "seconds."
PRINT
PRINT "The difference can also be expressed in standard time notation:"
PRINT FormatD$(TotalDiff#, "hh:mm:ss")
TimeValue# Function
Action
Returns a serial number that represents the time of the argument.
Syntax
TimeValue# ( time$)
Remarks
The argument time$ is a time between 0:00:00 (12:00:00 A.M.) and 23:59:59
(11:59:59 P.M.), inclusive. Time can be entered as "2:24PM" or "14:24".
Any date information used in time$ is ignored.
For more information, see the topic "Serial Numbers" in this section.
To use TimeValue# in the QBX environment, use the DTFMTER.QLB Quick
library. To use TimeValue# outside of the QBX environment, link your
program with the appropriate DTFMT xx.LIB file. Depending on the compiler
options you chose when you installed BASIC, one or more of the following
files will be available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Hour&, Minute&, Now#, Second&, Serial Numbers, TimeSerial#, Year&
Weekday& Function
Action
Takes a date-time serial number and returns the day of the week.
Syntax
Weekday& ( serial# )
Remarks
The Weekday& function returns an integer between 1 (Sunday) and 7
(Saturday) that represents the day of the week corresponding to the
argument.
The argument serial# is a serial number that represents a date and/or time.
For more information, see the topic "Serial Numbers" in this section.
To use Weekday& in the QBX environment, use the DTFMTER.QLB Quick library.
To use Weekday& outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Day&, Hour&, Minute&, Month&, Now#, Second&, Year&
Year& Function
Action
Takes a date-time serial number and returns the year.
Syntax
Year& ( serial# )
Remarks
The Year& function returns an integer between 1753 and 2078, inclusive,
that represents the year corresponding to the argument.
The argument serial# is a serial number that represents a date and/or time.
For more information, see the topic "Serial Numbers" in this section.
To use Year& in the QBX environment, use the DTFMTER.QLB Quick library. To
use Year& outside of the QBX environment, link your program with the
appropriate DTFMT xx.LIB file. Depending on the compiler options you chose
when you installed BASIC, one or more of the following files will be
available:
╓┌────────────────┌──────────────────────────────────────────────────────────╖
Filename Compiler options
────────────────────────────────────────────────────────────────────────────
DTFMTER.LIB 80x87 or emulator math; DOS or OS/2 real mode
DTFMTAR.LIB Alternate math; DOS or OS/2 real mode
DTFMTEP.LIB 80x87 or emulator math; OS/2 protected mode
DTFMTAP.LIB Alternate math; OS/2 protected mode
The DATIM.BI header file contains the necessary function declarations for
using the date/time functions. For more information on using libraries, see
Chapter 18, "Using LINK and LIB" and Chapter 19, "Creating and Using Quick
Libraries" in the Programmer's Guide.
See Also
Day&, Hour&, Minute&, Month&, Now#, Second&, Serial Numbers
a
♀Toolbox Summary Tables
The following groups are summarized here:
* Matrix Math Function procedures
* Presentation Graphics Sub and Function procedures
* Font SUB and Function procedures
* User Interface SUB and Function procedures
- Menu
- Window
- Mouse
- General
Matrix Math Function Procedures
* I is integer.
* L is long integer.
* S is single-precision floating point.
* D is double-precision floating point.
* C is currency.
Addition
--------
MatAddI%
MatAddL%
MatAddS%
MatAddD%
MatAddC%
Finds the sum of two matrixes whose row and column dimensions are identical.
Subtraction
-----------
MatSubI%
MatSubL%
MatSubS%
MatSubD%
MatSubC%
Finds the difference between two matrixes whose row and column dimensions
are identical.
Multiplication
--------------
MatMultI%
MatMultL%
MatMultS%
MatMultD%
MatMultC%
Finds the product of two matrixes where the first matrix has the same number
of columns as the second matrix has rows.
Determinant
-----------
MatDetI%
MatDetL%
MatDetS%
MatDetD%
MatDetC%
Finds the determinant of a square matrix.
Inverse
-------
MatInvS%
MatInvD%
MatInvC%
Finds the multiplicative inverse of a square matrix, if one exists; that is,
if the determinant is not equal
to 0.
Gaussian elimination
--------------------
MatSEqnS%
MatSEqnD%
MatSEqnC%
Uses Gaussian elimination to solve, if a solution exists, a system of linear
equations contained in a square matrix and a vector.
Presentation Graphics Sub and FUNCTION Procedures
Chart
Draws a bar, column, or line chart.
ChartMS
Draws a multi-series bar, column, or line chart.
ChartPie
Draws a pie chart.
ChartScatter
Draws a single-series scatter chart.
ChartScatterMS
Draws a multi-series scatter chart.
ChartScreen
Sets the screen mode to be used when displaying a chart.
DefaultChart
Initializes a ChartEnvironment structure for the specified chart type and
style.
GetPaletteDef
Gets a copy of the current internal chart palette.
GetPattern$
Returns a string that can be used by BASIC as a pixel pattern
LabelChartH
Prints a user-defined string horizontally on a chart.
LabelChartV
Prints a user-defined string vertically on a chart.
MakeChartPattern$
Changes fill pattern and color.
ResetPaletteDef
Builds the internal chart palette for the current screen mode using the
current style pool.
SetPaletteDef
Replaces the internal chart palette with user-defined values.
Font SUB and FUNCTION Procedures
GetFontInfo
Gets font information for the currently selected font.
GetGTextLen%
Returns the pixel length of a string based on the currently selected font.
GetMaxFonts
Gets the maximum number of fonts that can be registered and loaded.
GetRFontInfo
Gets font information for the currently registered fonts.
GetTotalFonts
Gets the number of fonts currently registered and loaded.
LoadFont%
Loads the font information from the .fon files or memory for the specified
fonts and returns the number of fonts actually loaded.
OutGText%
Outputs text in the currently selected font using the current graphics color
at the current graphics cursor position. Returns pixel length of the
character output.
RegisterFonts%
Registers font-header information from a specified .fon file and returns the
number of fonts registered.
RegisterMemFont%
Registers the font-header information for fonts that reside in memory and
returns the number of fonts registered.
SelectFont
Designates a loaded font as the active font.
SetGCharSet
Sets the character set used in subsequent graphics characters.
SetGTextColor
Sets the character color used in subsequent graphic characters.
SetGTextDir
Sets the horizontal or vertical orientation of graphics characters.
SetMaxFonts
Sets the maximum number of fonts that are allowed to be registered and
loaded.
UnRegisterFonts
Removes registered fonts from memory.
User Interface Procedures
The following tables summarize the procedures that make up the User
Interface toolbox. These functions are provided in four separate toolbox
files. The files are:
* MENU.BAS
* WINDOW.BAS
* MOUSE.BAS
* GENERAL.BAS
Each table lists the type of operation performed by the procedure, the
procedure name, and the result of the procedure. See the detailed
description of each of the procedures later in this part for more
information about how to use them in your programs.
Menu SUB and FUNCTION Procedures
Initialize variables and preprocess menus
-----------------------------------------
MenuInit
Initializes global menu arrays and mouse driver servicing routines.
MenuPreProcess
Performs calculations and builds indexes so menus run faster.
Define and display menus
------------------------
MenuColor
Assigns color to various components of the menus.
MenuSet
Defines the structure of menus and the quick keys associated with each menu
selection.
MenuShow
Draws the menu across the top line of the screen.
Change the state of menus or menu items
---------------------------------------
MenuItemToggle
Toggles the state of a menu item between enabled but not selected and
enabled and selected.
MenuSetState
Explicitly assigns the state of a menu item. States are: empty (menu item
does not appear on the menu); enabled but not selected; enabled and
selected; and disabled.
Process menu events
-------------------
MenuCheck
Provides a numeric indication of what menu selection, if any, was made
following a menu or shortcut-key event.
MenuEvent$
Monitors user input to determine if a menu choice is being made with either
the mouse or the keyboard.
MenuInkey$
Performs a BASIC INKEY$ function as well as a MenuEvent$ and
ShortCutKeyEvent$ function.
MenuOff
Turns off menu and shortcut-key event processing.
MenuOn
Turns on menu and shortcut-key event processing that was previously turned
off.
Shortcut keys
-------------
ShortCutKeyDelete$
Revokes any previous shortcut-key definitions associated with a particular
menu item.
ShortCutKeyEvent$
Polls user input to determine if a menu item was selected using a shortcut
key.
ShortCutKeySet
Assign shortcut keys to individual menu items.
Window SUB and FUNCTION Procedures
Initialize window variables
---------------------------
WindowInit
Initializes global variables for all procedures in WINDOW.BAS.
Define windows
--------------
WindowBox
Draws a box with a single-line border at a designated position within the
current window.
WindowClose
Closes a specified window.
WindowColor
Changes color characteristics of the current window.
WindowOpen
Defines the size, position, color, and other characteristics of individual
windows.
WindowSetCurrent
Makes the specified window the current window.
Get information about windows
-----------------------------
WindowCols
Returns the number of columns in the current window.
WindowCurrent
Returns the number of the current window handle.
WindowNext
Returns the number of the next available window handle.
WindowRows
Returns the number of rows in the current window.
Display text in windows
-----------------------
WindowCls
Clears all text from within a window.
WindowLine
Draws a horizontal line across a window at the row specified.
WindowLocate
Sets the row and column of the window text cursor to define the next
position where a character will be printed.
WindowPrint
Prints text in a window at the position established by WindowLocate.
WindowScroll
Scrolls text, in the current window, the number of lines specified.
Button actions
--------------
ButtonClose
Erases the specified button from the current window and deletes it from the
global arrays.
ButtonInquire
Returns a value that indicates the state of the specified button. Only used
with button types 1, 2, 3, 6, and 7.
ButtonOpen
Opens a button of a specified type and places it in the current window at
the specified window coordinates.
ButtonSetState
Sets the state of the specified button in the current window.
ButtonToggle
Toggles the state of the specified button between selected and not selected.
Edit field actions
------------------
EditFieldClose
Erases the specified edit field from the current window and deletes it from
the global arrays.
EditFieldInquire
Returns the string associated with the specified edit field.
EditFieldOpen
Opens an edit field and places it in the current window at specified
coordinates.
Miscellaneous actions
---------------------
Alert
Displays a window containing between one and three buttons that indicate
user choices. Returns a value that indicates the number of the button
selected by the user.
Dialog
Returns a value that indicates what type of button, edit field, or window
event occurred during window-event processing.
ListBox
Displays a window containing a list box, a scroll bar, an OK button, and a
Cancel button. Returns a value that indicates the number of the item
selected in the list box,
or 0 if Cancel is selected.
MaxScrollLength
Returns a value that indicates how many positions are available on a
specified scroll bar.
Mouse SUB Procedures
Initialize the mouse
--------------------
MouseDriver
Calls Interrupt 51 (33H) and passes parameters to the proper CPU registers.
MouseInit
Initializes mouse driver servicing routines.
Establish limits of mouse movement on the screen
------------------------------------------------
MouseBorder
Defines the area where the mouse can be used.
Manipulate the mouse
--------------------
MouseHide
Turns off display of the mouse cursor.
MousePoll
Polls the mouse driver to establish the position of the mouse cursor and the
status of mouse buttons.
MouseShow
Turns on display of the mouse cursor.
General SUB and FUNCTION Procedures
Accept and evaluate keyboard input
----------------------------------
AltToASCII$
Decodes extended key codes associated with the Alt key and returns an
individual ASCII character.
GetShiftState
Returns the status of one of eight possible shift states.
Manipulate screen areas
-----------------------
AttrBox
Changes color attributes of text within an area described by specified row
and column coordinates.
Box
Draws a box around a defined area using specified foreground and background
colors.
GetBackground
Saves an area of the screen into a named buffer.
PutBackground
Restores to specified coordinates a previously saved screen area from a
named buffer.
Scroll
Scrolls the defined area a specified number of lines.
Matrix Math Toolbox
This section describes the six FUNCTION procedures supported by the Matrix
Math toolbox:
* MatAdd FUNCTION
* MatSub FUNCTION
* MatMult FUNCTION
* MatDet FUNCTION
* MatInv FUNCTION
* MatSEqn FUNCTION
Matrix Math is the name of a BASIC toolbox (MATB.BAS) included with
Microsoft BASIC. The toolbox contains a set of matrix-manipulation
procedures that perform math operations on two-dimensional matrixes. There
is a separate toolbox procedure for each supported numeric data type. Which
one to use depends on the data type of the elements in the matrix. The last
letter in the procedure name identifies the data type of the procedure, as
follows:
Letter Numeric data type
I Integer
S Single precision floating point
C Currency
L Long integer
D Double precision floating point
All numeric data types are supported by MatAdd, MatSub, MatMult, and MatDet.
Integer and long integer data types are not supported by MatInv and MatSEqn.
Each procedure returns a result code that indicates the success of the
operation, or, in the case of an error, the nature of the problem
encountered. The following result codes are defined:
Result code Significance
0 Normal completion. No error occurred.
- 1 Determinant for matrix is 0. No inverse of the input matrix
exists.
- 2 Matrix not square; doesn't have same number of rows as
columns.
- 3 Inside dimension not the same. The number of columns in
matrix1 is not the same as the number of rows in matrix2.
- 4 Matrixes not of the same dimension. That is, there are not
the same number of rows in matrix1 that are in matrix2 or there are not the
same number of columns in matrix1 that are in matrix2.
- 5 Dimensions for the solution matrix not correctly declared.
The matrix does not have the proper number of rows and columns.
Note
----
By default all arrays are zero based; that is, the lower bound of an array
is 0. You may wish to use OPTION BASE 1 so that the numbers in the DIM
statement accurately reflect the number of row and column elements in your
matrixes.
Following is a description of the FUNCTION procedures in the Matrix Math
toolbox.
MatAdd FUNCTION
MatAddI%
MatAddL%
MatAddS%
MatAddD%
MatAddC%
Syntax
errcode% = MatAddtype%(matrix1( ), matrix2( ))
Remarks
MatAddtype% performs matrix addition of two matrixes that are the same in
both row (m) and column (n) dimensions. The input matrixes contain values
whose data type is defined by the last letter in the procedure name (I, L,
S, D, or C). The sum is returned in matrix1( ), replacing any previous
values. The solution matrix contains values of the same data type as the
input matrixes. Once the procedure has been performed, the contents of
matrix2( ) are meaningless.
MatAddtype% uses the following arguments:
matrix1( )
----------
A matrix consisting of m x n dimensions.
matrix2( )
----------
A matrix consisting of m x n dimensions.
A result code indicates the success or failure of the FUNCTION procedure.
Possibilities are:
0 Normal completion. No error occurred.
-4 Matrixes not of the same dimension. That is, there are not
the same number of rows in matrix1 as there are in matrix2 or there are not
the same number of columns in matrix1 as in matrix2.
MatSub FUNCTION
MatSubI%
MatSubL%
MatSubS%
MatSubD%
MatSubC%
Syntax
errcode% = MatSubtype%(matrix1( ), matrix2( ))
Remarks
The MatSubtype% procedure performs matrix subtraction of two matrixes whose
row (m) and column (n) dimensions are identical. The input matrixes contain
values whose data type is defined by the last letter in the procedure name
(I, L, S, D, or C). The first matrix is subtracted from the second and the
difference is returned in matrix1( ), replacing any previous values. The
solution matrix contains values of the same data type as the input matrixes.
Once the procedure has been performed, the contents of matrix2( ) are
meaningless.
MatSubtype% uses the following arguments:
matrix1( )
----------
A matrix consisting of m x n dimensions.
matrix2( )
----------
A matrix consisting of m x n dimensions.
A result code is returned that indicates the success or failure of the
FUNCTION procedure. Possible result codes are:
0 Normal completion. No error occurred.
- 4 Matrixes not of the same dimension. That is, there are not the same
number of rows in matrix1 as there are in matrix2 or there are not the same
number of columns in matrix1 as in matrix2.
MatMult FUNCTION
MatMultI%
MatMultL%
MatMultS%
MatMultD%
MatMultC%
Syntax
errcode% = MatMulttype%(matrix1( ), matrix2( ), matrix3( ))
Remarks
The MatMulttype% procedure performs matrix multiplication of two matrixes.
The first matrix must have the same number of columns (n in an m x n matrix)
as the number of rows in the second matrix (n in an n x k matrix). The input
matrixes contain values whose data type is defined by the last letter in the
procedure name (I, L, S, D, or C). The first matrix is multiplied by the
second and the product is returned in matrix3( ). The solution matrix
contains values of the same data type as the input matrixes. Once the
procedure has been performed, the contents of the input matrixes are
meaningless.
MatMulttype% uses the following arguments:
matrix1( )
----------
A matrix consisting of m x n dimensions.
matrix2( )
----------
A matrix consisting of n x k dimensions.
matrix3( )
----------
Solution matrix consisting of m x k dimensions.
A result code is returned that indicates the success or failure of the
FUNCTION procedure. Possible result codes are:
0 Normal completion. No error occurred.
- 3 Inside dimension not the same. The number of columns in matrix1 is not
the same as the number of rows in matrix2.
- 5 Dimensions for the solution matrix not correctly declared. The matrix
does not have the proper number of rows and columns.
Note
----
Matrix division is performed using the MatInvtype% procedure to multiply one
matrix by the inverse of the second; that is, A/B = A * Inverse(B).
MatDet FUNCTION
MatDetI%
MatDetL%
MatDetS%
MatDetD%
MatDetC%
Syntax
errcode% = MatDettype%(matrix ( ), determinant)
Remarks
The MatDettype% procedure finds the determinant of a square matrix; that is,
a matrix that has the same number of rows and columns (n x n). The input
matrix contains values whose data type is defined by the last letter in the
procedure name (I, L, S, D, or C). The resulting determinant, of the same
data type as the input matrix values, is placed in determinant. After the
procedure is performed, the contents of matrix( ) are meaningless.
MatDettype% uses the following arguments:
matrix ( )
----------
A matrix consisting of n x n dimensions.
determinant
-----------
The determinant for matrix ( ).
A result code indicates the success or failure of the FUNCTION procedure.
Possibilities are:
0 Normal completion. No error occurred.
- 2 Matrix not square. The matrix does not have the same number of rows as
columns.
MatInv FUNCTION
MatInvS%
MatInvD%
MatInvC%
Syntax
errcode% = MatInvtype%(matrix ( ))
Remarks
The MatInvtype% procedure finds the multiplicative inverse of a square
matrix; that is, a matrix that has the same number of rows and columns (n x
n). The input matrix contains values whose data type is defined by the last
letter in the procedure name (S, D, or C). The resulting inverse matrix, of
the same data type as the input matrix values, is returned in matrix( ),
replacing any previous values.
The argument matrix ( ) is a matrix consisting of n x n dimensions.
A result code indicates the success or failure of the FUNCTION procedure.
Possibilities are:
0 Normal completion. No error occurred.
- 1 The determinant for the matrix is 0. No inverse of the input matrix
exists.
- 2 Matrix not square. The matrix does not have the same number of rows as
columns.
Note
----
Matrix division is performed using the MatInvtype% procedure to multiply one
matrix by the inverse of the second, that is, A/B = A * Inverse(B).
MatSEqn FUNCTION
MatSEqnS%
MatSEqnD%
MatSEqnC%
Syntax
errcode% = MatSEqntype%(matrix1( ), matrix2( ))
Remarks
The MatSEqntype% procedure solves a system of linear equations contained in
a square matrix; that is, a matrix that has the same number of rows and
columns (n x n). Gaussian elimination is used to solve the equations. The
input matrix contains values whose data type is defined by the last letter
in the procedure name (S, D, or C). The first matrix is the square input
matrix that contains the coefficients for a system of simultaneous
equations. The second matrix, matrix2( ), is the space where the solution is
returned. The solution space is an n x 1 matrix. The solution matrix
contains values of the same data type as the input matrix. Once the
procedure has been performed, the identity matrix is in matrix1( ).
MatSEqntype% uses the following arguments:
matrix1( )
----------
A matrix consisting of n x n dimensions.
matrix2( )
----------
Solution array consisting of 1 x n dimensions.
A result code is returned that indicates the success or failure of the
FUNCTION procedure. Possible result codes are:
0 Normal completion. No error occurred.
- 1 Determinant for matrix is 0. No inverse of the input matrix exists.
- 2 Matrix not square. The matrix does not have the same number of rows as
columns.
- 3 Inside dimension not the same. The number of columns in matrix1 is not
the same as the number of rows in matrix2.
Presentation Graphics Toolbox
The first part of this section describes the SUB and FUNCTION procedures
that are supported by the Presentation Graphics toolbox. The second part
describes the SUB and FUNCTION procedures that are supported by the Fonts
toolbox. The Fonts toolbox can be used with the Presentation Graphics
toolbox or independently to draw graphics text.
The Presentation Graphics toolbox (CHRTB.BAS), included with the BASIC 7.0
Compiler, contains a set of routines for defining, analyzing, and printing
charts on the screen.
There are five kinds of charts, each available in two styles as shown here:
Style Bar Column Line Scatter Pie
1 Plain Plain Lines and Lines and Percent
points points displayed
2 Stacked Stacked Points only Points only No percent
To use the toolbox, you first must declare the dimensions for a variable as
the user-defined type ChartEnvironment. The definition for this type is
found in the CHRTB.BI header file. This file also contains definitions for
constants that can be used as arguments to the procedures described in this
section. Using these constants in place of hand-coded numerics will make
your program cleaner and easier to debug.
Presentation Graphics Error Codes
If an error occurs during the execution of a presentation graphics
procedure, the variable ChartErr will contain a non-zero value.
For non-BASIC errors, the error numbers can be tested using numerics or
constants as defined in the CHRTB.BI header file. The meaning of a non-BASIC
error:
Number Constant name Type of error
15 cBadLogBase LogBase <= 0
20 cBadScaleFactor ScaleFactor = 0
25 cBadScreen Invalid screen mode
30 cBadStyle Invalid chart style
105 cBadDataWindow Data window calculated
too small
110 cBadLegendWindow Legend-window coordinates
invalid
135 cBadType Invalid chart type
155 cTooFewSeries Too few series
(first% > last%)1
160 cTooSmallN No data in series (n% = 0)2
165 cBadPalette Palette not dimensioned
correctly
170 cPalettesNotSet SetPaletteDef procedure hasn't
been used
175 cNoFontSpace No more room for new fonts
Numbers greater than 100 are fatal errors and will cause charting routines
to exit.
If BASIC generates an error, the value of ChartErr is equal to 200 plus the
BASIC error number. (See Appendix D, "Error Messages" for a complete list of
BASIC error messages.)
Chart Sub
Action
Draws bar, column, and line charts.
Syntax
Chart env, cat$(), value!(), n%
Remarks
The Chart procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
cat$()
------
A one-dimensional string array of category names.
value!()
--------
A one-dimensional single-precision array that contains the
chart data.
n%
--
An integer that contains the number of data items in value!().
The value!() and cat$() arrays must have a lower bound of 1.
The AnalyzeChart routine uses the same arguments as Chart. AnalyzeChart
analyzes and defines parameters in the chart environment based on the input
data, but it does not print a chart on the screen.
ChartMS Sub
Action
Draws multi-series bar, column, and line charts.
Syntax
ChartMS env, cat$(), value!(), n%, first%, last%, serieslabel$()
Remarks
The ChartMS procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
cat$()
------
A one-dimensional string array of category labels.
value!()
--------
A two-dimensional single-precision array of values that contains multiple
series of data.
n%
--
An integer that contains the number of data items in each series to be
charted.
first%
------
An integer that indicates the first series in array value!() to be charted.
last%
-----
An integer that indicates the last series in array value!() to be charted.
serieslabel$()
--------------
A one-dimensional string array that contains labels for the different data
series.
Dimensions for the value!() and serieslabel$() arrays are declared as
follows:
DIM Val!( 1 to n%, first% to last%)
DIM serieslabel$( first% to last%)
To chart all series, set first% to 1 and last% to the last series number in
array value!(). To chart several contiguous series, set first% to the lowest
series number and last% to the highest series number desired.
An analysis routine called AnalyzeChartMS (included in the Presentation
Graphics toolbox) uses the same arguments as ChartMS. AnalyzeChartMS
analyzes and defines parameters in the chart environment based on the input
data, but it does not print a chart on the screen.
ChartPie Sub
Action
Draws bar, column, and line charts.
Syntax
ChartPie env, cat$(), value!(), expl%(), n%
Remarks
The ChartPie procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
cat$()
------
A one-dimensional string array of category names.
value!()
--------
A one-dimensional single-precision array that contains the
chart data.
expl%()
-------
A one-dimensional integer array containing flags that determine whether each
element of the pie chart is exploded. If the value of an expl%() array
element is nonzero, that slice of the pie chart is exploded. If the array
element is zero, the slice is not exploded.
n%
--
An integer that contains the number of data items in value!().
The value!(), cat$(), and expl%() arrays must have a lower bound of 1.
An analysis routine called AnalyzePie (included in the Presentation Graphics
toolbox) uses the same arguments as ChartPie. AnalyzePie analyzes and
defines parameters in the chart environment based on the input data, but it
does not print a chart on the screen.
ChartScatter Sub
Action
Draws single-series scatter charts.
Syntax
ChartScatter env, valx!(), valy!(), n%
Remarks
The ChartScatter procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
valx!()
-------
A one-dimensional single-precision array of values for the x axis.
valy!()
-------
A one-dimensional single-precision array of values for the y axis.
n%
--
An integer that contains the number of data items to be charted.
The valx!() and valy!() arrays must have a lower bound of 1.
An analysis routine called AnalyzeScatter (included in the Presentation
Graphics toolbox) uses the same arguments as ChartScatter. AnalyzeScatter
analyzes and defines parameters in the chart environment based on the input
data, but it does not print a chart on the screen.
ChartScatterMS Sub
Action
Draws multi-series scatter charts.
Syntax
ChartScatterMS env, valx!(), valy!(), n%, first%, last%, serieslabel$()
Remarks
The ChartScatterMS procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
valx!()
-------
A two-dimensional single-precision array of values for multiple series of
data for the x axis.
valy!()
-------
A two-dimensional single-precision array of values for multiple series of
data for the y axis.
n%
--
An integer that contains the number of data items to be charted.
first%
------
An integer that indicates the first series to be charted.
last%
-----
An integer that indicates the last series to be charted.
serieslabel$()
--------------
A one-dimensional string array that contains labels for the different data
series.
Dimensions for the valx!(), valy!() and serieslabel$() arrays are declared
as follows:
DIM valx!( 1 to n%, first% to last%)
DIM valy!( 1 to n%, first% to last%)
DIM serieslabel$( first% to last%)
To chart all series, set first% to 1 and last% to the last series number in
array value!(). To chart several contiguous series, set first% to lowest
series number and last% to the highest series number desired.
An analysis routine called AnalyzeScatterMS (included in the Presentation
Graphics toolbox) uses the same arguments as ChartScatterMS.
AnalyzeScatterMS analyzes and defines parameters in the chart environment
based on the input data, but it does not print a chart on the screen.
ChartScreen Sub
Action
Sets the screen mode to be used when displaying a chart.
Syntax
ChartScreen n%
Remarks
The argument n% is an integer that contains a valid screen-mode number.
This procedure must be used to set the screen mode instead of the standard
BASIC SCREEN statement.
If an invalid screen mode is used, the variable ChartErr will contain the
number 25.
See Also: SCREEN Statement
DefaultChart Sub
Action
Initializes the elements of the variable type ChartEnvironment for the
specified chart type and style.
Syntax
DefaultChart env, type%, style%
Remarks
The DefaultChart procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
type%
-----
An integer that defines the type of chart (1-5).
style%
------
An integer that defines the style of the chart (1-2).
The variable type% can use either numeric data or constants found in the
CHRTB.BI file to define the chart as shown in the following table:
Value Constant Type of chart
1 cBar Bar
2 cColumn Column
3 cLine Line
4 cScatter Scatter
5 cPie Pie
The value of the variable style% determines the style of the chart as shown
here:
Value Bar Column Line Scatter Pie
1 Plain Plain Lines & points Lines & points Percent
2 Stacked Stacked Points only Points only No percent
For program clarity, the following constants (found in the CHRTB.BI file)
should be used in place of numeric arguments:
Numeric argument Equivalent constant
1 cPlain, cLines, cPercent
2 cStacked, cNoLines, cNoPercent
GetPaletteDef Sub
Action
Gets a copy of the current internal chart palette.
Syntax
GetPaletteDef palc%(), pals%(), palp$(), palch%(), palb%()
Remarks
The GetPaletteDef procedure uses the following arguments:
palc%()
-------
A one-dimensional integer array of color numbers corresponding to the
palette entries.
pals%()
-------
A one-dimensional integer array of line styles corresponding to the palette
entries.
palp$()
-------
A one-dimensional string array of fill patterns corresponding to the palette
entries.
palch%()
--------
A one-dimensional integer array of plot-character numbers corresponding to
the palette entries.
palb%()
-------
A one-dimensional integer array of line styles used for drawing window
borders and grid lines.
Dimensions for each array should be declared from 0 to cPalLen, a constant
found in the CHRTB.BI header file. Note that all palette arrays have a lower
bound of 0 (not 1, which is used for data and category-string arrays).
For more information on fill patterns, see the entries for PAINT and PALETTE
in Part 1, "Language Reference."
GetPattern$ FUNCTION
Action
Returns a string that can be used by BASIC as a pixel pattern.
Syntax
GetPattern$(bits%, patternNum%)
Remarks
The GetPattern$ and MakeChartPattern$ procedures are used in combination
with the GetPaletteDef and SetPaletteDef procedures to change the fill
pattern for pie, column, and bar charts. GetPattern$ constructs a value for
refPattern$, which is one of the arguments used by MakeChartPattern$.
The GetPattern$ procedure uses the following arguments:
Parameter Description
bits% Use 2 for screen mode 1, 8 for screen mode 13, and 1 for all
other screen modes.
patternNum% An integer between one and cPalLen.
For more information, see the entry for the MakeChartPattern$ procedure
later in this section.
LabelChartH Sub
Action
Prints a user-defined string horizontally on a chart.
Syntax
LabelChartH env, x%, y%, font%, color%, string$
Remarks
The LabelChartH procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
x%
--
An integer that indicates the left position of the first character, in
pixels, relative to the chart window.
y%
--
An integer that indicates the bottom of the first character, in pixels,
relative to the chart window.
font%
-----
An integer that contains the number of the font (in currently loaded list)
to use.
color%
------
An integer that contains the color number in the chart palette used to
assign color to the string.
string$
-------
The text string to be printed.
The LabelChartH procedure must be called after calling the charting sub.
If an invalid font number (such as 0) is contained in font%, the first font
loaded is used. If no fonts are loaded, the default font contained in the
Presentation Graphics toolbox files is used.
LabelChartV Sub
Action
Prints a user-defined string vertically on a chart.
Syntax
LabelChartV env, x%, y%, font%, color%, string$
Remarks
The LabelChartV procedure uses the following arguments:
env
---
A variable dimensioned as type ChartEnvironment.
x%
--
An integer that indicates the left position of the first character, in
pixels, relative to the chart window.
y%
--
An integer that indicates the top of the first character, in pixels,
relative to the chart window.
font%
-----
An integer that contains the number of the font (in currently loaded list)
to use.
color%
------
An integer that contains the color number in the chart palette used to
assign color to the string.
string$
-------
The text string to be printed.
The LabelChartV procedure must be called after calling the charting sub.
Each character is printed vertically and appears in a vertical column.
If an invalid font number (such as 0) is contained in font%, the first font
loaded is used. If no fonts are loaded, the default font contained in the
Presentation Graphics toolbox files is used.
MakeChartPattern$ FUNCTION
Action
Changes fill pattern and color.
Syntax
MakeChartPattern$(refPattern$, foreground%, background%)
Remarks
The MakeChartPatern$ and GetPattern$ procedures are used in combination with
the GetPaletteDef and SetPaletteDef procedures to change the fill pattern
for pie, column, and bar charts.
The GetPattern$ procedure uses the following arguments:
refPattern$ A string representing the pixel pattern.
foreground% Attribute to map to the pixels in refPattern$ that are
defined as being on.
background% Attribute to map to the pixels in refPattern$ that are
defined as off.
Note that if foreground% and background% are the same value, the fill
pattern appears as a solid color.
Constructing a value for refPattern$ is difficult. When using the
Presentation Graphics toolbox, you can simplify the process by using the
GetPattern$ procedure to choose an internally-defined pattern.
MakeChartPattern$ maps colors to the string returned by GetPattern$ to
produce the combination of color and pattern you want. For more information,
see the entry for the GetPattern$ procedure earlier in this section.
ResetPaletteDef Sub
Action
Rebuilds the internal chart palette for the current screen mode.
Syntax
ResetPaletteDef
SetPaletteDef Sub
Action
Replaces the internal chart palette with new values.
Syntax
SetPaletteDef palc%(), pals%(), palp$(), palch%(), palb%()
Remarks
The SetPaletteDef procedure uses the following arguments:
palc%()
-------
A one-dimensional integer array of color numbers corresponding to the
palette entries.
pals%()
-------
A one-dimensional integer array of line styles corresponding to the palette
entries.
palp$()
-------
A one-dimensional string array of fill patterns corresponding to the palette
entries.
palch%()
--------
A one-dimensional integer array of plot-character numbers corresponding to
the palette entries.
palb%()
-------
A one-dimensional integer array of line styles used for drawing window
borders and grid lines.
The dimensions for each array must be declared from 0 to cPalLen, a constant
found in the CHRTB.BI header file. Note that all palette arrays have a lower
bound of 0 (not 1, which is used for data and category string arrays).
For more information on fill patterns, see the entries for PAINT and PALETTE
in Part 1, "Language Reference."
Part 3: Fonts Tool Box
The Fonts toolbox (FONTB.BAS), included with this version of BASIC, contains
a set of routines that perform font-management tasks such as registering,
loading, selecting, and printing fonts on the screen.
Nine font files are supplied: Courier fonts in COURA.FON, COURB.FON, and
COURE.FON, Helvetica fonts in HELVA.FON, HELVB.FON and HELVE.FON, and Times
Roman fonts in TMSRA.FON, TMSRB.FON and TMSRE.FON. Each of these files
contains six font sizes. Besides these two font files, the Fonts toolbox
will work with any standard Windows bitmap .FON file.
To use the Fonts toolbox, you must compile and link the FONTASM.OBJ and
FONTB.BAS modules into a .LIB or .QLB library file. Once this library
exists, you can use it just like any other library. The Fonts toolbox can be
used independently of the Presentation Graphics toolbox to draw graphics
text.
Several of the procedures use the font-header information defined in the
user-defined type FontInfo. This type is defined in the FONTB.BI header
file. This file also contains definitions for constants that can be used as
arguments to the procedures described in this section. Using these constants
in place of hand-coded numbers makes your program cleaner and easier to
debug.
Font Error Codes
If an error occurs during the execution of a font function or sub procedure,
the variable FontErr will contain a non-zero value.
For non-BASIC errors, the error numbers can be tested using numerics or
constants as defined in the FONTB.BI header file. The meaning of a non-BASIC
error is shown in Table 3.9.
╓┌───────────┌────────────────────────────────────────────────┌──────────────╖
Number Constant name Type of error
────────────────────────────────────────────────────────────────────────────
FontNum The location of the font in the registered list
or the loaded list.
Ascent The pixel distance from the character baseline
to the top of the character box.
Points The point size of the current font as defined
in the LoadFont% function.
Number Constant name Type of error
────────────────────────────────────────────────────────────────────────────
PixWidth The width of the character bitmap. A value of 0
specifies a proportional font. A nonzero value
specifies the pixel width of the characters in
a fixed-space font.
PixHeight The height of the character bitmap.
Leading The number of blank lines at the top of the
character definition to act as leading between
lines.
AvgWidth The average width of characters in pixels.
MaxWidth The pixel width of the widest character in the
font.
FileName The filename from which the font was loaded.
The filename has the extension .FON.
Number Constant name Type of error
────────────────────────────────────────────────────────────────────────────
The filename has the extension .FON.
FaceName The name of the typeface (for example,
Helvetica, Courier) taken from the filename.
Note
When using the GetFontInfo procedure, be sure you have access to the .FON
file on disk so that it can find the FontNum, FileName, and FaceName values
for the currently selected font.
For more information on the elements of the variable type FontInfo, see
documentation on font file format in Chapter 7, "File Formats" in the
Programmer's Reference, which is part of the Microsoft Windows Software
Development Kit.
GetGTextLen% Function
Action
Returns the pixel length of a string based on the currently selected font.
Syntax
GetGTextLen% ( txt$)
Remarks
GetGTextLen% is an integer that contains the pixel length of the string
supplied in the argument txt$. The pixel length returned from the
GetGTextLen% function is based on the currently selected font. From this
pixel length, you then can determine whether a string will fit on a
particular screen (for example, CGA, EGA).
GetMaxFonts Sub
Action
Gets the maximum number of fonts that can be registered and loaded.
Syntax
GetMaxFonts ( maxregistered%, maxloaded%)
Remarks
The GetMaxFonts procedure uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
maxregistered% An integer that is the maximum
number of fonts that can be
registered.
maxloaded% An integer that is the maximum
number of fonts that can be loaded.
Argument Description
────────────────────────────────────────────────────────────────────────────
number of fonts that can be loaded.
GetMaxFonts returns the current number of fonts that can be registered and
loaded as set in the SetMaxFonts routine. The default is 10.
See Also
GetTotalFonts, SetMaxFonts
GetRFontInfo Sub
Action
Gets the font information on the currently registered font.
Syntax
GetRFontInfo ( n%, fontinfo)
Remarks
The GetRFontInfo procedure uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
n% The number of the registered font.
fontinfo A variable of type FontInfo that
receives the font-header
information.
The FontInfo data structure type is defined as follows:
FontInfo
TYPE FontInfo
FontNumASINTEGER
AscentASINTEGER
PointsASINTEGER
PixWidthASINTEGER
PixHeightASINTEGER
LeadingASINTEGER
AvgWidthASINTEGER
MaxWidthASINTEGER
FileNameASSTRING * cMaxFileName
FaceNameASSTRING * cMaxFaceName
END TYPE
The following list describes the parts of the FontInfo data structure:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Part Description
────────────────────────────────────────────────────────────────────────────
FontNum The location of the font in the
Part Description
────────────────────────────────────────────────────────────────────────────
FontNum The location of the font in the
registered list or the loaded list.
Ascent The pixel distance from the
character baseline to the top of
the character box.
Points The point size of the current font
as defined in the LoadFont%
function.
PixWidth The width of the character bitmap.
A value of 0 specifies a
proportional font. A non-zero
value specifies the pixel width of
the characters in a fixed-space
font.
PixHeight The height of the character bitmap.
Part Description
────────────────────────────────────────────────────────────────────────────
PixHeight The height of the character bitmap.
Leading The number of blank lines at the
top of the character definition to
act as leading between lines.
AvgWidth The average width of characters in
pixels.
MaxWidth The pixel width of the widest
character in the font.
FileName The filename from which the font
was loaded. The filename has the
extension .FON.
FaceName The name of the typeface (for
example, Helvetica, Courier) taken
from the filename.
Part Description
────────────────────────────────────────────────────────────────────────────
from the filename.
Note
When using GetRFontInfo, make sure you have access to the .FON file on disk
so that it can find the FontNum, FileName, and FaceName values for the
currently selected font.
For more information on the elements of the variable type FontInfo, see the
Microsoft Windows developer documentation on font file format.
GTextWindow Sub
Action
Retains the logical coordinates of window boundaries. (See note below.)
Syntax
GTextWindow ( x1, y1, x2, y2, Scrn%)
Remarks
The GTextWindow procedure uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
x1 Integer containing the minimum X
value (logical coordinate).
y1 Integer containing the minimum Y
value.
x2 Integer containing the maximum X
value.
Argument Description
────────────────────────────────────────────────────────────────────────────
value.
y2 Integer containing the maximum Y
value.
Scrn% Integer containing either cTRUE
(used with WINDOW SCREEN statement
to show Y values increase top to
bottom) or cFALSE (used with
WINDOW statement to show window Y
values increase bottom to top).
registered% The number of currently registered
fonts.
loaded% The number of currently loaded
fonts.
See Also
GetMaxFonts, SetMaxFonts
LoadFont% Function
Action
Loads the font information from the .FON files or memory for the specified
registered fonts and returns the number of fonts actually loaded.
Syntax
LoadFont% ( fontspec$)
Remarks
The argument fontspec$ is a specification used to load one or more of the
registered fonts. The specification for each font consists of one or more of
the following:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Specification Description
────────────────────────────────────────────────────────────────────────────
n # Loads font number # in the list
of currently registered fonts.
t name Specifies the desired font name.
(There must be a space between t
and name.)
s # Specifies point size #. When s is
specified, only the fonts designed
for the screen mode specified by m
are used.
h # Specifies pixel height # of a
font.
m # Specifies screen mode #. This is
Specification Description
────────────────────────────────────────────────────────────────────────────
m # Specifies screen mode #. This is
used for sizing fonts with s. The
default is the current screen mode.
b Selects the best fit based on the
size specified in the s or h
options. The specification b is
ignored with vector fonts because
they can be any size.
╓┌────┌──────────────────────────────────────────────────────────────────────╖
────────────────────────────────────────────────────────────────────────────
f Loads only a single fixed-space font.
p Loads only the first proportionally spaced font that registered.
Any previously loaded fonts are removed from memory. To load more than one
font, multiple specifications are needed.
Multiple specifications are separated by slash characters, and blanks are
ignored. If the specifications do not match a registered font or if an
invalid font is specified, then font number one (n1) is used.
The LoadFont% function loads the character-bit maps into the loaded fonts
array. This array corresponds to the registered fonts array which stores the
font-header information. Before you can use the LoadFont% function, you
must use the RegisterFont% function.
Note
The total size of the font data should be less than or equal to 64K unless
the /AH option is used when invoking QBX. The /AH option allows the use of
larger arrays.
For more information on selecting a particular loaded font, see the
SelectFont procedure.
Example
The following example demonstrates the LoadFont% function.
r% = RegisterFonts("tmsrb.fon")' r% should = 6 after call.
l% = LoadFont("h8/h12/h24")' l% should = 3 after call.
' 3 fonts (8,12,24 pts) will be loaded and usable.
SelectFont 2' The 12-point font is current.
SetGTextColor 10' Color 10 is light green.
textlen% = OutGText (1,1,"TmsRmn 12-point")
END
Note that to load fonts according to their order in the font file, l% would
take the form:
l% = LoadFont%("n1,n3,n6")' Load the first, third, and sixth fonts.
OutGText% Function
Action
Outputs text in the currently selected font, using the current graphics
color at the current graphics cursor position, and returns the pixel length
of the character output.
Syntax
OutGText% ( x, y,
txt$)
Remarks
The OutGText% function uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
Argument Description
────────────────────────────────────────────────────────────────────────────
x A single-precision number that is
the x coordinate of the upper-left
boundary of the first character.
y A single-precision number that is
the y coordinate of the upper-left
boundary of the first character.
txt$ Text string to output.
After the OutGText% function has completed outputting the text, it returns
the pixel length of the character string, and x and y are changed to the
upper-right position of the last character.
RegisterFonts% function
Action
Registers the font-header information from a specified .FON file and returns
the number of fonts registered.
Syntax
RegisterFonts% ( filename$)
Remarks
The RegisterFonts% procedure registers the font-header information from the
.FON file specified in filename$. The font-header information is stored in
the registered-fonts array. This array corresponds to the loaded-fonts array
which contains the character-bit maps of the fonts stored in the .FON file.
Because an .FON file may hold one or more fonts, RegisterFonts% returns the
number of fonts registered by the function.
This procedure will register any number of fonts up to the maximum set with
the SetMaxFonts procedure or to the limit of available memory.
Note
When using the RegisterFonts% procedure, be sure you have access to the
.FON file on disk so that it can find the filename of the currently selected
font.
For more information on loading the fonts, see the LoadFont% procedure.
RegisterMemFont% function
Action
Registers the font-header information of fonts that reside in memory and
returns the number of fonts registered.
Syntax
RegisterMemFont% ( fontseg%, fontoffset%)
Remarks
The RegisterMemFont% procedure uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
fontseg% An integer that is the segment
address of the in-memory font.
fontoffset% An integer that is the offset
address of the in-memory font..
SelectFont ( n)
Remarks
The argument n contains the number of the loaded font that is selected and
becomes the active font.
If n is greater than the maximum number of loaded fonts, the procedure
automatically selects the font number that corresponds to the remainder from
the modular division between n and the number of currently loaded fonts.
For example, if n is 12 and the maximum of loaded fonts is 8, then the font
number selected is 4.
SetGCharSet Sub
Action
Sets the character set used in subsequent graphics characters.
Syntax
SetGCharSet (charset%)
Remarks
The argument charset% is the character set used in mapping input characters
to output characters. charset% is an integer with two possible values:
cIBMChars and cWindowsChars. The two values are constants defined in the
FONTB.BI file.
SetGTextColor Sub
Action
Sets the character color used in subsequent graphic characters.
Syntax
SetGTextColor ( color%)
Remarks
The argument color% is an integer that is the pixel value of the color to
use in graphic characters.
SetGTextDir Sub
Action
Sets the horizontal or vertical orientation of graphics characters.
Syntax
SetGTextDir (dir%)
Remarks
The argument dir% is an integer that specifies a direction for the graphics
characters. Possible values for dir%, and the resulting character
orientation (counterclockwise rotation) are:
╓┌────────────┌──────────────────────────────────────────────────────────────╖
Value Character direction
────────────────────────────────────────────────────────────────────────────
0 0 degrees (no rotation)
1 90 degrees (top of character is to the left)
2 180 degrees (characters are inverted)
3 270 degrees (top of character is to the right)
SetMaxFonts Sub
Action
Sets the maximum number of fonts that are allowed to be registered and
loaded.
Syntax
SetMaxFonts ( maxregistered%, maxloaded%)
Remarks
The SetMaxFonts procedure uses the following arguments:
╓┌───────────────────────────────────────┌───────────────────────────────────╖
Argument Description
────────────────────────────────────────────────────────────────────────────
maxregistered% An integer that specifies the
Argument Description
────────────────────────────────────────────────────────────────────────────
maxregistered% An integer that specifies the
maximum number of fonts that can
be registered.
maxloaded% An integer that specifies the
maximum number of fonts that can
be loaded.
The SetMaxFonts procedure allocates a maximum number of font-header
elements to hold font information. The font information is registered when
the RegisterFonts% function is called. Therefore, SetMaxFont is called
prior to RegisterFonts% or LoadFont%. If SetMaxFonts is not called, the
default number is 10.
SetMaxFonts acts as a complete reinitialization by removing any previously
registered or loaded fonts from memory and then setting the new maximum
limits of fonts that can be loaded or registered.
UnRegisterFonts Sub
Action
Removes registered fonts from memory.
Syntax
UnRegisterFonts ( )
Remarks
The UnRegisterFonts procedure reduces the array storing the font headers to
one element, thereby removing the registered fonts from memory.
Note
When you use UnRegisterFonts to remove the font-header information from the
registered fonts array, you reduce the array to only one position.
Therefore, if you want to re-register fonts, you must call SetMaxFonts to
reset the maximum number of fonts that can be registered; for example,
SetMaxFonts(6,6), before calling the RegisterFonts% function.
♀The User Interface Toolbox
The User Interface toolbox is a group of BASIC procedures and
assembly-language routines that is included with Microsoft BASIC. Together,
these tools allow you to add professional-looking windows and menus to your
programs.
The User Interface toolbox includes many of the user interface features of
the QBX programming environment. When you use the QBX user interface, you
are using many of the features that the toolbox can bring to your own
programs.
* You can define pull-down menus to support:
Color
Mouse
Access keys
Shortcut keys
* You can choose these options in overlapping character-based windows:
Color
Closable windows
Movable windows
Resizable windows
Title bars
Window-border character
* You can use list boxes and alert boxes.
* You can specify dialog boxes with:
Edit fields
Option buttons
Command buttons
Area buttons
The BASIC source code to all of the toolbox procedures is provided with
Microsoft BASIC. You can use these procedures as listed, or alter or expand
their functionality to meet your requirements. Even though most of the
procedures are written in BASIC, they are fast enough for most applications.
There is also an assembly-language object routine, UIASM.OBJ, to ensure that
you get quick response from your user-interface design. This
assembly-language module is linked into the libraries and Quick libraries
created from the User Interface toolbox.
What Makes Up the User Interface Toolbox
The User Interface toolbox actually consists of four parts - that is, four
separate BASIC source-code files - and an include file for each. The files
are:
* MENU.BAS, MENU.BI
* WINDOW.BAS, WINDOW.BI
* MOUSE.BAS, MOUSE.BI
* GENERAL.BAS, GENERAL.BI
In each case, the .BAS file contains the actual code for the procedures and
the .BI file contains user-defined type definitions and procedure
declarations used in the .BAS file.
The following discussion briefly explains the contents of each part of the
User Interface toolbox.
Menus
The MENU.BAS source-code file contains all the procedures that let you
create custom menus in your programs. These procedures are dependent on the
other parts of the User Interface toolbox (GENERAL.BAS and MOUSE.BAS). If
you use the procedures in MENU.BAS, you must include GENERAL.BI, MOUSE.BI,
and MENU.BI in your program so you have the proper declarations and
definitions. In addition to procedure declarations, the header file MENU.BI
contains definitions of several user-defined types that are used in global
variables to store menu configuration information.
A more detailed explanation of menus and their application is described in
the MENU.BAS section below.
Windows
The WINDOW.BAS source-code file contains the procedures that let you create
custom character-based windows in your programs. WINDOW.BAS is dependent on
all the other parts of the User Interface toolbox; therefore, when you use
the procedures in WINDOW.BAS, you must include GENERAL.BI, MOUSE.BI,
MENU.BI, and WINDOW.BI so that all declarations and definitions on which
WINDOW.BAS depends are available.
The header file WINDOW.BI contains procedure declarations along with the
definitions of user-defined types. These user-defined types are used to
store information about the characteristics of windows, buttons, and edit
fields.
Mouse
The MOUSE.BAS source-code file provides mouse support. The procedures in
this code can be used by themselves if need be, but they were designed as an
integral part of the User Interface toolbox. The routines specifically
support the Microsoft Mouse. A Microsoft Mouse and driver are recommended.
However, the procedures support any pointing device with a 100 percent
Microsoft-Mouse-compatible driver. A Microsoft driver (MOUSE.COM) is shipped
with BASIC.
If you use the procedures in MOUSE.BAS, you must include GENERAL.BI and
MOUSE.BI in your program so you will have the proper declarations and
definitions. The header file MOUSE.BI includes procedure declarations for
the MOUSE.BAS file.
General
The GENERAL.BAS source-code file contains a number of general purpose
character-based routines that are used in both the MENU.BAS and WINDOW.BAS
files. While these files can be used by themselves, they are intended to
support the other procedures in the User Interface toolbox. If you use any
of the procedures in GENERAL.BAS, you must include the header file,
GENERAL.BI.
The header file GENERAL.BI contains a user-defined type definition (RegType)
that is used with the Interrupt routine to access DOS interrupt services for
mouse support. This DOS interrupt also returns the shift state of special
keys, and scrolls screen areas. GENERAL.BI contains a number of global
constant definitions that apply throughout the User Interface toolbox. These
definitions are described in the following table:
Constant Value Comment
FALSE 0
TRUE -1
MINROW 2 Minimum number of rows on screen
MAXROW 25 Maximum number of rows on screen
MINCOL 1 Minimum number of columns on screen
MAXCOL 80 Maximum number of columns on screen
MAXMENU 10 Maximum number of menus on menu bar
MAXITEM 20 Maximum number of items on a menu
MAXWINDOW 10 Maximum number of windows on screen
MAXBUTTON 50 Maximum number of buttons on screen
MAXEDITFIELD 20 Maximum number of edit fields on screen
MAXHOTSPOT 20 Maximum number of active areas on screen
Note
----
An active area is defined as any area that can be selected by the user,
including all types of buttons and edit fields, and any of the special
characters used to affect windows.
How to Use the Toolbox in Your Programs
You can incorporate the User Interface toolbox into your programs in three
ways. The first is to simply include the source-code files you plan to use
in your program. For each source-code file you include, be sure to also
include the associated .BI file. Use the $INCLUDE metacommand to include
external files in your program.
The second way is to load each BASIC source-code file as a separate module
and use a Quick library only for the assembly-language routines. You should
use this method if you are planning to alter or expand the functionality of
the User Interface toolbox. Create the Quick library you need with the
following command:
LINK /Q UIASM.OBJ QBX.LIB, UIASM.QLB,,QBXQLB.LIB;
The final method - and most practical when creating stand-alone programs -
is to create a Quick library that uses the procedures in the BASIC
source-code files and the assembly-language files. This is somewhat more
difficult, but is still quite easy. If you chose to have Quick libraries
created when you first installed BASIC, you already have the Quick library
you need. If you didn't, you'll have to make it yourself. To begin, be sure
that you are in the QBX directory where all of the .LIB files that came with
the program are located.
Creating a complete Quick library involves several steps. First you'll have
to create a Quick library that includes needed procedures that are already
in the QBX libraries (QBX.QLB and QBX.LIB) plus the User Interface toolbox
object file, UIASM.OBJ. You can do this at the system prompt with the
following command:
LINK /Q UIASM.OBJ QBX.LIB, UIASM.QLB,,QBXQLB.LIB;
Next, create the parallel .LIB library using the same files you just used to
make the Quick library. Use the following command:
LIB UIASM.LIB+UIASM.OBJ+QBX.LIB;
Once you've created the first two libraries, you can create the libraries
that include not only the assembly-language routines, but the BASIC
procedures as well. The easiest way is to do this from the QBX programming
environment. Start QBX with the /L option and specify the Quick library that
you just created, as follows:
QBX /L UIASM.QLB
Once you are in the QBX programming environment, use the File menu to load
each of the individual files you want to include in your User Interface
toolbox library. For example, if you want to use menus in your program, load
GENERAL.BAS, MOUSE.BAS, and MENU.BAS. GENERAL.BAS and MOUSE.BAS are required
because of dependencies that exist between the components of the User
Interface toolbox. If you want windows, load GENERAL.BAS, MOUSE.BAS,
MENU.BAS, and WINDOW.BAS.
With all of the files loaded, choose Make Library from the Run menu. When
prompted for a library name, use the name UITBEFR.QLB. Press Return and two
libraries will be created for you. The first is the Quick library that you
will use whenever you want to incorporate menus into your programs that run
in QBX. The second is the parallel .LIB file that will allow you to create a
stand-alone .EXE file from your BASIC program.
If you change any of the BASIC code that comprises the User Interface
toolbox, you can relink those object modules and create new libraries and
Quick libraries as needed. More complete information about creating
libraries and using mixed-language programming can be found in Chapter 18,
"Using LINK and LIB" in the Programmer's Guide.
If you use a library or Quick library that contains procedures from one or
more of the User Interface toolbox source-code files, you must include the
.BI file for that source-code file into your program before you call any of
the library's procedures. If you include a complete source-code file, it is
not necessary to include the .BI file, because an $INCLUDE metacommand is
already in the source-code file. However, if you include the source-code
file in your program, you must ensure that you also include any other files
(either .BAS or .BI) that the included code might depend on. For example, if
you use WINDOW.BAS, you must also include all of the other parts of the User
Interface toolbox. The procedures in WINDOW.BAS depend on definitions,
declarations, and procedures in each of the other parts.
Detailed Description
The following sections contain a detailed descriptions of each of the
individual parts of the User Interface toolbox. Because the User Interface
toolbox is character based, many procedures require row and column
coordinates as arguments. Where these are required, the following
definitions apply:
row%, col% An integer pair that describes a screen position.
row1%, col1% An integer pair that describes the upper-left corner of an
area.
row2%, col 2% An integer pair that describes the lower-right corner of an
area.
Note
----
The row% and col% coordinates can be actual screen coordinates. However,
often they are coordinates that are relative to the upper-left corner of the
current window.
MENU.BAS
Using the procedures in MENU.BAS is straightforward. In most cases, the
demonstration program UIDEMO.BAS provides enough information for a BASIC
programmer of some experience to get started. However, a few notes of
introduction are in order.
When you use the procedures in MENU.BAS, you must provide the following
global array declarations in your program, in the order shown:
COMMON SHARED /uitools/GloMenu AS MenuMiscType
COMMON SHARED /uitools/GloTitle() AS MenuTitleType
COMMON SHARED /uitools/GloItem() AS MenuItemType
DIM GloTitle(MAXMENU) AS MenuTitleType
DIM GloItem(MAXMENU, MAXITEM) AS MenuItemType
The order is important because the block defined by COMMON in the Quick
library must agree with the block defined by COMMON in the programming
environment. These global arrays are used to store information about the
menus you define.
As previously mentioned, the menus in the User Interface toolbox work like
those in the QBX programming environment. Menu titles are displayed on a
menu bar that extends across the top of the screen in row 1. Associated with
each menu are one or more menu items. From the programmer's standpoint,
menus are numbered from left to right, beginning at 1. Menu items -that is,
those choices associated with each menu - are numbered from top to bottom,
also beginning at 1. For any given menu, menu item 0 is always the menu
title.
The MenuColor procedure lets you select the color scheme for your menus. A
single MenuSet statement is all that is required to set up each menu title
on the menu bar or each menu item associated with a menu.
Menus can be selected with the mouse - by pointing and clicking - or with
the keyboard, by pressing the Alt key and the highlighted letter in the
desired menu title. When a menu is selected, the choices associated with
that menu will pull down, or drop, from the menu bar so that you can see the
choices available. When a pull-down menu is displayed, menu items can be
chosen by pointing and clicking with the mouse, or pressing the highlighted
key associated with that choice. The key combinations used in the latter
selection technique are called access keys. Access keys consist of a series
of menu-item-selection keystrokes; each series begins by pressing the Alt
key.
You also can set up shortcut keys to use in lieu of the mouse or the regular
access keys. Shortcut keys can use any character or extended character,
except those that use the Alt key. For example, you can use Ctrl+X,
Ctrl+F10, or simply F3). To enable a shortcut key, use a ShortCutKeySet
statement to identify the menu and menu item with the definition of the
short-cut key.
Before actually building your menus, you need to initialize global arrays to
speed up menu response. Use the MenuInit procedure to initialize the arrays
you declared and initialize the mouse.
The following code fragment illustrates how to put together a short menu
with one title, two item choices and a means of exiting the menu:
MenuInit ' Initialize everything, including the mouse.
MenuSet 1,0,1,"Menu Title",1 ' Set up menu title.
MenuSet 1,1,1,"Selection 1 F1",11 ' Set up first selection.
MenuSet 1,2,1,"Selection 2 F2",11 ' Last parameter determines
' highlight.
MenuSet 1,3,1,"-",1 ' Make a line across the menu.
MenuSet 1,4,1,"Exit Ctrl-X",2 ' Set up way to get out.
ShortCutKeySet 1,1,CHR$(0)+CHR$(59) ' Set F1 as shortcut key for 1.
ShortCutKeySet 1,2,CHR$(0)+CHR$(60)
ShortCutKeySet 1,4,CHR$(24) ' Set Ctrl-X for Exit.
MenuColor 14,1,12,8,14,3,12 ' Specify color scheme
MenuPreProcess ' Do all necessary calculations.
MenuShow ' Display the menu.
MouseShow ' Make mouse cursor visible.
Notice that the menu title is described as menu 1, item 0. Item 0 means that
the MenuSet statement specifies a menu title, not a menu item. Numbers from
1 through 4 are the remaining selections. Item 3 is special. It's not really
a selection item. The hyphen character (-) causes a bar to be placed across
the pull-down menu. It is useful for breaking up functional groupings of
menu selections. You can't select it, so you should remember to use a SELECT
CASE statement that excludes that item number when processing the
selections. See the demonstration program UIDEMO.BAS for a working example.
Also notice that within the text for Selection 1, F1 is shown to the right.
F1 is the shortcut key for Selection 1 that is programmed using the first
ShortCutKeySet statement. The extended keyboard code for the F1 key is
CHR$(0) + CHR$(59).
Use MenuColor to set up the colors for your menus, the highlighted colors to
use when an item is selected, and the highlighted characters to use when
choosing a menu item from the keyboard.
MenuPreProcess performs the necessary calculations and builds indexes that
help speed up menu execution. MenuShow actually displays the menu bar on the
screen. The three-dimensional shadow and other programming chores are
handled for you automatically. Once the menu bar is displayed, the call to
MouseShow makes the mouse cursor visible.
After you've displayed your menus, you want to be able to have the program
translate the available choices into action. Processing menu selections is
also very straightforward. The MenuInkey$ procedure within a WHILE...WEND
control-flow structure serves well to poll user input. The following code
fragment illustrates how to process user input and translate a user's choice
to a desired action:
Finished = FALSE
WHILE NOT Finished
kbd$ = MenuInkey$ ' Monitor all user input.
SELECT CASE kbd$ ' See what the user entered.
CASE "menu" ' If kbd$ = "menu".
menu = MenuCheck(0) ' Get menu number.
item = MenuCheck(1) ' Get item number.
GOSUB HandleMenuEvent ' Handle selection.
CASE ELSE
.
. ' If kbd$ = anything else.
.
END SELECT
WEND
HandleMenuEvent:
SELECT CASE menu
CASE 1 ' Handles Menu 1 .
SELECT CASE item
CASE 1
Selection1Routine ' Handle selection 1.
CASE 2
Selection2Routine ' Handle selection 2.
CASE 4
Finished = TRUE ' Handle Exit.
END SELECT
END SELECT
RETURN
The code shown above processes keyboard input and mouse input with
MenuInkey$. If you wanted to preclude any keyboard input, you could use
MenuEvent instead of MenuInkey$, as follows:
WHILE NOT Finished
MenuEvent ' Monitor menu events only.
IF MenuCheck(2) THEN
menu = MenuCheck(0) ' Get menu number.
item = MenuCheck(1) ' Get item number.
GOSUB HandleMenuEvent ' Determine which item.
END IF
. ' What to do if MenuCheck(2)
. ' hasn't changed.
.
WEND
The preceding information is intended to give you an overview of how the
menus work. With this information and the detailed information provided for
each procedure, you should be able to incorporate menus into your BASIC
applications. Be sure to see the example code in UIDEMO.BAS that
demonstrates how most of the procedures are used.
A description of each procedure that comprises MENU.BAS is next.
MenuCheck FUNCTION
Action
Returns an integer that indicates which menu selection, if any, was made
following a menu or shortcut-key event.
Syntax
variablename% = MenuCheck(action%)
Remarks
The MenuCheck procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
action%
-------
An integer that identifies the specific information requested. Values are as
follows:
Value Associated action/Return value
0 Checks to see if a menu item was selected since
MenuCheck was last called.
If a menu item was selected, MenuCheck returns the number of
the menu and sets the global variables so that when MenuCheck(1) is called,
the appropriate menu item number is returned. If no menu item was selected,
returns 0.
1 Returns the matching menu item of the last menu selection.
MenuCheck(1) is reset each after each call to MenuCheck(0).
2 Returns true (-1) if menu item has been selected as of the last
MenuCheck(0) call, or false (0) if not. If a selection has occurred, use
MenuCheck(0) and MenuCheck(1) to determine what selection was made.
MenuCheck(2) changes no values.
The MenuCheck procedure simulates polling for a menu event. When a menu
event occurs, global variables are set to their appropriate values.
MenuCheck(0) then returns the menu number, or 0 if no menu was selected
since the last call to MenuCheck.
You can use MenuCheck to provide information about menu selection as
follows:
kbd$ = MenuInkey$
SELECT CASE kbd$
CASE "menu"
menu = MenuCheck(0)
item = MenuCheck(1)
MouseHide
PRINT menu, item
MouseShow
CASE ELSE
PRINT kbd$
END SELECT
or
MenuEvent
IF MenuCheck(2) THEN
menu = MenuCheck(0)
item = MenuCheck(1)
MouseHide
PRINT menu, item
MouseShow
END IF
See Also
MenuEvent, MenuInkey$, ShortCutKeyEvent
Example
See the main loop of the code example UIDEMO.BAS for a practical
implementation of the MenuCheck procedure.
MenuColor SUB
Action
Assigns colors to the components of a menu.
Syntax
MenuColor fore%, back%, highlight%, disabled%, cursorfore%, cursorback%,
cursorhi%
Remarks
The MenuColor procedure uses the following arguments:
fore%
-----
An integer that defines menu foreground color (0 - 15).
back%
-----
An integer that defines menu background color (0 - 7).
highlight%
----------
An integer that defines text color (0 - 15) of the access key character.
disabled%
---------
An integer that defines text color of disabled items (0 - 15).
cursorfore%
-----------
An integer that defines the menu cursor foreground color (0 - 15).
cursorback%
-----------
An integer that defines the menu cursor background color (0 - 7).
cursorhi%
---------
An integer that defines text color (0 - 15) of the access key character when
the menu cursor is on that menu item.
The values specified are placed into global variables. You can use any color
scheme you choose within the range of available colors. Shadows that appear
beneath menu windows are always black.
Use MenuColor in your program to set up menu colors. Colors should be
initialized before the menu is displayed the first time. If colors are not
initialized, the default monochrome color scheme places the following
integers into the argument list (in order): 0, 7, 15, 8, 7, 0, 15. This
results in a monochrome display.
If you change colors while your program is running, use MenuShow to show the
changes.
See Also: MenuShow
Example
See the SetupMenu procedure in the code example UIDEMO.BAS for the specific
implementation of the MenuColor procedure.
MenuDo SUB
Action
Used internally by other procedures in MENU.BAS. Do not use or alter this
procedure.
Syntax
MenuDo
Remarks
The MenuDo procedure is used only within MENU.BAS to process menu selection
using the mouse and keyboard. To process menu selections in your program,
you should use MenuInkey$ or MenuEvent, both of which use this procedure.
If menus are enabled (using MenuOn), MenuDo takes control of the program
when the user is selecting a menu item by any means. MenuDo controls the
display and responds to user input until a selection has been made. Once a
selection has been made, use the MenuCheck procedure to determine which menu
item was selected.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: MenuEvent, MenuInkey$
MenuEvent SUB
Action
Monitors user input to determine if a menu item is being chosen, with either
the mouse or the keyboard.
Syntax
MenuEvent
Remarks
If MenuEvent detects either a pressed Alt key or a mouse button press while
the mouse cursor is on the top row, program control is transferred to
MenuDo. MenuDo retains program control until an item is selected or the user
aborts the menu process either by releasing the mouse button somewhere other
than the top row or by pressing the Esc key. Once an item is selected, use
MenuCheck to evaluate the selection.
MenuEvent is used by the MenuInkey$ procedure to determine when a user has
pressed the Alt key in conjunction with a keyboard selection or has selected
a menu by moving the mouse cursor to the top row and pressing the left mouse
button.
See Also: MenuInkey$, ShortCutKeyEvent
MenuInit SUB
Action
Initializes global menu arrays and the mouse driver-servicing routines.
Syntax
MenuInit
Remarks
To enable mouse driver servicing, MenuInit calls MouseInit in MOUSE.BAS.
Use MenuInit at or near the beginning of any program that uses the menu
procedures provided in the User Interface toolbox. You must call MenuInit
before any other menu procedures are used.
See Also: MenuPreProcess
Example
See the initialization section in the code example UIDEMO.BAS for a specific
implementation.
MenuInkey$ FUNCTION
Action
Performs a BASIC INKEY$ procedure, as well as both a MenuEvent procedure and
a ShortCutKeyEvent procedure, returning a string.
Syntax
variablename$ = MenuInkey$
Remarks
The MenuInkey$ procedure operates exactly like the standard BASIC INKEY$
procedure, but additionally performs MenuEvent and ShortCutKeyEvent
procedures. If either a menu event or a shortcut-key event occurs,
MenuInkey$ returns the word "menu" instead of the normally expected INKEY$
value. When MenuInkey$ returns the word "menu," use MenuCheck to determine
which menu and menu item was selected.
See Also: MenuDo, MenuEvent, ShortCutKeyEvent
Example
See the main loop in the code example UIDEMO.BAS for a specific
implementation.
MenuItemToggle SUB
Action
Toggles the state of of the selected menu item between 1 (enabled) and 2
(enabled with a check mark) to indicate selection of the menu item.
Syntax
MenuItemToggle menu%, item%
Remarks
The MenuItemToggle procedure uses the following arguments:
menu%
-----
An integer that identifies the position (from left to right) of the affected
menu.
item%
-----
An integer that identifies the number (from top to bottom) of the menu item
within the menu.
Use MenuItemToggle whenever you want to indicate that a particular menu item
has been selected. It is not necessary to re-execute MenuPreProcess after
performing a MenuItemToggle operation.
See Also: MenuPreProcess, MenuSetState
MenuOff SUB
Action
Turns off menu and shortcut-key event processing.
Syntax
MenuOff
Remarks
Menu and shortcut-key event processing is disabled by setting the global
variable GloMenu.MenuOn to FALSE (0). When menu event processing is off,
MenuDo ignores any mouse or keyboard activity that would normally trigger a
menu event.
Use MenuOff anytime you want to turn menu event processing off.
See Also: MenuOn
MenuOn SUB
Action
Turns on menu and shortcut-key event processing.
Syntax
MenuOn
Remarks
Menu and shortcut-key event processing is enabled by setting the global
variable GloMenu.MenuOn to TRUE (-1). When menu event processing is on,
MenuDo takes control of the display and the program when any mouse or
keyboard activity occurs to trigger a menu event.
Use MenuOn anytime you want to turn menu event processing back on after
disabling with MenuOff.
See Also: MenuOff
MenuPreProcess SUB
Action
Performs calculations and builds indexes so the menu procedures run faster.
Syntax
MenuPreProcess
Remarks
Use MenuPreProcess anytime MenuSet is performed one or more times, and any
time the state of a menu item is changed using MenuSetState to change to or
from the empty (-1) or not displayed state. You must call MenuPreProcess
anytime changes other than item selection changes are made to the menus.
See Also: MenuSet, MenuSetState
Example
See the SetupMenu procedure in the code example UIDEMO.BAS for a specific
implementation.
MenuSet SUB
Action
Defines the structure of your menus and defines the access keys associated
with individual menu selections.
Syntax
MenuSet menu%, item%, state%, text$, accesskey%
Remarks
The MenuSet procedure uses the following arguments:
menu%
-----
An integer that identifies the position (from left to right) of a menu on
the menu bar.
item%
-----
An integer that identifies the position (from top to bottom) of the menu
item within the menu. If item% is 0, then text$ is the menu title. Other
numbers indicate consecutive menu selections.
state%
------
An integer that indicates the state of the menu item:
Value Menu state that appears on menu
0 Disabled - appears in color defined by the disabled% variable set
with MenuColor.
1 Enabled - this is the normal state.
2 Enabled with a check mark.
text$
-----
A string that is the name of the menu item. Menu titles are limited to 15
characters; individual menu items are limited to 30 characters.
accesskey%
----------
An integer that indicates the position, within text$, of the character that
is used to choose the menu item. This access key is highlighted in color
defined by the highlight% variable set with MenuColor.
Use MenuSet to initialize the contents of your menus. A separate MenuSet
entry is required for each item, including the title on each menu. Each
MenuSet entry defines either a menu title or a menu item that is to be
displayed and the state of individual menu items. Menu items can be enabled,
disabled, checked, or even made invisible. You also can specify access keys
for menu items to allow one-stroke selection.
MenuPreProcess must be executed after a series of MenuSet statements or any
time the state of a menu item is changed using MenuSetState. MenuShow must
be re-executed if any change to the menu title has occurred.
See Also: MenuPreProcess, MenuSetState, MenuShow
Example
See the SetupMenu procedure in the code example UIDEMO.BAS for a specific
implementation.
MenuSetState SUB
Action
Explicitly assigns the state of a menu item.
Syntax
MenuSetState menu%, item%, state%
Remarks
The MenuSetState procedure uses the following arguments:
menu%
-----
An integer that identifies the position (from left to right) of the affected
menu.
item%
-----
An integer that identifies the number of the menu item within the menu.
state%
------
An integer that indicates the state of the menu item:
-1 Empty - does not appear on menu.
0 Disabled - appears in color defined by the disabled% variable set
with MenuColor.
1 Enabled - this is the normal state.
2 Enabled with a check mark.
Use MenuSetState whenever you want to change the state of a particular menu
item. You must re-execute MenuPreProcess if the state of the menu item
changes to or from the empty or not displayed state.
See Also: MenuPreProcess
MenuShow SUB
Action
Draws the menu bar across the top of the screen.
Syntax
MenuShow
Remarks
All menu titles that have been established with MenuSet are displayed. Use
MenuShow to initially display your menu bar once it has been defined with
MenuSet, and use it each time you change the menu bar.
See Also: MenuPreProcess
Example
See the initialization section in the code example UIDEMO.BAS for a specific
implementation.
ShortCutKeyDelete SUB
Action
Deletes the shortcut key associated with a particular menu item.
Syntax
ShortCutKeyDelete menu%, item%
Remarks
The ShortCutKeyDelete procedure uses the following arguments:
menu%
-----
An integer that identifies the position (from left to right) of the affected
menu.
item%
-----
An integer that identifies the number of the menu item within the menu.
Use ShortCutKeyDelete anytime you want to void shortcut keys that were
previously established with ShortCutKeySet.
See Also: ShortCutKeyEvent, ShortCutKeySet
ShortCutKeyEvent SUB
Action
Polls user input to determine if a menu item is being selected by using one
of the shortcut keys.
Syntax
ShortCutKeyEvent kbd$
Remarks
The argument kbd$ is a string that contains a character entered at the
keyboard. ShortCutKeyEvent checks kbd$ against a list of shortcut keys
defined using ShortCutKeySet. If a match is found, the proper menu and item
are selected. This duplicates exactly the functionality of the MenuEvent
procedure. Use MenuCheck to determine which menu and item were selected.
If you use MenuInkey$ in your program, ShortCutKeyEvent is automatically
performed; if you use the BASIC INKEY$ procedure, you must explicitly call
ShortCutKeyEvent to process shortcut-key events.
See Also: MenuCheck, ShortCutKeyDelete, ShortCutKeySet
ShortCutKeySet SUB
Action
Assigns shortcut keys to individual menu items.
Syntax
ShortCutKeySet menu%, item%, kbd$
Remarks
The ShortCutKeySet procedure uses the following arguments:
menu%
-----
An integer that identifies the position (from left to right) of the affected
menu.
item%
-----
An integer that identifies the number of the menu item within the menu.
kbd$
----
A string that indicates which character is allowed as a shortcut key for
selection of the menu item. The string argument kbd$ can be any single
character, or any extended characters, except those that use the Alt key.
Without shortcut keys, each menu item can be selected by pressing the Alt
key and the highlighted character in the menu name, followed by the
highlighted letter in the menu item. CommandKeySet provides additional
functionality by allowing you to specify a single character, such as
Shift+F1 or F1, as a shortcut to menu item selection. A separate
ShortCutKeySet entry is required for each shortcut key you assign.
Use ShortCutKeySet statements during menu initialization at the same place
where MenuSet is used.
See Also: MenuSet, ShortCutKeyDelete, ShortCutKeyEvent
Example
See the SetupMenu procedure in the code example UIDEMO.BAS for a specific
implementation.
WINDOW.BAS
As with MENU.BAS, you can learn much about using the procedures in
WINDOW.BAS by studying the demonstration program UIDEMO.BAS, which is
provided as a code example. However, a few words of introduction will be
helpful. The best way to get a feel for the ease of use of the window
procedures is to experiment for yourself, using the code in the
demonstration as an example.
In addition to the global-array declarations used with MENU.BAS, you must
declare the following global arrays in your program, in the order shown, if
you use the procedures in WINDOW.BAS:
COMMON SHARED /uitools/GloWindow() AS WindowType
COMMON SHARED /uitools/GloButton() AS ButtonType
COMMON SHARED /uitools/GloEdit() AS EditFieldType
COMMON SHARED /uitools/GloStorage AS WindowStorageType
COMMON SHARED /uitools/GloBuffer$()
DIM GloWindow(MAXWINDOW) AS WindowType
DIM GloButton(MAXBUTTON) AS ButtonType
DIM GloEdit(MAXEDITFIELD) AS EditFieldType
DIM GloWindowStack(MAXWINDOW) AS INTEGER
DIM GloBuffer$(MAXWINDOW +1,2)
These global arrays are used to store information about the windows you plan
to use in your program. The window effects provided by WINDOW.BAS let you
open and use text windows virtually anywhere on your screen. For each
window, you can independently define the following window characteristics:
* Initial position, by row and column
* Color
* Ability to close window or not
* Ability to move window or not
* Ability to resize window or not
* Window title
* Border characters
You also can define as modal windows any of the windows you make. A modal
window is a window that forces the user to respond to a prompt within the
window itself. You cannot select, either with the mouse or the keyboard,
anything outside the window's border. An alert message box is an example of
a modal window.
A single WindowOpen statement lets you open your window. Once you've opened
a window, you can fill it with text, edit fields, list boxes with scroll
bars, and push buttons of several types, all of which behave much like the
QBX user interface. If you open several windows, you can move between them
by using the mouse to select the one you want. A single procedure, WindowDo,
monitors your mouse and keyboard activity while a window is open, and
responds according to your input.
To put text in whatever window is active, WindowLocate lets you specify
where the text is to go and WindowPrint lets you print it there. Edit fields
(boxes that contain some text for you to either accept or change) are
created in a window using EditFieldOpen. They are closed with
EditFieldClose.
List boxes with scroll bars are displayed by passing an array containing the
items in the list to the ListBox procedure. In addition to a list of items,
List boxes always contain OK and Cancel command buttons.
An assortment of buttons, with a full range of features, are placed on the
screen with the ButtonOpen procedure. Supported button types and their
behavior are described in the following table:
Button type Explanation
Command button Confirms settings, gets help, or escapes.
Option button Selects one of several options (use direction keys).
Check box Turns one option on or off (use Spacebar).
Area button An invisible button on the screen that occupies a
defined area. When selected, causes some event to occur.
Vertical scroll bar Vertically scrolls long lists or screen areas.
Horizontal scroll bar Horizontally scrolls screen areas that are wider than
the active window.
Before opening a window - in fact, before using any of the routines in
WINDOW.BAS - you must do some program initialization. The following code
fragment illustrates how to do the initialization and how to use some of the
procedures in WINDOW.BAS:
MenuInit ' Initialize menus and mouse.
WindowInit ' Initialize windows.
MouseShow ' Make mouse cursor visible.
WindowOpen 1,5,25,15,45,0,3,0,3,0,-1,-1,0,0,0,"-Window 1-"
WindowPrint 1,"" ' Put a blank line at the top.
WindowPrint 1,"Features:" ' Put text in the window.
WindowPrint 1,"Title bar"
WindowPrint 1,"Closable window"
WindowPrint 1,"No border"
ButtonOpen 1,2,"OK",11,8,1,0,1 ' Open an OK button.
WindowOpen 2,8,29,17,49,0,5,0,5,15,-1,-1,0,0,1,"-Window 2-"
WindowPrint 1, "" ' Put a blank line at the top.
WindowPrint 1, "Features:" ' Put text in the window.
WindowPrint 1, "Title bar"
WindowPrint 1, "Closable window"
WindowPrint 1, "Single-line border"
WindowLine 9 ' Put a line across the bottom.
ButtonOpen 1,2,"OK",11,8,1,0,1
ExitFlag = FALSE
WHILE NOT ExitFlag
WindowDo 1,0 ' Monitor for a window event.
SELECT CASE Dialog(0) ' Return what event occurred.
CASE 1,4,6 ' Handle user actions:
WindowClose WindowCurrent ' Selecting OK, selecting the
' close box, or pressing Enter.
IF WindowCurrent = 0 THEN ' Just in case it's the last
ExitFlag = TRUE ' or only window.
END IF
CASE 3 ' Handle selecting another window
WindowSetCurrent Dialog(3) ' and making it current.
CASE 9 ' Handle pressing Esc.
ExitFlag = TRUE
CASE ELSE ' Handle everything else.
END SELECT
WEND
WindowClose 0 ' Close all windows.
MouseHide ' Hide the mouse cursor.
COLOR 15, 0 ' Change colors back to original.
CLS ' Clear the screen.
END
The code fragment opens two windows, each of a different color. Both contain
some text about the features that are available in that window. Both also
contain an OK command button that, when chosen, causes the selected window
to close.
Both windows are movable. To move a window, move the mouse cursor to any of
the dot-pattern (ASCII 176) characters adjacent to the title bar, or to the
title bar itself. Press the left mouse button and drag a window by moving
the mouse. Release the button when you are satisfied with the position.
Close a window by selecting the equal sign (=) in the upper-left corner of
the window. Pressing Enter while either window is selected has the same
effect as choosing the OK command button or selecting the window-close
control character (=). Close a window by using WindowClose. WindowClose
closes the window and any buttons or edit fields that may be open within the
window.
You can move between the two windows and close either or both of them in any
order. When both are closed, the program ends. When a window can be resized
(the windows in the example cannot), a plus (+) character is displayed in
the lower-right corner. Select the plus character and drag the mouse to
resize the window.
The preceding information is intended to give you an overview of how the
toolbox windows work. With this overview and the following detailed
information about each procedure, you should be able to easily incorporate
windows into your BASIC programs. The example code in UIDEMO.BAS
demonstrates how most of the procedures are used.
A description of each procedure that comprises WINDOW.BAS follows.
Alert FUNCTION
Action
Displays a window with one to three buttons that indicate choices for the
user.
Syntax
variablename$ = Alert(style%, text$, row1%, col1%, row2%, col 2%, b1$, b2$,
b3$)
Remarks
The Alert procedure returns an integer from 1 to 3, inclusive, indicating
which button was selected by the user. Use Alert whenever you want to
display a dialog box and force a user decision. The Alert procedure uses the
following arguments:
variablename$
-------------
Any BASIC variable name, including the name of a record variable or record
element.
style%
------
An integer that indicates the style of the text to be displayed. The values
of style% are:
1 Truncated printing. If text is longer than the window, it is
truncated. The text cursor is moved to the first character of the next line.
2 Character wrapping. If text is longer than the window, the text
continues on the next line.
3 Text wrapping. Same as style 2 except that text is wrapped only at
spaces.
4 Truncated centering. Text is centered on the current line. If text is
too long, it is truncated.
text$
-----
A string that contains the text to be displayed in the dialog box. You can
force a new line in text$ by using the vertical bar character ( | ). Use
several together for more than one blank line.
row1%, col1%
------------
An integer pair that specifies absolute screen row and column coordinates.
row2%, col 2%
-------------
An integer pair that specifies the lower-right-corner coordinates of
an area.
b1$
---
A string that contains the text for button 1.
b2$
---
A string that contains the text for button 2.
b3$
---
A string that contains the text for button 3.
If you use fewer than three buttons, use a null string ("") for the text of
any unused buttons. All alert windows are modal; that is, they do not allow
selection outside their boundaries. If you do not provide at least one
button in your alert window, the Alert procedure will place a single OK
button in the window for you.
You must ensure that the window you have described is large enough to
contain all three buttons on the bottom row, that the window is at least
three rows high, and that the window is large enough to contain text$. If
the window is too small or any other problem occurs, the Alert procedure
returns 0.
See Also: Dialog, ListBox
Example
See the DemoAlert procedure in the code example UIDEMO.BAS for a specific
implementation.
BackgroundRefresh SUB
Action
Used internally by other procedures in WINDOW.BAS. Do not use or alter this
procedure.
Syntax
BackgroundRefresh handle%
Remarks
The BackgroundRefresh procedure restores a previously saved background from
a global array to the area where a window was displayed. The argument
handle% is an integer that indicates the number of the window whose
background is being restored. This can be any number between 1 and the value
declared in the constant MAXWINDOW.
If you want to restore a background, use the PutBackground procedure in
GENERAL.BAS.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: WindowClose, WindowDo, WindowSetCurrent
BackgroundSave SUB
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
BackgroundSave handle%
Remarks
The BackgroundSave procedure saves the background (the area behind where a
window is to be displayed) in a global array. The argument handle% is an
integer that indicates the number of the window whose background is being
saved. This can be any number between 1 and the value declared in the
constant MAXWINDOW.
If you want to save a background, use the GetBackground procedure in
GENERAL.BAS.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: WindowDo, WindowOpen,WindowSetCurrent
ButtonClose SUB
Action
Erases the specified button from the current window and deletes it from the
global arrays.
Syntax
ButtonClose handle%
Remarks
The ButtonClose procedure is used to close individual buttons that have been
opened with ButtonOpen. The argument handle% is an integer that indicates
the number of the button being closed. This can be any number between 0 and
the value declared in the constant MAXBUTTON, inclusive. If handle% is 0,
all buttons in the current window are closed.
If the WindowClose procedure is used to close a window that contains
buttons, you need not use this procedure, because all buttons associated
with a closing window are closed automatically.
See Also: ButtonOpen, WindowClose
ButtonInquire FUNCTION
Action
Returns an integer that identifies the state of a specified button.
Syntax
variablename% = ButtonInquire(handle%)
Remarks
The ButtonInquire procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
handle%
-------
An integer that indicates the number of the button whose state is requested.
This can be any number between 1 and the value declared in the constant
MAXBUTTON, inclusive.
The ButtonInquire procedure is used when you need to determine the state of
a type 1, 2, 3, 6, or 7 button, as specified in ButtonOpen.
See Also: ButtonSetState
ButtonOpen SUB
Action
Opens a button of the specified type, and places it in the current window at
the window coordinates specified.
Syntax
ButtonOpen handle%, state%, text$, row1%, col1%, row2%, col 2%, buttonType%
Remarks
Use ButtonOpen when you want to place any kind of buttons in open windows.
The ButtonOpen procedure uses the following arguments:
handle%
-------
An integer that indicates the number of the button that is being opened.
This can be any number between 1 and the value declared in the constant
MAXBUTTON, inclusive.
state%
------
An integer that indicates the initial state of the button that is being
opened. For each different button type and state% value, the following
applies:
Type Value Significance
1 1 Normal.
2 Default choice (brackets highlighted).
3 Chosen (highlighted in reverse video).
2 & 3 1 Normal.
2 Selected (checked).
4 0 Does not apply to type 4 (area button).
5 Reserved for future use.
6 & 7 n Indicates the initial position of the scroll bar's position
indicator. It can be between 1 and the maximum position.
text$
-----
A string that contains the text to be displayed in the button. Does not
apply to button types 4, 6, or 7.
row1%, col1%
------------
An integer pair that describes the upper-left corner of an area relative to
the upper-left corner of the current window, not the screen.
row2%, col 2%
-------------
An integer pair that specifies the lower-right corner of an area, relative
to the upper-left corner of the current window, not the screen. The
coordinates row2% and col 2% apply only to button types 4, 6, and 7. Any
values in these arguments are ignored by other button types; however,
arguments must be in the argument list, even if their value is 0.
buttonType%
-----------
An integer that indicates the type of button to be opened. The following is
a list of valid button types:
1 Command button
2 Check box
3 Option button
4 Area button
5 Reserved for future use
6 Vertical scroll bar
7 Horizontal scroll bar
Note that the positioning coordinates are relative to the current window,
not absolute from the top-left corner of the screen. Within each window,
each button has a unique handle% value. Because buttons are local to
specific windows it is permissible to have more than one button with the
same handle% value, provided they are in different windows.
See Also: ButtonClose
ButtonSetState SUB
Action
Sets the state of the specified button and redraws it.
Syntax
ButtonSetState handle%, state%
Remarks
The ButtonSetState procedure operates on buttons in the current window. Use
ButtonSetState to change button state in response to user selection of
different buttons. The ButtonSetState procedure uses the following
arguments:
handle%
-------
An integer that indicates the number of the button whose state is being set.
This can be any number between 1 and the value declared in the constant
MAXBUTTON, inclusive.
state%
------
An integer that indicates the state of the button. For each different button
type and state% value, the following applies:
Type Value Significance
1 1 Normal.
2 Default choice (brackets highlighted).
3 Chosen (highlighted in reverse video).
2 & 3 1 Normal.
2 Selected (checked).
4 0 Does not apply to type 4.
5 Reserved for future use.
6 & 7 n Sets the initial position of the scroll bar's position
indicator. It can be between 1 and the maximum position.
See Also: ButtonInquire
ButtonShow SUB
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
ButtonShow handle%
Remarks
The ButtonShow procedure draws a button on the screen, and is used
automatically by WINDOW.BAS. Normally, you never need to call this procedure
directly since it is automatically called when needed. The argument handle%
is an integer that indicates the number of the button that is being opened.
This can be any number between 1 and the value declared in the constant
MAXBUTTON, inclusive.
Warning
-------
Do not alter this procedure unless you are customizing the User Interface
toolbox and know how the use or alteration of this procedure will affect the
operation of all other procedures in the toolbox.
See Also: ButtonOpen, ButtonSetState, ButtonToggle
ButtonToggle SUB
Action
Toggles a button state between state 1 (normal) and state 2 (selected).
Syntax
ButtonToggle handle%
Remarks
Use ButtonToggle to toggle button state in response to user selection of
different buttons. The argument handle% is an integer that indicates the
number of the button whose state is being toggled. This can be any number
between 1 and the value declared in the constant MAXBUTTON. ButtonToggle
applies only to type 1, 2, or 3 buttons.
See Also: ButtonSetState
Dialog FUNCTION
Action
Returns an integer whose value indicates what type of button, edit-field, or
window event occurred within the WindowDo procedure.
Syntax
variablename% = Dialog(op%)
Remarks
The Dialog procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
op%
---
An integer that defines a specific operation that Dialog is to evaluate. The
following table lists the possible values of op% and the information that is
returned:
op% Return Event/significance
0 0 No event took place.
1 A button was pressed. Use Dialog(1) to determine which button.
2 An edit field was selected. Use Dialog(2) to determine which
field.
3 A window other than the current window was selected. Use
Dialog(3) to determine which window.
4 Current window's close box was selected.
5 Current window needs to be refreshed because it was resized.
6 Enter key was pressed.
7 Tab key was pressed.
8 Shift+Tab was pressed.
9 Esc was pressed.
10 Up Arrow key was pressed.
11 Down Arrow key was pressed.
12 Left Arrow key was pressed.
13 Right Arrow key was pressed.
14 Spacebar was pressed.
15 Current window was moved.
16 Home key was pressed.
17 End key was pressed.
18 PgUp key was pressed.
19 PgDn key was pressed.
20 Menu item was chosen.
1 * Returns the number of the button just pressed. May be from 1
to the value declared in MAXBUTTON, inclusive.
2 * Returns the number of the edit field just selected. May be
from 1 to the value declared in MAXEDITFIELD, inclusive.
3 n Returns the number of the window just selected. May be from 1
to the value declared in MAXWINDOW, inclusive.
4 - 15 Reserved for future use.
17 * Returns the row of the cursor within the field of button type
4. (See ButtonOpen.) May be from 1 to the value declared in MAXROW
inclusive.
18 * Returns the column of the cursor within the field of button
type 4. (See ButtonOpen.) May be from 1 to the value declared in MAXCOL,
inclusive.
19 -2 Selected Down or Right direction key on scroll bar (button
type 6 or 7).
-1 Selected Up or Left direction key on scroll bar (button type 6
or 7)
* Selected a position on grayed area of scroll bar. May be from
1 to the maximum number of positions on the scroll bar.
20 Reserved for future use.
Using an op% value of 0, you can determine what happened; using the other
arguments, you can determine where it happened.
See Also: Alert, ListBox
Example
See the individual procedures in the code example UIDEMO.BAS for examples of
specific usage.
ditFieldClose SUB
Action
Erases the specified edit field from the current window and deletes it from
the global arrays.
Syntax
EditFieldClose handle%
Remarks
Use EditFieldClose when you want to erase an edit field from a window rather
than close the window. The argument handle% is an integer that indicates the
number of the edit field being closed. This can be any number between 0 and
the value declared in the constant MAXEDITFIELD, inclusive. If handle% is 0,
all edit fields in the current window are closed. If the WindowClose
procedure is used to close a window that contains edit fields, you need not
use this procedure since all edit fields associated with a closing window
are automatically closed.
See Also: EditFieldOpen, WindowClose
EditFieldInquire FUNCTION
Action
Returns the string associated with the specified edit field.
Syntax
variablename$ = EditFieldInquire(handle%)
Remarks
Use EditFieldInquire when you need to return the edit string associated with
a particular edit field. The EditFieldInquire procedure uses the following
arguments:
variablename$
-------------
Any BASIC variable name, including the name of a record variable or record
element.
handle%
-------
An integer that indicates the number of the edit field whose edit string is
requested. This can be any number between 1 and the value declared in the
constant MAXEDITFIELD, inclusive.
See Also: EditFieldOpen
Example
See the DemoDialog procedure in the code example UIDEMO.BAS for a specific
implementation.
Argument Description
EditFieldOpen SUB
Action
Opens an edit field and places it in the current window at the window
coordinates specified.
Syntax
EditFieldOpen handle%, text$, row%, col%, fore%, back%, visLength%,
maxLength%
Remarks
Use the EditFieldOpen procedure anytime you want to open an edit field in
the current window. The EditFieldOpen procedure uses the following
arguments:
handle%
-------
An integer that indicates the number of the edit field that is being opened.
This can be any number between 1 and the value declared in the constant
MAXEDITFIELD, inclusive.
text$
-----
A string that contains the text that is to be initially placed in the edit
field for editing.
row%, col%
----------
An integer pair that describes the upper-left corner of an area, relative to
the upper-left corner of the current window, not the screen.
fore%
-----
An integer that defines the edit field foreground color (0 - 15)
back%
-----
An integer that defines the edit field background color (0 - 7)
visLength%
----------
An integer that indicates the length of the edit field that is visible on
the screen.
maxLength%
----------
An integer that indicates the maximum length of the edit field, up to a
maximum of 255 characters.
Note that the positioning coordinates are relative to the current window,
not absolute from the top left of the screen. The edit field foreground and
background colors may be different from the rest of the window. If the
maximum length of the edit field is greater than the visible length of the
edit field, the field will scroll left and right, as needed, during editing.
See Also: EditFieldClose
Example
See the DemoDialog procedure in the code example UIDEMO.BAS for specific
usage.
FindButton FUNCTION
ebAction
Used internally by the button procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
variablename% = FindButton(handle%)
Remarks
The FindButton procedure returns an index into the global array where a
button is stored. Each button is uniquely described by the window in which
it exists, and a button handle. FindButton assumes the current window.
The FindButton procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
handle%
-------
An integer that indicates the number of the button whose index is requested.
This can be any number between 1 and the value declared in the constant
MAXBUTTON, inclusive.
Warning
-------
Do not alter this procedure unless you are customizing the User Interface
toolbox and you know how the alteration of this procedure will affect the
operation of all other procedures in the toolbox.
See Also: ButtonClose, ButtonInquire, ButtonSetState, ButtonShow,
ButtonToggle, MaxScrollLength, WindowDo
FindEditField FUNCTION
Action
Used internally by WINDOW.BAS. Do not use or alter this procedure.
Syntax
variablename% = FindEditField(handle%)
Remarks
The FindEditField procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
handle%
-------
An integer that indicates the number of the edit field whose index is
requested. This can be any number between 1
and the number declared in the constant MAXEDITFIELD, inclusive.
The FindEditField procedure returns an index into the global array where an
edit field is stored. Each edit field is uniquely described by the window in
which it exists, and an edit field handle. FindEditField assumes the current
window.
Warning
-------
Do not alter this procedure unless you are customizing the User Interface
toolbox and you know how the alteration of this procedure will affect the
operation of all other procedures in the toolbox.
See Also: EditFieldClose, EditFieldInquire, WindowDo
ListBox FUNCTION
Action
Displays a window containing a list box, a scroll bar, an OK button, and a
Cancel button.
Syntax
variablename% = ListBox (text$( ), maxRec%)
Remarks
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
text$( )
--------
A string array that contains the text items to be displayed in the
list box.
maxRec%
-------
An integer that defines the maximum number of entries in the
list box.
With the ListBox procedure, you can use the mouse or keyboard to select any
single item from the text in a list box. To accept the current choice,
select OK. Use Cancel to reject all choices and close the list box. The
ListBox procedure returns an integer that is the number of the item selected
from the text in the list box when OK is selected, or 0 if Cancel is
selected.
Use ListBox when you have a list of things to choose from that may be longer
than the available screen space.
See Also: Alert, Dialog
Example
See the DemoListBox procedure in the code example UIDEMO.BAS for a specific
usage.
MaxScrollLength FUNCTION
Action
Returns an integer that is the maximum number of positions in the specified
scroll bar.
Syntax
variablename% = MaxScrollLength(handle%)
Remarks
The MaxScrollLength procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
handle%
-------
An integer that specifies the scroll bar for which the maximum number of
positions is requested. This is the number that is used to identify the
scroll bar when it is opened using ButtonOpen. This can be any number
between 1 and the value declared in the constant MAXBUTTON, inclusive.
The MaxScrollLength procedure is used to determine how many positions your
scroll bar has. Use this procedure to increment or decrement the cursor
position in response to user selection of the direction arrows to move the
cursor.
See Also: ListBox
Example
See the DemoScrollBar procedure in the code example UIDEMO.BAS for a
specific usage.
WhichWindow FUNCTION
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
variablename% = WhichWindow(row%, col%)
Remarks
The WhichWindow procedure returns an integer that is the window number for
the location specified on the screen. Overlapping windows are taken into
account. The WhichWindow procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
row%, col%
----------
An integer pair that describes a particular point on the screen.
Warning
-------
Do not alter this procedure unless You're customizing the User Interface
toolbox and know how the alteration of this procedure will affect the
operation of all other procedures in the toolbox.
See Also: WindowDo
WindowBorder FUNCTION
Action
Returns a 14-character string that describes the border of the window.
Syntax
border$ = WindowBorder (windowType%)
Remarks
The argument windowType% is an integer that describes a particular window
type.
The border of the window actually determines what characteristics a window
will have. Each character position in the returned string is representative
of a particular component of the border. Some positions in the border have
added significance, in that special characters in those positions implement
certain features. The following list indicates the significance of each
border$ character position and the features implemented by special
characters:
Position Character defined Special effect character
1 Upper-left corner Equal sign (=) makes window closable.
2 Top line Dot-pattern character (ASCII 176) makes
window movable.
3 Upper-right corner
4 Left-side line
5 Middle fill character
6 Right-side line
7 Lower-left corner
8 Bottom line
9 Lower-right corner Plus sign (+) makes window resizable.
10 Left-side intersection
11 Middle line
12 Right-side intersection
13 Shadow flag "S" in this position puts a 3D shadow on
window.
All predefined window types have shadows.
14 Title flag "T" in this position puts a title bar
across the top of
the window if the length of title$ in WindowOpen
is greater than 0.
Twenty-four basic predefined window types are provided in WINDOW.BAS. These
combinations include all of the special features (movable, closable,
resizable, shadow, and title) with three different borders. You can have no
border, a single-line border, or a double-line border. All available options
can be specified with arguments to the WindowOpen procedure.
If you want to create other custom window types, modify the WindowBorder
procedure in WINDOW.BAS to add more window types. By observing the
conventions in the list above, you can create windows that have the features
and any special borders you want. To create custom window types, modify this
procedure and recompile it into your Quick library and .LIB file.
Note
----
The WindowBorder procedure is used internally by WINDOW.BAS and under normal
circumstances will not be called directly by your program. You may wish to
modify and recompile this procedure to extend or alter its functionality.
See Also: ButtonOpen, EditFieldOpen, WindowClose, WindowDo, WindowOpen,
WindowPrintTitle, WindowSetCurrent
WindowBox SUB
Action
Draws a box with a single-line border, within the current window at the
coordinates specified.
Syntax
WindowBox box Row1%, boxCol1%, box Row2%, boxCol 2%
Remarks
The WindowBox procedure uses the following arguments:
box Row1%, boxCol%
------------------
An integer pair that describes the upper-left corner of an area relative to
the upper-left corner of the current window.
box Row2%, boxCol 2%
--------------------
An integer pair that describes the lower-right corner of an area relative to
the upper-left corner of the current window.
The WindowBox procedure is used by the ListBox procedure to create a
single-line box within the window. WindowBox can be used to box any window
area as desired.
See Also: ListBox
WindowClose SUB
Action
Closes a specified window, closing all buttons and edit fields associated
with that window.
Syntax
WindowClose handle%
Remarks
The argument handle% is an integer that indicates the number of the window
being closed. This can be any number between 0 and the value declared in the
constant MAXWINDOW, inclusive. When you close the current window, the top
window becomes the current window. Any button and edit fields associated
with the closing window are also closed. If handle% is 0, all windows are
closed.
See Also: WindowOpen
Example
See the DemoWindow procedure in the code example UIDEMO.BAS for a specific
usage that closes all open windows.
WindowCls SUB
Action
Clears the current window.
Syntax
WindowCls
Remarks
The WindowCls procedure is used whenever you want to erase the text
contained in a window. WindowCls clears the current window using the window
background color (not the text background color) defined when the window was
first opened with WindowOpen.
See Also: WindowColor, WindowOpen, WindowScroll
Example
See the DemoResize procedure in the code example UIDEMO.BAS for a specific
implementation.
WindowColor SUB
Action
Reassigns the values of the text color variables for the current window.
Syntax
WindowColor textFore%, textBack%
Remarks
The WindowColor procedure uses the following arguments:
textFore%
---------
An integer that defines foreground color (0 - 15) of text.
textBack%
---------
An integer that defines background color (0 - 7) of text.
Use WindowColor whenever you want to change the color of the text being
printed in a window. Any printing after using WindowColor is done in the
newly defined colors.
See Also: WindowOpen
WindowCols FUNCTION
Action
Returns an integer that is the number of interior columns in the current
window.
Syntax
variablename% = WindowCols (handle%)
Remarks
The WindowCols procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
handle%
-------
An integer that indicates the number of the window whose column count is
requested. This can be any number between
1 and the value declared in the constant MAXWINDOW, inclusive.
Use WindowCols when you want to determine the number of columns in a window,
especially when dealing with resizable windows. These "interior" columns are
those where text can be displayed.
Argument Description
See Also: WindowRows
WindowCurrent FUNCTION
Action
Returns an integer that is the handle number of the current window.
Syntax
variablename% = WindowCurrent
Remarks
The argument variablename% is any BASIC variable name, including the name of
a record variable or record element. Use WindowCurrent anywhere you need the
number of the current window as an argument for other window procedures (for
example, WindowClose and WindowCurrent).
See Also: WindowSetCurrent
Example
See the DemoWindow procedure in the code example UIDEMO.BAS for a specific
usage example.
WindowDo SUB
Action
Takes control of the program and waits for a button, edit-field, or window
event to occur in an open window.
Syntax
WindowDo currButton%, currEdit%
Remarks
The WindowDo procedure uses the following arguments:
currButton%
-----------
An integer that indicates the number of the current button. The current
button is that button where the text cursor is located at the time of the
call to WindowDo.
currEdit%
---------
An integer that indicates the number of the current edit field. The current
edit field is the edit field where the text cursor is located at the time of
the call to WindowDo. If it is 0, it is assumed that the text cursor is not
currently in an edit field. If it is nonzero, WindowDo lets the user edit
the current edit field.
Only buttons and edit fields in the current window are active. If no buttons
or edit fields are used in the window, use 0 for both arguments. Once an
event takes place, use Dialog(0)
to determine which event occurred.
Program execution continues after an event occurs.
See Also: Dialog
Example
See the DemoDialog, DemoDialogEZ, DemoResize, DemoScrollBar, and DemoWindow
procedures in the code example UIDEMO.BAS for specific usage examples.
WindowInit SUB
Action
Initializes the global window, button, and edit-field arrays.
Syntax
WindowInit
Remarks
The WindowInit procedure is used at or near the beginning of any program
that uses the window procedures provided by the User Interface toolbox. You
must call WindowInit before any other window procedures are used. You can
execute WindowInit again anytime you need to reset the windowing
environment.
See Also: ButtonOpen, EditFieldOpen, WindowOpen
WindowLine SUB
Action
Draws a horizontal line across the current window at the row specified.
Syntax
WindowLine row%
Remarks
The argument row% is an integer that describes a row relative to the top of
the current window. The WindowLine procedure is used in dialog boxes to
separate parts. WindowLine is used by the Alert procedure to draw a
horizontal line above the buttons.
See Also: WindowPrint
Example
See the DemoDialogEZ procedure in the code example UIDEMO.BAS for a specific
implementation.
WindowLocate SUB
Action
Sets the row and column of the window text cursor in a window.
Syntax
WindowLocate row%, col%
Remarks
The coordinates row% and col% are integers that describe a print position
relative to the upper-left corner of the current window. The WindowLocate
procedure is used, once a window has been opened, to position the window
text cursor to the starting point of a line of text. This is the position
where the next character will be placed when a WindowPrint operation occurs.
See Also: WindowPrint
Example
See the DemoDialog procedure in the code example UIDEMO.BAS for a specific
implementation.
WindowNext FUNCTION
Action
Returns an integer that is the handle number of the next available window.
Syntax
variablename% = WindowNext
Remarks
The WindowNext procedure is used in situations where a window is to be
opened, but the opening routine has no information about other windows that
may already be open. The argument variablename% is any BASIC variable name,
including the name of a record variable or record element.
See Also: WindowCurrent, WindowOpen
WindowOpen SUB
Action
Defines and opens a window.
Syntax
WindowOpen handle%, row1%, col1%, row2%, col 2%, textFore%, textBack%,
fore%, back%, highlight%, movewin%, closewin%, sizewin%, modalwin%,
borderchar%, title$
Remarks
The WindowOpen procedure uses the following arguments:
handle%
-------
An integer that indicates the number of the window that is being opened.
This can be any number between 1 and the value declared in the constant
MAXWINDOW, inclusive.
row1%, col1%
------------
An integer pair that specifies absolute screen row and column coordinates.
row2%, col2%
------------
An integer pair that specifies the lower-right-corner coordinates of an
area.
textFore%
---------
An integer that defines text foreground color (0 - 15).
textBack%
---------
An integer that defines text background color (0 - 7).
fore%
-----
An integer that defines window foreground color (0 - 15).
back%
-----
An integer that defines window background color (0 - 7).
highlight%
----------
An integer that defines color (0 - 15) of highlighted buttons.
movewin%
--------
TRUE indicates a movable window; FALSE indicates a stationary window.
closewin%
---------
TRUE indicates a window that can be closed; FALSE indicates a window that
can't be closed.
sizewin%
--------
TRUE indicates a resizable window; FALSE indicates a window that can't be
resized.
modalwin%
---------
TRUE indicates a modal window; FALSE indicates a nonmodal window. When a
window is modal, any attempt to select outside the window is unsuccessful
and results in a beep.
borderchar%
-----------
0 indicates no border; 1 indicates a single-line border; 2 indicates a
double-line border.
title$
------
A string that is the title of the window. If title$ is a null string (""),
no title is displayed.
The WindowOpen procedure is used to open windows anywhere on the screen.
Twenty-four basic window types are predefined in WINDOW.BAS; however, the
fact that any of the basic types can be created as either a standard or
modal window increases the available number to 48.
See Also: WindowBorder, WindowClose, WindowNext
Example
See the DemoWindow procedure in the code example UIDEMO.BAS for a specific
implementation.
WindowPrint SUB
Action
Prints text, in the style specified, in the current window at the position
established by WindowLocate.
Syntax
WindowPrint style%, text$
Remarks
The WindowPrint procedure uses the following arguments:
style%
------
An integer that indicates the style of the text to be displayed.
Possible values for style% and their significance are described as follows:
Value Significance
1 Truncated printing. If text is longer than the window, it is
truncated. The text cursor is moved to the first character of the next line.
The window is scrolled, if necessary.
2 Character wrapping. If text is longer than the window, the text
continues on the next line, scrolling if necessary. The text cursor is moved
to the first character on the next line, scrolling if necessary.
3 Text wrapping. Same as style 2 except that text is wrapped only at
spaces.
4 Truncated centering. Text is centered on the current line. If text
is too long, it is truncated.
-1 Same as style 1 except, after printing, text cursor is positioned
immediately following the last character printed.
-2 Same as style 2 except, after printing, text cursor is positioned
immediately following the last character printed.
-3 Same as style 3 except, after printing, text cursor is positioned
immediately following the last character printed.
text$
-----
A string that contains the text to be displayed in the window.
Use WindowPrint whenever you want to display text in a window.
See Also: WindowLocate
Example
See the DemoWindow procedure in the code example UIDEMO.BAS for a specific
implementation.
WindowPrintTitle SUB
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
WindowPrintTitle
Remarks
The WindowPrintTitle procedure prints a window's title bar.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: WindowDo
WindowRefresh SUB
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
WindowRefresh handle%
Remarks
The WindowRefresh procedure restores a window to the screen from a global
array. The handle% is an integer that indicates the number of the window
being restored. This can be any number between 1 and the value declared in
the constant MAXWINDOW, inclusive.
To restore part of the screen, use the PutBackground procedure in
GENERAL.BAS.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: WindowDo
WindowRows FUNCTION
Action
Returns an integer that is the number of interior rows in the current
window.
Syntax
variablename% = WindowRows (handle%)
Remarks
The WindowRows procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
handle%
-------
An integer that indicates the number of the window whose row count is
requested. This can be any number between 1 and the value declared in the
constant MAXWINDOW, inclusive.
Use WindowRows when you need to determine the number of interior rows in a
window. Interior rows are those where text can be displayed. The WindowRows
procedure can be used when resizing windows that contain text, to ensure
that you don't print more text than there are lines available to print on.
See Also: WindowCols
Example
See the DemoWindow procedure in the code example UIDEMO.BAS for a specific
implementation.
WindowSave SUB
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
WindowSave handle%
Remarks
The WindowSave procedure saves a window into a global array. If you want to
save part of the screen, use the GetBackground procedure in GENERAL.BAS. The
argument handle% is an integer that indicates the number of the window being
saved. This can be any number between 1 and the value declared in the
constant MAXWINDOW, inclusive.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: WindowDo
WindowScroll SUB
Action
Scrolls text in the current window by the number of lines specified.
Syntax
WindowScroll lines%
Remarks
The WindowScroll procedure is used in the WindowPrint procedure of the User
Interface toolbox. The argument lines% is an integer that defines the number
of lines to scroll. If lines% is greater than 0, the window scrolls up; if
lines% is less than 0, the window scrolls down. If lines% equals 0, the
window is cleared.
See Also: WindowCls, WindowPrint
WindowSetCurrent SUB
Action
Makes the specified window the current window, placing it on top (in front)
of any other windows that may be open.
Syntax
WindowSetCurrent handle%
Remarks
The WindowSetCurrent procedure is used to change to a new window. Only the
current window is displayed with a shadow effect. The argument handle% is an
integer that indicates the number of the window to make current. This can be
any number between 1 and the value declared in the constant MAXWINDOW,
inclusive.
See Also: WindowCurrent
Example
See the DemoWindow procedure in the code example UIDEMO.BAS for a specific
implementation.
WindowShadowRefresh SUB
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
WindowShadowRefresh handle%
Remarks
The WindowShadowRefresh procedure restores the background behind a shadow
from a global array. If you want to restore part of the screen, use the
PutBackground procedure in GENERAL.BAS. The argument handle% is an integer
that indicates the number of the window whose shadow background is being
restored. This can be any number between 1 and the value declared in the
constant MAXWINDOW, inclusive.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: WindowDo
WindowShadowSave SUB
Action
Used internally by the other procedures in WINDOW.BAS. Do not use or alter
this procedure.
Syntax
WindowShadowSave handle%
Remarks
The WindowShadowSave procedure saves the background (the area behind where a
window's shadow is to be displayed) into a global array. If you want to save
part of the screen, use the GetBackground procedure in GENERAL.BAS. The
argument handle% is an integer that indicates the number of the window whose
shadow background is being saved. This can be any number between 1 and the
value declared in the constant MAXWINDOW, inclusive.
Warning
-------
Do not use or alter this procedure unless you are customizing the User
Interface toolbox and you know how the use or alteration of this procedure
will affect the operation of all other procedures in the toolbox.
See Also: WindowDo
MOUSE.BAS
The MOUSE.BAS source-code file supports the Microsoft Mouse and other
pointing devices that have a 100 percent Microsoft-Mouse-compatible driver.
Although the procedures can be used by themselves, they were designed as an
integral part of the User Interface toolbox.
If you use the procedures in MOUSE.BAS, you must include GENERAL.BI and
MOUSE.BI in your program so you will have the proper declarations and
definitions. The header file MOUSE.BI includes procedure declarations for
the MOUSE.BAS file.
A description of the procedures that comprise MOUSE.BAS follows.
MouseBorder SUB
Action
Establishes the limits of mouse movement on the screen.
Syntax
MouseBorder row1%, col1%, row2%, col 2%
Remarks
The MouseBorder procedure uses the following arguments:
row1%, col1%
------------
An integer pair that specifies absolute screen row and column coordinates.
row2%, col 2%
-------------
An integer pair that specifies the lower-right corner coordinates of an
area.
MouseBorder is used in WINDOW.BAS to establish the limits of mouse movement
when windows are moved or resized. Mouse movement is permitted only within
the boundary described by the parameters of MouseBorder.
See Also: WindowDo, MouseInit
MouseDriver SUB
Action
Calls Interrupt 51 (33H) and passes the parameters to the proper registers.
Syntax
MouseDriver M0%, M1%, M2%, M3%
Remarks
The MouseDriver procedure uses the following arguments:
M0% An integer that is placed into the AX register.
M1% An integer that is placed into the BX register.
M2% An integer that is placed into the CX register.
M3% An integer that is placed into the DX register.
Interrupt 51 provides DOS mouse services. Refer to the Microsoft Mouse
Programmer's Guide for detailed information about mouse servicing routines.
MouseDriver is used in MOUSE.BAS (all procedures) where access to operating
system mouse routines is required.
See Also: MouseBorder, MouseHide, MouseInit, MousePoll,
MouseShow
MouseHide SUB
Action
Decrements a cursor flag in the mouse driver, causing the mouse cursor to be
hidden.
Syntax
MouseHide
Remarks
Use this procedure before each time you print something on the screen, to
prevent the mouse cursor from being overwritten. Once you've written to the
screen, be sure to use a corre-sponding MouseShow procedure to turn the
mouse cursor back on; otherwise you will be unable to see your mouse cursor.
When the internal cursor flag is less than 0, the mouse cursor is hidden.;
when it is 0, the mouse cursor is displayed. It is never greater than 0.
MouseHide is used throughout the User Interface toolbox anytime something is
displayed on the screen.
Note
----
The cursor flag is part of the mouse driver, not part of these mouse
procedures or the User Interface toolbox.
See Also: MouseDriver, MouseShow
MouseInit SUB
Action
Initializes the mouse-driver-servicing routines.
Syntax
MouseInit
Remarks
MouseInit is used at or near the beginning of any program that uses the
procedures provided by the mouse procedures of the User Interface toolbox.
MouseInit must be called before any other mouse procedures are used.
The MouseInit procedure sets the cursor flag in the mouse driver to -1. When
the internal cursor flag is less than 0, the mouse cursor is hidden; when it
is 0, the mouse cursor is displayed. It is never greater than 0.
Note
----
The cursor flag is part of the mouse driver, not part of these mouse
procedures or the User Interface toolbox.
See Also: MenuInit, MouseDriver
MousePoll SUB
Action
Polls the mouse driver.
Syntax
MousePoll row%, col%, lbutton%, rbutton%
Remarks
The MousePoll procedure uses the following arguments:
row%
----
A variable that contains the row coordinate for the mouse cursor.
col%
----
A variable that contains the column coordinate for the mouse cursor.
lbutton%
--------
A variable that contains the status of the left mouse button.
rbutton%
--------
A variable that contains the status of the right mouse button.
MousePoll places the row and column position of the mouse cursor into the
row% and col% variables. The MousePoll procedure also determines the status
of the left and right mouse buttons, and places the status (TRUE if pressed
or FALSE if not) into the lbutton% and rbutton% variables, as appropriate.
MousePoll is used throughout the User Interface toolbox whenever the
location of the mouse cursor or the status of the mouse buttons is required.
See Also: MouseDriver
MouseShow SUB
Action
Increments a cursor flag in the mouse driver that causes the mouse cursor to
be displayed.
Syntax
MouseShow
Remarks
The MouseShow procedure is used each time you print something to the screen;
it rewrites the mouse cursor to the screen. You should use a MouseShow
procedure for each MouseHide you use in your program.
When the internal cursor flag is less than 0, the mouse cursor is hidden.
When it is 0, the mouse cursor is displayed. It is never greater than 0. If
the internal cursor flag is already 0, this procedure has no effect.
MouseShow is used throughout the User Interface toolbox whenever anything is
displayed on the screen.
Note
----
The cursor flag is part of the mouse driver, not part of these mouse
procedures or the User Interface toolbox.
See Also: MouseDriver, MouseHide
GENERAL.BAS
The GENERAL.BAS source-code file contains a number of general purpose
character-based routines that are used in both the MENU.BAS and WINDOW.BAS
files. While these files can be used by themselves, they are intended to
support the other procedures in the User Interface toolbox. If you use any
of the procedures in GENERAL.BAS, you must include the header file,
GENERAL.BI.
A description of the procedures that comprise GENERAL.BAS follows
AltToASCII$ FUNCTION
Action
Decodes the extended key codes associated with the Alt key, and returns only
the individual ASCII character.
Syntax
variablename$ = AltToASCII$ (kbd$)
Remarks
The AltToASCII$ procedure uses the following arguments:
variablename$
-------------
Any BASIC variable name, including the name of a record variable or record
element.
kbd$
----
A string that contains a character entered at the keyboard.
AltToASCII$ is used in the procedures in MENU.BAS to identify access keys
that have been pressed for menu-item selection (Alt + 0 - 9, A - Z, - and
=).
For instance, pressing the Alt key with the "A" key places two scan-code
values into the keyboard buffer, CHR$(0)+CHR$(30). AltToASCII$ strips off
CHR$(0) and returns "A," which is the letter represented by scan code 30.
The keyboard can be polled with either the BASIC INKEY$ procedure or the
MenuInkey$ procedure (preferred) included in the MENU.BAS file in the User
Interface toolbox.
See Also: MenuDo
AttrBox SUB
Action
Changes the color of the characters within a box.
Syntax
AttrBox row1%, col1%, row2%, col 2%, attr%
Remarks
The AttrBox procedure uses the following arguments:
row1%, col1%
------------
An integer pair that specifies absolute screen row and column coordinates.
row2%, col2%
------------
An integer pair that specifies the lower-right corner coordinates of an
area.
attr%
-----
An integer that defines the color and intensity attributes for your
particular display adapter. The number is derived by adding the product of
16 times the value of the background color (0 - 7) to the value of the
foreground color (0 - 15). See the entries for the SCREEN and PALETTE
statement for more information.
AttrBox changes the color attribute of characters within a box, described by
column and row coordinates, to the attribute contained in the argument
attr%. The characters within the described area are unaffected, except for
changes in color.
AttrBox is used in MENU.BAS to provide shadows for the menus, and in
WINDOW.BAS to draw the shadow on newly displayed windows.
See Also: MenuDo, WindowShadowSave
Box SUB
Action
Draws a box around a defined area, using the foreground and background
colors specified.
Syntax
Box row1%, col1%, row2%, col 2%, fore%, back%, border$, fillflag%
Remarks
The Box procedure uses the following arguments:
row1%, col1%
------------
An integer pair that specifies absolute screen row and column coordinates.
row2%, col 2%
-------------
An integer pair that specifies the lower-right corner coordinates of an
area.
fore% An integer that defines the foreground color (0 - 7)
back%
-----
An integer that defines the background color (0 - 15).
border$
-------
Nine-character string that defines the characters that are used to create
the box. Each character position is significant because it defines a
particular part of the box. Characters are defined as follows:
Position Character described
1 Upper-left-corner character
2 Top-line character
3 Upper-right-corner character
4 Left-side line character
5 Fill character for middle area
6 Right-side line character
7 Lower-left-corner character
8 Bottom-line character
9 Lower-right-corner character
fillflag%
---------
TRUE (-1) if the interior of the box is to be cleared;
FALSE (0) if it is not.
The Box procedure is used in WINDOW.BAS to draw boxes on the screen.
The individual character entries in the argument border$ define which
characters are used to draw the box. You can use any characters in either
the standard ASCII or extended character set. Normally, box characters in
the range CHR$(179) through CHR$(218) are used. (The figure on the following
page shows the box characters and their corresponding ASCII codes.)
Figure 3.1 Box border characters and their corresponding ASCII codes
Box characters can be entered by pressing the Alt key and the appropriate
numbers on the keypad. The function of each of the nine character positions
in the argument border$ is shown in the table above.
If fewer than nine characters are included in border$, a default single-line
box is drawn; if more than nine characters are included, only the first nine
are used.
See Also: WindowBox, WindowDo, WindowOpen
GetBackground SUB
Action
Saves an area of the screen into a named buffer.
Syntax
GetBackground row1%, col1%, row2%, col 2%, buffer$
Remarks
The GetBackground procedure uses the following arguments:
row1%, col1%
------------
An integer pair that specifies absolute screen row and column coordinates.
row2%, col 2%
-------------
An integer pair that specify the lower-right corner coordinates of an area.
buffer$
-------
Name of the buffer variable where the defined area is to be stored.
GetBackground is used in MENU.BAS to store in a buffer the area (for
example, the background where a window is to be displayed) that a menu is to
occupy, before the menu is displayed. GetBackground is also used in
WINDOW.BAS to store in a buffer the area that a window is to occupy, before
the window is displayed. When used with MENU.BAS or WINDOW.BAS, a buffer is
created for each menu or window, up to the maximum allowable (normally 10 of
each).
There must be a buffer for each different area that is to be stored. The
GetBackground procedure creates enough space in each buffer to hold the
defined screen area. It then uses an assembly-language routine (GetCopyBox)
to perform the actual screen-save operation.
See Also: MenuDo, PutBackground, WindowDo, WindowSave,
WindowShadowSave
GetShiftState FUNCTION
Action
Returns the status of one of eight shift states.
Syntax
variablename% = GetShiftState (bit%)
Remarks
The GetShiftState procedure uses the following arguments:
variablename%
-------------
Any BASIC variable name, including the name of a record variable or record
element.
bit%
----
An integer between 0 and 7, inclusive, that defines which key status is
requested.
The returned value is TRUE if the state of the key is pressed (Alt,
Ctrl, Shift) or On if the key operates as a toggle (Scroll Lock, NumLock,
Caps Lock, Ins). If the key is not pressed or On, FALSE (0) is returned. The
values for bit% and the keys represented are described as follows:
Value Key status (return value)
0 Right Shift pressed (TRUE)/not pressed (FALSE)
1 Left Shift pressed (TRUE)/not pressed (FALSE)
2 Ctrl pressed (TRUE)/not pressed (FALSE)
3 Alt pressed (TRUE)/not pressed (FALSE)
4 Scroll Lock pressed (TRUE)/not pressed (FALSE)
5 NumLock toggle on (TRUE)/off (FALSE)
6 Caps Lock toggle on (TRUE)/off (FALSE)
7 Ins toggle on (TRUE)/off (FALSE)
The GetShiftState procedure is used in MENU.BAS to determine whether the Alt
key has been pressed, so that user input can be properly processed to select
the desired menu item. GetShiftState is also used in WINDOW.BAS when editing
edit fields.
See Also: MenuDo, MenuEvent, WindowDo
PutBackground SUB
Action
Restores the background from the named buffer to the row and column
coordinates specified.
Syntax
PutBackground row%, col%, buffer$
Remarks
The PutBackground procedure uses the following arguments:
row%, col%
----------
An integer pair that specifies absolute screen row and column coordinates.
buffer$
-------
Name of the buffer variable where the defined area was stored by the
GetBackground procedure.
PutBackground is used in MENU.BAS to restore an area on the screen from a
buffer, after closing a menu. PutBackground is also used in WINDOW.BAS to
restore an area on the screen from a buffer, after closing a window. The
complementary action, that of storing the background in a buffer before a
menu or window is displayed, is performed by the GetBackground procedure.
Normally, a background is restored to the coordinates from which it was
previously saved before a menu or window was displayed. The PutBackground
procedure checks the screen boundaries to ensure that the area can be
properly restored to the screen. It then actually uses an assembly-language
routine (PutCopyBox) to restore the screen background. When used with
MENU.BAS and WINDOW.BAS, buffers created for each menu or window contain the
background for the area occupied by the menu or window. When the menu or
window is no longer displayed, the background for that area is restored to
the screen.
See Also: GetBackground, MenuDo, WindowDo, WindowRefresh,
WindowShadowRefresh
Scroll SUB
Action
Scrolls the defined area.
Syntax
Scroll row1%, col1%, row2%, col 2%, lines%, attr%
Remarks
Scroll is used in WINDOW.BAS to scroll an area within a defined window. The
Scroll procedure uses the following arguments:
row1%, col1%
------------
An integer pair that specifies absolute screen row and column coordinates.
row2%, col2%
------------
An integer pair that specifies the lower-right corner coordinates of an
area.
lines%
------
An integer that defines the scrolling behavior that occurs within the
defined area. If lines% is less than 0, the area scrolls down by that number
of lines. If lines% is greater than 0, the area scrolls up by that number of
lines. If lines% is 0, the defined area is cleared.
attr%
-----
An integer in the range 0 - 7 that defines the color to fill any newly
created blank lines.
See Also: WindowScroll
Compatibility with Microsoft QuickBASIC for the Macintosh
Every effort has been made to retain a high degree of compatibility between
the functionality in the User Interface toolbox and that which exists in
QuickBASIC for the Apple Macintosh. Many programs from the Macintosh
platform can be readily converted for use with the PC. However, there are
some limitations that you should be aware of.
Programs that use graphics windows on the Macintosh cannot be converted
because this user interface package is text (character) based.
Programs that use event trapping on the Macintosh must be converted to
polling before conversion can be effected.
Each Macintosh QuickBASIC window command has a functional counterpart in the
User Interface toolbox. Often a Macintosh QuickBASIC command has more than
one function. Where this is true, there may be more than one corresponding
procedure for QuickBASIC on the PC. The following table can be used as a
general guideline for converting programs from one platform to the other:
Macintosh QuickBASIC PC BASIC
ALERT Alert
BUTTON function ButtonInquire
BUTTON statement ButtonOpen, ButtonSetState, ButtonToggle
BUTTON CLOSE ButtonClose
CLS WindowCls
COMMAND ShortCutKeyDelete, ShortCutKeyEvent, ShortCutKeySet
DIALOG Dialog, WindowDo
EDIT$ EditFieldInquire
EDIT FIELD EditFieldOpen
EDIT FIELD CLOSE, EditFieldClose
LOCATE WindowLocate
PRINT WindowPrint
MENU function MenuCheck, MenuEvent, MenuInkey$
MENU statement MenuColor, MenuItemToggle, MenuPreProcess, MenuSet,
MenuSetState, MenuShow
MENU RESET MenuInit
MENU ON MenuOn
MENU OFF MenuOff
MOUSE MouseHide, MouseInit, MousePoll, MouseShow
SCROLL WindowScroll
WINDOW function WindowCols, WindowCurrent, WindowRows
WINDOW statement WindowColor, WindowInit, WindowOpen, WindowSetCurrent
WINDOW CLOSE WindowClose
Miscellaneous WindowBox, WindowLine
A number of features are similar, but not exactly the same in both
environments. Some of the differences are outlined below:
* Buttons cannot be disabled on the PC, only opened or closed.
* On the Macintosh, the active window may differ from the current output
window. On the PC, the active window and the current window are the same.
* On the PC, the Dialog(0) procedure returns 2 whenever an edit field is
selected, not just when there is more than one edit field, as occurs on the
Macintosh.
* On the PC, edit fields cannot be centered or right justified. They are
always left justified.
* Macintosh MOUSE functions 3 through 6 are not implemented on the PC.
* Macintosh WINDOW type 7 is not implemented in any manner on the PC.
Window types are somewhat different on the PC than they are on the
Macintosh. Each of the windows on the Macintosh - numbered 1 through 7 - has
a slightly different functionality. The PC window types allow you to specify
any combination of available features with WindowOpen, so that you have full
control over the features of your PC windows. Custom window configurations,
beyond the 24 basic types provided, can be created by modifying the
WindowBorder procedure.
A number of new or extended features have been implemented to enhance the
usability of this package. These features are described as follows:
* The Dialog procedure has been greatly extended to cover the full range
of menu and keyboard events.
* All menus are keyboard accessible by two means. Access keys (standard)
are provided and shortcut keys (optional) can be user defined.
* Print formatting (word wrap, centering, and so on) can be specified.
* Window contents are automatically saved when windows overlap, so
windows do not need to be refreshed. An exception is that a window must be
refreshed when a window is resized. The programmer must ensure that
refreshing occurs when a window is resized.
* Buttons and menus can be toggled.
* Scroll bars are implemented as button types 6 (vertical) and 7
(horizontal).
* List boxes are implemented.
* Field buttons (invisible buttons that occupy an area of the screen) are
implemented as button type 4.
One very important difference between the PC and the Macintosh lies in the
use of the keyboard. On the Macintosh, the assumption is made that every
computer has a mouse pointing device. This assumption cannot be made for the
PC. During the evolution of text window environments on the PC, a standard
has emerged that is adhered to by the procedures in this toolbox.
This creates a significant problem when converting programs from the
Macintosh to the PC. Keys with well defined purposes, like the Spacebar and
the Tab key, actually get trapped by the routines that process keyboard
input. This means that Macintosh applications that are particularly keyboard
intensive will not work well in the PC Windows environment. A word
processor, for example, would be abysmally slow and therefore would not be
practical within a window. There are three choices available for the
programmer who wants to convert such an application:
* Do all the keyboard-intensive operations outside of the WindowDo
procedure. The vast majority of PC window-based applications do this anyway.
Then you can use windows for dialog and list boxes. This is the preferred
method.
* Learn how WindowDo works and customize it, or write your own WindowDo
procedure to suit your needs.
* Learn how edit fields and buttons operate, and create your own object
type. The edit field can be extended to support multiple lines.
Generally, these routines are quite flexible and can certainly add
functionality to your programs, as well as conversion capability from one
platform to the other.