home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-06-26 | 199.2 KB | 5,480 lines |
-
-
-
-
-
-
-
- GLIB version 1.90
- Released: June, 1991
- Copyright InfoSoft, 1986-1990, 1991
-
- Note: This release is intended for QB 4.5 ONLY !
- For BASIC PDS 7.x support, get GLib 2.01x
-
-
-
- The files that should be included on this disk or .ZIP are:
-
- GLIB19.NEW - Overview of new features in GLib 1.9
- GLIB19.DOC - Complete Library documentation.
- MACRO19.DOC - Documentation for care and feeding of the
- Macro Field Editor, QCalc, Clock, DialogBox
- and Status Line 'macro' Routines.
- GLIBXTD.BI - BASIC include file of declarations for ALL
- GLib 1.9 routines (for reference use).
- GLIB19.QLB - The routines for use with QB4 environment.
- GLIBDEMO.BAS - A QB demo of some of the routines.
- QCALCDEM.BAS - Brief demo of the QCALC routine.
- MFEDDEMO.BAS - Demo of MFed, text input handler.
- EMP.DAT - Sample data file for MFEDDEMO.BAS
- MAILERG - Quick Mailer for registering.
- LIST.ME - Any last minute thoughts or notes
-
-
-
- Upon registering, users will also receive a Quick Reference guide
- to using the routines (GLIB19.QRF).
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 1
-
-
-
-
-
-
- License, Terms and Use:
-
- Under no circumstances may these routines be distributed
- individually or without the accompanying documentation, which is an
- integral part of the package, nor may the documentation be altered in
- anyway. This includes, but is not limited to distributing GLIB19.QLB
- for use in executing applications compiled to BRUN format.
-
- Under no circumstances may the routines in the GLIB package,
- source, object files, libraries or documentation be distributed by or
- otherwise become a part of, or affiliated with any group or
- organization involved in the distribution of what is generally been
- come to be known as SHAREWARE for disk or distribution fees, or for
- fees of any sort without my express WRITTEN consent. This includes
- supplying the routines, library and or documentation for so-called
- disk fees.
-
- Finally, we make no claims that the routines herein will fit
- your needs, simply that in all testing and prior use that they worked
- for us and that you may find them interesting and helpful in your
- programming. Any liability for the use, misuse or inability to use
- the GLIB routines or libraries, is solely the users.
-
-
-
-
- 1. GLIB Compatibility
- Unless otherwise noted, all routines used in GLIB are written
- in assembler with MASM 5.1. The few BASIC based routines that there
- are, were written under QB 4.5 or the MS BASIC PDS Compiler 7.x.
-
- DO NOT attempt to combine older QB3 routines with QB4x
- routines into a QB4 compiled program or library. ASM based routines
- require significant conversion for use under QB4. Linking QB3 and QB4
- BASIC based routines will require that both runtime modules be used,
- BCOM/BRUN30 and BCOM/BRUN40 - which WILL yield certain disaster.
-
-
-
- 2. Support
- As long as it exists, I will support and entertain questions
- regarding QB and/or GLIB via the QuickBASIC conference on The
- Information Booth, (316) 684 8744, 1200 - 2400 bps, 24 hrs.
- If you have a problem with GLIB, you _MUST_ be prepared to
- supply supporting source code demonstrating the problem you are
- having. I am more than a little interested in any GLib or QB bugs
- that you might find, but I do not have the time to track down problems
- based on vague descriptions of problems when I cannot see if you are
- using the sub program right. PLEASE do not waste my time with gen-
- eral, vague inquiries without supporting source examples - I do not
- need and cannot use .EXE files.
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 2
-
-
-
-
-
-
-
- 3. Terms of usage
- You are granted free and unlimited personal use of any and all
- routines in the environment library (".QLB") for GLIB 1.9 that you may
- find of value. Furthermore, you are free to pass along the BBS
- distribution files (listed at the start of this document) as long as
- they are passed along as a whole according to the guidelines listed
- above.
- No one is granted any permission to share or pass along the
- BCOM library (".LIB") or any object files. As distributed, the GLIB
- documentation, demo or tutor and the environment library (".QLB")
- provide you with everything you need to call and execute GLIB routines
- from within the editor/environment. Furthermore, as described above
- you are given unlimited rights for such use. This provides an ex-
- tremely generous forum for purposes of sampling, testing and evalua-
- tion and allows unlimited latitude in terms of personal use or as a
- tutorial regarding some of the more advanced features in today's
- QuickBASIC. Note that this personal use does not include any rights
- to distribute the .QLB as a runtime module. That is, if your sole
- intent with GLib is personal use or experimental use from within the
- environment, no monies are requested, expected or solicited.
-
- However, you might find some of the routines of value and want
- to incorporate them into a standalone .EXE applications. In this
- case, the library (.LIB) of routines and permission to use them in
- such applications may be purchased as described in item (4) below.
-
-
- 4. License terms
- If you choose to purchase a LIBRARY/OBJECT module license,
- implicit in that, is the specific rights to use the routines in GLIB
- in your standalone runtime program either by direct linking or the use
- of the BUILDRTM program in BASIC PDS. This further includes the
- supplying the QuickLibrary (QLB) as a runtime module if that is your
- desire, however this method does not either implicitly or explicitly
- bequeath another or secondary LIBRARY/OBJECT module license to any end
- user(s) or people receiving that as a run time module. The routines
- may only be passed along in linked form, as a QLB or EXE file, never
- as an OBJECT module or in LIBRARY form.
-
- A LIBRARY/OBJECT module license is grated only to the person or
- company providing payment or named on the mailer. No grandfather,
- parent or child usage rights are implied or granted. That is, a
- LIBRARY license purchased by an individual grant the usage of the
- library by that individual, not their employer or anyone outside the
- immediate family. Conversely, a license purchased by a company,
- corporation, business or government organization does not imply or
- grant any person employed, allied or associated with that organization
- personal usage rights without purchasing a LIBRARY/OBJECT license.
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 3
-
-
-
-
-
-
-
- 5. Purchasing GLIB
-
- To get the latest version of GLIB as well as the standalone
- library (.LIB):
-
-
- a. QB Version Support
- We will no longer compile current code for all previous
- versions of QB. The chart below defines those GLib Libraries avail-
- able for the various QB version over the last few years.
-
- QB 4.0 QB 4.00(a / b) QB 4.5 BASIC PDS 7.x
- GLib 2.0?/x X
- GLib 1.9 X
- **GLib 1.7 X X
-
- ** Version 1.7 is a past release, but since it is the last to
- support QB 4.0, QB 4.0(a), QB 4.00(b) and BASCOM 6.00, we will
- continue to support it (and it alone) for those still using
- those QB versions.
-
-
- b. First Time buyers:
- Fill out the enclosed mailer, with $40 in checks or money
- orders (these must be payable in US Funds) and mail it to the address
- on the mailer. You'll receive, by return mail a diskette containing
- complete documentation, object files, .LIB and .QLB for release 1.9.
-
-
-
- c. Upgrading a previous GLib version:
- Upgrades from GLib 1.7 with your serial number are $15.00
- Upgrades from GLib 1.7 without serial number,
- as well as GLib version 1.6/1.65 are $20.00
- Upgrades from GLib 1.5 and before are $30.00
-
- Fill out the mailer, indicating an upgrade and the version
- originally purchased and send it back with US Funds, and we'll mail
- out an upgrade diskette.
-
-
-
- d. In ALL cases, you MUST use the mailer so that we can identify
- diskette type, QB version etc. Please allow 4-5 weeks for delivery.
-
-
- Mailing Address:
- InfoSoft
- GLIB 1.9
- PO Box 782057
- Wichita, Ks
- 67278-2057
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 4
-
-
-
-
-
-
-
- GLIB 1.9 Functions and Sub Programs
- -----------------------------------
-
- NOTE WELL: All but a very, very few GLib functions are in ass-
- embler. As such, the data type you pass is VERY important. Unless
- otherwise specified, all numbers are INTEGERS, so assume a trailing
- '%' unless otherwise noted. This pertains to FUNCTIONS too: Ansi-
- Loaded is AnsiLoaded% unless DEFINT A-Z is in effect. Likewise,
- string lengths can be critical and care should be taken to note and
- pass the required length for correct results.
-
-
-
- Name: AnsiLoaded Type: FUNCTION
- Syntax: RCode = AnsiLoaded
-
- This simply returns an integer indicating is ANSI.SYS (or
- compatible) is loaded as a device driver. If loaded, it returns non
- Zero and if not, it returns zero. This can helpful in determining
- whether to use DPRINT (qv) or not.
-
-
-
- Name: ArgCnt Type: FUNCTION
- Syntax: qargs = ArgCnt
- ArgCnt may also be invoked with the 'C' like name of 'argc'.
-
- Returns the number of arguments in the command tail delimited by a
- space. That is, with 'FOOBAR.EXE /qwerty /1 /2 /3 /4', ArgCnt would
- return 5 as the number of command tail arguments. ArgCnt can also be
- called by the 'C'-like name of argc. See also ArgVar and GetCmdTail.
- ArgVar and ArgCnt replace the interim routine CmdLine. Example:
- PRINT "Number of command line arguments is: "; ArgCnt
-
-
-
- Name: ArgVar Type: FUNCTION
- Syntax: var$ = ArgVar$(arg)
- ArgVar may also be invoked with the 'C' like name of 'argv'.
-
- ArgVar is the complementary routine to ArgCnt(qv) by returning a
- specified argument from the command tail in the programs PSP. ArgVar
- returns a string variable representing the unparsed, specified argu-
- ment from the command tail. To fetch the entire command tail see
- GetCmdTail. As with ArgCnt and GetCmdTail, ArgVar deals with the
- ACTUAL command tail found in the program's PSP, so accommodations
- should be made for when your program running as a QB file versus as a
- EXE (see QBLoaded). Example - Print all command tail elements:
- FOR x = 1 to argc
- PRINT argv$(x) ' prints them one-by-one
- NEXT x
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 5
-
-
-
-
-
-
- Name: AttrMake Type: FUNCTION
- Syntax: attr = AttrMake(Fg, Bg)
-
- Converts 2 integers representing the fore and background colors
- into a single integer representing the attribute. Example:
- Attr = AttrMake(14, 4) ' returns 78
-
-
-
- Name: AttrRev Type: FUNCTION
- Syntax: NewAttr = AttrRev(Attr)
-
- Reverses a passed attribute byte from fg/bg to bg/fg. When
- highlighting a portion of the screen, this can be faster than separate
- steps:
- CALL AttrSplit(attr, fg, bg) \
- SWAP fg, bg > NewAttr = AttrRev(attr)
- NewAttr = AttrMake(fg, bg) /
-
-
- Name: AttrSplit Type: SUB
- Syntax: CALL AttrSplit(Attr, Fg, Bg)
-
- UnConverts a single integer representing the attribute into 2
- integers representing the fore and background colors. This assumes a
- legitimate attribute value. Example:
- CALL AttrSplit(78, fg, bg) ' fg = 14, bg=4
-
-
-
- Name: BCD2Int / Int2BCD Type: FUNCTION
- Syntax: IntVal = BCD2Int(BCDVal)
- BCDVal = Int2BCD(IntVal)
-
- Many times when dealing with DOS directly, you need Binary Coded
- Decimal values (such as when tinkering with DOS file dates and/or
- times). These 2 routines allows you to quickly encode or decode BCD
- values.
-
-
- Name: BitChkInt/BitClrInt/BitSetInt Type: FUNCTION
- Syntax: result = BitChkInt(IValue, bit)
- result = BitClrInt(IValue, bit)
- result = BitSetInt(IValue, bit)
-
- Allows you to CHECK, CLEAR or SET a specific bit in an integer
- value. Such integer bit coding allows you to store several values or
- flags in a single integer. Since an integer is 16 bits, up to 16
- different flags or other 0/1 values could be stored on disk in the
- space of 2 bytes. See also Bit---Lng. Note that BitClrLng and
- BitSetLng both return new integers representing the new value with the
- desired bits cleared or set.
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 6
-
-
-
-
-
-
- Name: BitChkLng/BitClrLng/BitSetLng Type: FUNCTION
- Syntax: result& = BitChkLng(LValue&, bit)
- result& = BitClrLng&(LValue&, bit)
- result& = BitSetLng&(LValue&, bit)
-
- Allows you to CHECK, CLEAR or SET a specific bit in an long
- value.Long integer bit coding allows you to store up various values or
- flags in a long integer. Since a long integer is 32 bits, up to 32
- different flags or other 0/1 values could be stored on disk in the
- space of 4 bytes. See also Bit---Int. Note that BitClrLng and
- BitSetLng both return new long integers representing the new value
- with the desired bits cleared or set.
-
-
-
- Name: Boxes Type: SUB
- Syntax: CALL Boxes(TRow, LCol, BRow, LCol, frame, attr)
-
- BOXES is similar to the windows sub in that it puts frame like
- items on the screen. BOXES differs from WINDOWS in that a wider
- selection of frame styles are offered, fewer parameters are passed and
- without the label centering code, sound effects and the like, it is
- slightly faster. The first four parameters mark the perimeter of the
- box to draw and 'attr' indicates the color attribute to use on the
- frame and interior. The frame parameter may range from 0 to 9 to
- indicate the style of frame to use:
- 0 - Spaces used as border
- 1 - Double / Double ( )
- 2 - Double Horz / Single Vert ( )
- 3 - Single / Single ( )
- 4 - Single Horz / Double Vert ( )
- 5 - Medium Thick boxes (ASCII 220-223)
- 6 - thick boxes (ASCII 219, 219, 221, 222
- 7 - ASCII 176 used
- 8 - ASCII 177 used
- 9 - ASCII 178 used
-
-
- Name: BoxesFrame Type: SUB
- Syntax: CALL BoxesFrame(TRow, LCol, BRow, LCol, frame, attr)
-
- BoxesFrame is almost identical to Boxes except that the interior
- is hollow. This allows you to pop a box onto the screen framing
- existing text without disturbing that text.
-
-
-
- Name: BShadow Type: SUB
- Syntax: CALL BShadow( 0 | 1 )
-
- This is used to indicate to the Library that all subsequent calls
- to Boxes should automatically include a 3-D shadow effect. Calling it
- with a non zero (1) parameter turns on shading, while zero turns it
- off. Use this to also control the shading effect in FlexMenu (aka
- MenuChoice). Do not confuse this with WShadow which control which
- SIDE the windows shadowing takes place on.
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 7
-
-
-
-
-
-
- Name: BufferCalc Type: FUNCTION
- Syntax: size = BufferCalc(Trow, LCol, Brow, Rcol)
-
- Given a set of coordinates, BufferCalc returns an integer indicat-
- ing the number of bytes indicating the size an array would have to be
- to hold such a section of the screen. This can be very useful when
- used to size an array for use with SaveWdw - RestWdw. Example:
- size = BufferCalc(1, 1, 12, 40)
- REDIM ScrnArry(size)
- CALL SaveWindow(ScrnArry(1), 1, 1, 12, 40)
-
-
-
- Name: Chirp Type: SUB
- Syntax: CALL Chirp(x)
-
- This routine is used to sound the speaker in a fast tone of either
- ascending or descending pitch. The same method is used in WDW to make
- the popping sound. CHIRP is provided to allow you to make a un-
- popping sound when removing a window. There are 2 modes in the CHRP
- routine:
- mode 1 = ascending frequency (up)
- 2 = descending frequency (down)
- Example:
- m=1
- CALL CHIRP(m) ' will sound a "chirp" of ascending frequency
- ' as will:
- CALL CHIRP(1)
-
-
-
- Name: Chk286 Type: FUNCTION
- Syntax: retc = Chk286
-
- Provides a quick check as to whether a 80286 processor is in-
- stalled in the machine. This can help determine the speed of certain
- loops in games or other timing dependant loops. A non zero return
- indicates true, and zero indicates false. This is called internally
- by some GLib routines to check if a feature or function is systemical-
- ly available.
-
-
-
- Name: CLon / CLoff Type: SUB
- Syntax: CALL CLON : CALL CLOFF
-
- Neither of these take an argument or pass a parameter. They
- simply engage (CLON) or disengage (CLOFF) the Caps Lock state.
-
-
- Name: Clock Type: SUB
- Syntax: CALL Clock(Row, Col, Attr, Install)
-
- (CLOCK is documented in MACROxx.DOC). Row and Col are the (Tr,
- Lc) coordinates for the display, attr is the color to use and Install
- is 0, 1 or 2 for Uninstall, Install or install quiet mode.
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 8
-
-
-
-
-
-
- Name: ClrEOL Type: SUB
- Syntax: CALL ClrEOL(row, col, attr%)
-
- Clears the video display from the specified (row, col) using the
- specified attribute to the End Of the Line. See also ClrSOL, ClrSOS
- and ClrEOS.
-
-
- Name: ClrEOS Type: SUB
- Syntax: CALL ClrEOS(row, col, attr%)
-
- Clears the video display from the specified (row, col) using the
- specified attribute to the End Of the Screen. See also ClrSOL, ClrSOS
- and ClrEOL.
-
-
- Name: ClrSOL Type: SUB
- Syntax: CALL ClrSOL(row, col, attr%)
-
- Clears the specified line on the video display from column 1 to
- the specified (row, col) using the specified attribute. See also
- ClrEOS,ClrSOS and ClrEOL.
-
-
- Name: ClrSOS Type: SUB
- Syntax: CALL ClrSOS(row, col, attr%)
-
- Clears the video display from Start of the Screen to the specified
- (row, col) using the specified attribute. See also ClrEOS, ClrSOL and
- ClrEOL.
-
-
- Name: ClrKBD Type: SUB
- Syntax: CALL ClrKBD
-
- Clear the keyboard buffer of any and all waiting keystrokes. This
- is an effective way of eliminating type-ahead in critical portions of
- your program. See also KBStuff.
-
-
-
- Name: CPUInfo Type: FUNCTION
- Syntax: support = CPUInfo(Model, SubModel, BiosRev, CPUType,_
- NDPType)
-
- This is a very comprehensive system identification routine. The
- PC BIOS contains several bytes which can be used to determine the type
- of PC it is and whether it is a newer or later model. If an earlier
- PC system does not support the SubModel and BiosRev bytes, the func-
- tion will return non zero in support to indicate this. Most PC's
- after 1984 will support this.
-
- This routine returns several things:
- 1) Model - This byte identifies the type or class of machine.
-
- 2) SubModel - This identifies similar type systems from one
- another, such as a Model 50 from a Model 60 or a 286 based system.
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 9
-
-
-
-
-
-
- 3) BIOS Rev - The BIOS Revision byte helps further distinguishes
- PC systems - such as the original IBM AT (6 Mhz) from the
- later Model 339 (8 MHz).
-
-
- PC Systems table:
- Model Sub Mod BIOS rev
- 255 -- -- Orig. IBM PC type (all PC's to 10/82)
- 255 -- -- Original IBM XT's thru 8/82
- 255 -- -- Later IBM XT, XT/370 (11/82)
-
- 254 -- -- XT, 3270PC, IBM Portables
- 251 00 01 XT's 1/10/1986
- 251 00 02 640 kb XT - 5/09/1986
-
- 253 -- -- PCjr (6/1/83)
-
- 252 -- -- IBM AT dated 1/10/84
- 252 00 01 286 Systems
- 252 01 00 286 Systems (ca 11/85)
-
- 252 04 00 PS/2 Model 50
- 252 05 00 PS/2 Model 60
- 250* 00 00 PS/2 Model 30
-
- 249 -- -- Convertible
-
- 248 00 00 PS/2 Model 80
-
- Other
- 2d Compaq PC 4.77 (Mhz)
- 9a Compaq Plus (XT type)
-
- * We believe that the Model 25 shares this ID bytes with Model 30,
- but has a different sub model or BIOS rev identifier.
-
-
-
-
- 4) CPU type installed, NDP type:
- CPU returns the significant numbers in the central processor iden-
- tification and NDP returns info on any numerical co-processor:
- Type CPU parameter Type NDP parameter
- ---- ------------- ---- -------------
- 8086 86 None 0
- NEC V30 30 8087 87
- 8088 88 80287 287
- NEC V20 20 80387 387
- 80186 186
- 80188 188
- 80286 286
- 80386 386
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 10
-
-
-
-
-
-
- Name: CRTSwap Type: SUB
- Syntax: CALL CRTSwap(Crt, Mode)
-
- CRTSwap swaps the primary and alternate display, making the
- primary display that indicated in the call. This means future QPRINT
- and Save/RestoreScreen calls will act on the new monitor. BASIC's
- PRINT will continue to output to the initial display because QB, like
- your programs, looks at the equipment list only once at the start of
- the program and will not "notice" that you changed CRT's. QPRINT and
- other video routines like Save/Restore Screen determine the active CRT
- each time they are called and thus will act upon the new primary
- display.
- When calling CRTSwap, you tell it which CRT to activate:
- 0 = MONO, 1 = CGA, 2= EGA/VGA. Additionally, you tell it what
- video mode to put it in (not to be confused with the BASIC SCREEN
- function), by passing the mode. In general, when making a MONO CRT
- the primary display, 7 is the mode you will use, but CRTSwap does no
- checking for this. In setting the new mode, the new primary screen is
- inherently cleared. Example:
- CONST EGA = 3, MONO = 0 ' make MONO active in mode 7
- CALL CRTSwap(MONO, 7) ' PRINT to go to org display,
- ' QPRINT to MDA
- ..
- ..
- CALL CRTSwap(EGA, 3) ' make EGA active in mode 3
- ' PRINT goes to EGA, QPRINT to
- ' EGA
-
-
-
-
- Name: CtrlPrtSc Type: SUB
- Syntax: CALL CtrlPrtSc
-
- The same as entering Ctrl-PrtSc from the keyboard: turns on
- continuous printing. Note that this may have no effect on systems
- with keyboard enhancers installed.
-
-
-
- Name: CvtAlt Type: FUNCTION
- Syntax: retc = CvtAlt(x$)
-
- Returns the ASCII value of the letter used in with an [Alt-?]
- combination. If x$ is [Alt-Q], then retv returns from CvtAlt as 81
- which is ASC("Q"). This is useful in simplifying CASE structures
- which need to act on a wide variety of input possibilities. All such
- [Alt-?] key combinations have a length of 2 and CvtAlt will only
- attempt to translate strings that are 2 character long, or CvtAlt
- will return 0.
-
-
- Name: Date Type: SUB
- Syntax: CALL Date(mo, day, yr, dow)
-
- Return the current system date information. The day, month and
- year can be immediately used in DFRMAT.
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 11
-
-
-
-
-
-
- Name: DayOfYr Type: FUNCTION
- Syntax: DaySoFar = DayOfYr
-
- This simply returns the day of year as an integer. It is
- accurate for dates of 01-01-1980 to 02-28-2100 (The year 2100 is a
- centennial skip leap year - every 400 years we skip a leap year).
- This is a FUNCTION that works off the current system date, returning
- the day count in the FUNCTION name. Example:
- DECLARE FUNCTION DayOfYr%
- .
- .
- TodayCount = DayOfYr
-
-
-
-
- Name: DayOfWeek Type: FUNCTION
- Syntax: DCode = DayOfWeek(month, day, yr)
- DayOfWeek can also be called as ZellerDay.
-
- This uses a modified form of Zeller's Congruence to determine the
- day of week for any valid date. Example:
-
- WeekDay = ZellerDay(5, 17, 1989) ' returns 3 for Wed
-
- PRINT "That was a "; DayName$(WeekDay)
-
-
-
-
-
- Name: Delay/Delay18 Type: SUB
- Syntax: CALL Delay(secs)
- CALL Delay18(ticks)
-
- Delay will pause a given number of seconds to allow the user to
- read a display that you may have sent to the screen. Delay18 allows a
- delay resolution between that of Delay and MilliDelay by pausing in
- increments of 1 clock tick or 1/18.2th of a second. Example:
- sec=5
- CALL Delay(sec) ' or CALL Delay(5)
- ..
- CALL Delay18(9) ' 1/2 second
-
-
-
-
-
- Name: DialogBox Type: SUB
- Syntax: CALL DialogBox(Msg$, Prompt$, Ok$, Ret$) (DialogBox
- is fully documented in MACRO17.DOC).
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 12
-
-
-
-
-
-
- Name: DFrmat Type: SUB (BASIC)
- Syntax: CALL DFrmat(m, d, y, nudate$)
-
- Passed integers for the date, this routine will pass back a
- formatted date string. This is handy in formatting DOS/BASIC's
- sterile date format into something that has a more pleasing on screen
- appearance. The integers represent the day, month and year, and the
- return is a string similar to "August 1, 1987".
-
- DFRMAT has a lower range of 1800 as the year, and any year
- passed that is lower than 1800 has 1900 added to it, making 87 as
- valid an argument as 1987. Syntax:
- CALL dfrmat(8, 1, 87, nudate$)
- PRINT nudate$ ' output is August 1, 1987
-
- Alternative:
- CALL date(m, d, y, w)
- CALL dfrmat(m, d, y, nudate$)
-
-
-
-
- Name: DirA Type: FUNCTION
- Syntax: errc = DirA(mask$, BYVAL VARPTR(fil$(1)))
-
- DirA replicates the DOS DIR command in an elegant and efficient
- method - no shelling, no reading the screen after a FILES statement
- and no loops to execute numerous calls to get files and their names.
-
- This is similar to the services provided by FirstF and NextF,
- except that it places the returned file names directly into a string
- array. If you need only a few names or are searching for a specific
- name FirstF and NextF are ideal, but if you need to do something with
- a file list, DirA is much faster and neater. DirA works conventional
- string arrays (a Fixed Length String version is also included - see
- DirFLS) - be sure to initialize each element to 12 or more spaces.
- DirA returns just the file, not the pathname. If less than 12 spaces
- are available, DirA will supply as much of the name as it can and
- return a -1 to indicate you did not provide enough space in one or
- more elements.
-
- Since DirA works with a string array, you can use FilCnt first to
- get the number of files matching the mask ("*.*", "*.bas" etc) so as
- to dimension the array to the correct size. If the array is too small
- for the number of matching files and is overrun, your program will
- surely crash. (The array may be either Static or Dynamic).
-
- Note: BASIC passes parameters to sub programs by passing it's
- address. However when passing a string array element, it first makes
- a copy of that element which makes it impossible to treat it as an
- array element. By passing the first element of the array BYVAL, we
- are able to pass the address of the actual starting point to fil in
- the array. Because it is a FUNCTION and because it passes a parameter
- BYVAL, DIRA MUST be declared.
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 13
-
-
-
-
-
-
-
- Example:
-
- DECLARE FUNCTION DirA%(mask$, BYVAL ArryPtr%)
- ..
- errc = FilCnt("*.*", count)
- REDIM Fil$(count)
- FOR x = 1 to count
- Fil$(x) = SPACE$(12)
- NEXT x
-
- errc = DirA("*.*", VARPTR(Fil$(1)) )
-
-
-
-
- Name: DirF Type: FUNCTION
- Syntax: errc = DirF(mask$, SEG fil AS ANY)
- Note: DirF may be invoked as either DirF or DirFLS
-
- When you create a standard string array, what you actually create
- is a table of string descriptors indicating the length and location of
- each string element. A fixed length string array however is a con-
- tiguous block of string memory with no descriptors. Further, QB
- passes a standard string array IMAGE of a fixed length string array to
- subprograms, so a bit of cleverness is needed to address a Fixed
- Length string array - this is done by using the ANY keyword in the
- declaration statement. According to Microsoft, the recommended way to
- access User Defined (TYPE) structures and Fixed Length String Arrays
- should be passed as a segmented address and as ANY (SEG xxx AS ANY).
- Passing both the segment and address (VARSEG / VARPTR) BYVAL would
- work because it is essentially the same thing, but this is certainly
- messier.
-
- In the case of DirFLS, we must use a fixed length string that is
- precisely 12 characters per element. Using 13 or 11 or 15 will
- scramble the names due to the contiguous nature of the memory block.
- Further, since there are no descriptors associated with Fixed length
- Strings, the only error DirF will be able to detect is a NULL mask.
- Example:
- DECLARE SUB DirF (mask$, SEG arryptr AS ANY)
- ..
- ..
- TYPE FStruct ' struct to hide FLS array in
- s AS STRING * 12
- END TYPE
-
- errc = FilCnt("*.*", count) ' count files
- DIM fil(count) AS STRING * 12 ' make Fixed Len array
- CALL DirF(mask$, fil(1)) ' get dir list
-
- FOR x = 1 To count ' print them - note the .s
- PRINT fil(x).s
- NEXT x
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 14
-
-
-
-
-
-
- Name: DLight Type: FUNCTION
- Syntax: errc = DLight(drive)
-
- DLIGHT triggers the A: or B: drive light for the length of a 2
- sector disk read. This is helpful in demo or training programs to add
- realism to the session. It uses a BIOS level diskette service call
- and will return a FUNCTION error of -1 if you attempt to invoke it on
- a drive other than 0 or 1 (A: and B: respectively). On the other
- hand, the drive light will come on even if the drive is open without
- causing a "Drive Not Ready" error! Example:
- DECLARE FUNCTION DLight%(drive%)
- .
- .
- IF DLight(drv) THEN
- PRINT "Hey, dummy - I said A: or B: !")
- END IF
-
-
-
- Name: DlrFrmat Type: FUNCTION (BASIC)
- Syntax: errc = DlrFrmat(numstr$, mode, point)
-
- This allows you to format a numeric string to various currency
- conventions. Your options include allowing a "$" in front or not: if
- you allow it, DLRFRMAT will check to see if it is there and add it if
- it is not; if you do not want it, it will strip it off if entered.
- You also are allowed to format it out to 2 or 3 decimals (tenths of a
- cent). Parameters:
- nst$=String containing only numbers, "." or "$" to be formatted.
-
- Mode 0 - Returns numeric string without "$", forces a "." entry.
-
- Mode 1 - Returns numeric string with "$", forces "." entry.
-
- Point is used to tell DLRFRMAT how many decimals to pad to:
- 2 - pads "123." to "123.00"
- 3 - pads "45.1" to "45.100"
- 0 - automatic dollar decimal placement:
- "5" becomes ".05", "70" becomes ".70" and "146"
- becomes "1.46"
-
- Example:
- mode = 1 : DecPt=3
- INPUT "Enter your wage: ",nst$ 'user keys '7.50'
- CALL dlrfrmat(nst$, mode, DecPt)
- wag$ = nst$
- PRINT nst$ 'output: $7.500
-
- Note that in the case of an error, errc will be set accordingly:
- -1 = Invalid Mode specified
- -2 = Null string passed
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 15
-
-
-
-
-
-
- Name: DosVer Type: FUNCTION
- Syntax: OEM = DosVer(Major, Minor)
-
- Returns the DOS Version the system is running under as well as the
- OEM number, if any) - this is the DOS supplier for example, IBM's
- PC-DOS will return 00 as the OEM number, DEC as 16h etc. The Major
- and minor versions will be correct regardless of the OEM.
-
-
-
- Name: DPRINT Type: SUB
- Syntax: CALL DPRINT(a$)
- CALL DPrint("Hello, World")
-
- Beginning in QB4.00, the QB runtime library started to use a lower
- level method of writing to the screen for normal PRINT statements.
- This is good because it more or less builds in a QUICKPRINT feature to
- the language. But it is bad if you wish to occasionally use ANSI or
- other features that come with DOS level prints. DPRINT, is the
- inverse of a QPRINT - it uses DOS to print to the screen so that ANSI
- escape codes are recognized again. Another place that this is ex-
- tremely helpful is when your application is running under a multitask-
- ing system such as DoubleDOS, TaskView or similar - that is the
- display output will not 'bleed' thru to the other side. DPRINT should
- be declared so that you can syntactically use it the same as PRINT.
- Example:
- DECLARE SUB DPRINT(a$)
- ..
- ..
- DPRINT CHR$(27) + "[2J" ' <Esc>[2J is ASNI code to CLS
- DPRINT "Hello, world"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 16
-
-
-
-
-
-
-
- Name: DrvError Type: FUNCTION
- Syntax: errc = DrvError(drv$)
-
- DrvError is a very powerful and important function providing for a
- complete disk drive I/O Critical Error handler. It is called with the
- string character of the drive to test ("A", "C" etc). It returns a
- code indicating the level of readiness of that drive for I/O opera-
- tions to allow you to completely forego ON ERROR to trap for open
- drive doors, unformatted disks etc.
-
- DrvError works on several levels: first it takes over the DOS
- Critical Error Handler from BASIC - to trap errors before BASIC can.
- Next, it treats drive B with special care, if you attempt DrvError on
- "B", it will poll the system BIOS to see how many floppies are actual-
- ly installed to avoid "Insert disk in Drive B:..." messages. Next,
- DrvError tries to force an error first by reading the requested drive,
- to test for drive door open, formatted disks etc. Then it attempts to
- write to the drive by creating a unique file name, then deleting it.
- In any test, if an error occurs, our Critical Error Handler ISR in
- turn calls DOS to get the extended error information, tells DOS to
- abort the operation, then uninstalls the Critical error ISR, and
- returns the error code to you.
-
-
- Possible DrvError Returns:
- -1 = No Drive passed
- -2 = Attempt on non existent "B"
- 0 = all is well - proceed with a light heart
- 11, 26 = possible format errors
- 15 = Bad drive (or path)
- 19 = Write Protect error
- 21 = Door Is open
- 29 = misc Read error
- 30 = Misc Write Error
- 31 = Not formatted
- 34 = Invalid change, (DNR)
- 59 = Critical error
-
- See PhDrvSet and PhDrvCLr for suggestions on handling the phantom
- drive flag. DrvError requires DOS 3.0 or greater
- Example:
- INPUT "Drive to use: ", drv$
- errc = DrvError(drv$)
- IF errc THEN
- PRINT "Error reading from drive ";drv$
- GOSUB DrvFailure
- END IF
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 17
-
-
-
-
-
-
- Name: DrvSpace Type: SUB
- Syntax: CALL DrvSpace(a, b, c, d)
-
- Returns Total clusters, bytes per sector, available clusters, and
- sectors per cluster for the specified drive, allowing you to determine
- the overall drive space and/or free space.
- Parameters:
- Input:
- a - drive number to poll, 1= A:, 2=B: etc; 0 = default.
-
- Output:
- a - Returns sectors per cluster
- b - Returns available count of available clusters
- c - Returns bytes per sector
- d - Total clusters on drive
-
- Example:
- a=0 ' read default drive
- CALL drvspace(a, b, c, d)
- TotalSpace& = CLNG(a) * CLNG(c) * CLNG(d)
- FreeSpace& = CLNG(a) * CLNG(c) * CLNG(b)
-
-
-
- Name: EgaPrtScrn Type: SUB
- Syntax: CALL EGAPrtScrn
-
- Instructs the BIOS to ignore the default 25 line mode for Print-
- -Screen operations and check for the correct display size. All future
- Print-Screens (either via keyboard or GLIB's PrtScrn) will respect the
- actual screen size.
-
-
-
- Name: EqInfo Type: SUB
- Syntax: CALL EqInfo(Ram, Ser, Par, Game, Floppy)
-
- Returns some basic hardware configuration information. Extended
- CPU information is returned by CPUInfo, and additional Video subsystem
- is returned by VidInfo and VidType.
- Parameters
- RAM - Returns the amount of DOS memory installed
- SER - Returns number of serial ports installed
- PAR - Returns number of parallel ports installed
- Game - Returns 0/1 for game port installed
- Floppy- Returns 0,1,2 as number of physical floppies installed
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 18
-
-
-
-
-
-
- Name: ErrorMessage Type: SUB
- Syntax: CALL ErrorMessage(msg$, row, attr, sfx)
- ErrorMessage can also be invoked with the shorter name 'ErrMsg'
-
- ErrorMessage is a complex and useful subprogram designed to flash
- a defined message to the screen, pause 2 secs, then restore the
- screen. It can be used for more than just error messages, but since
- it restores the screen after the message display, it seems ideally
- suited to error messages. You determine the line to use, the sub-
- routine automatically centers the message.
-
- Parameters:
- msg$ = Message to display
- row = Line for message to display on
- attr = attribute to use
- sfx = Sound effects. 0=none 1=low tone
-
- Example:
- msg$="You must enter a customer name!"
- sfx=2
- CALL errmsg(msg$, 15, 31, sfx)
-
-
-
- Name: ExpandPath Type: SUB
- Syntax: CALL ExpandPath(FilSpec$, FullName$)
-
- DOS has an undocumented way of expanding filenames into fully
- qualified path names, complete with drive designation. By passing
- this routine a filename, it is expanded into a fully qualified file
- spec. Note that this DOES NOT do a WHEREIS type function to find the
- correct drive path designation, but merely appends the DEFAULT drive/
- path spec to the name. This remains very handy for converting a
- filespec in the current directory to a fully qualified name so that
- you can change directories and then address that file by it's complete
- name. The FullName$ where the qualified name is returned MUST be
- initialized to 64 spaces. The routine will pad the return parameter
- with spaces to 'blank out' any previous return.
-
- Example:
- DatFil$ = "myfil.dat"
- fullname$ = SPACE$(64)
- CALL ExpandPath(DatFil$, FullName$) ' expand
- DatFil$ = LTRIM$(RTRIM$(FullName$)) ' store in old variable
- CHDIR "\MAIN" ' move to main dir
-
- ' future references to DatFil$ will access the right file.
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 19
-
-
-
-
-
-
- Name: ExtPut/ExtGet Type: FUNCTION
- Syntax: errc = ExtPut(SEG DBlock, EPage, Bytes)
- errc = ExtGet(SEG DBlock, EPage, Bytes)
-
- ExtPut and Extget allow your application to access and use
- EXTENDED memory. This is NOT LIM/EMS memory but the memory found only
- on 286 or 386 systems and usually associated with protected mode
- operations. Such systems with more than 640k (usually 1MB) of onboard
- memory will have EXTENDED memory and usually use it either as a print
- spooler, ram disk or disk cache.
-
- ExtPut and ExtGet allow you to actually store and retrieve data to
- and from EXTENDED memory, which may add as much as 384k of such
- 'parking' memory to your larger programs. Note that the program does
- not execute in EXTENDED memory, but will be able to use it for data
- storage (usually an array). Once data from an array is moved there,
- it can be erased or REDIMmed to hold something else, then later
- resized and the data fetched back into DOS conventional memory for
- your program to access once again. That is, data stored or 'parked'
- in EXTENDED memory cannot be directly accessed by your program, but it
- can be fetched back for access.
-
- For purposes of these routines, we have broken the 384k (usually)
- block of memory into 24 blocks of 16k of storage which will term as
- PAGES. These pages or blocks are referenced as 0 thru 24. So, to
- store data at the 1MB mark, EPage should be set to 0, to store data in
- the second 16k block past the 1MB point, set EPage to 2 and so forth.
- You may move more than 16k at a time, indeed up to 64k of data may be
- moved in one call, but the 16k page size allows for maximum utiliz-
- ation of extended memory with a minimum of waste.
-
-
- ExtPut moves BYTES number of bytes from the passed array (DBLOCK) TO
- extended memory into the 'parking' spot EMark * 16k above the 1 meg
- mark. ExtGet, on the other hand fetches BYTES number of bytes from
- the specified parking spot INTO DOS conventional memory specified by
- DBLOCK. Even if you are not moving to or from an array, DBLOCK must
- be passed as a SEG parameter. To pass more than 32k as the number of
- bytes to move, use negative numbers for the BYTES parameter.
-
- ExtPut and ExtGet are functions that return the following error
- codes:
- 0 = Move went ok
- 1 = EXTENDED memory RAM parity error
- 2 = interrupt error
- 3 = gate address failed
-
-
- A few notes on using Extended memory:
- 1) This should be considered a very advanced routine and
- should NOT be utilized by you if you do not understand what
- EXTENDED and EXPANDED memory are and how they differ.
- 2) Again, this is NOT EMS/EXPANDED memory.
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 20
-
-
-
-
-
-
- 3) Moving less than 16k to or from EXTENDED memory still
- utilizes the entire 16k page. That is, 8k cannot be
- stored in the lower half of a block with the hopes of
- storing another 5 to 8k in the upper half of that block.
- This is designed this way to minimize extended memory
- wastage and aid in managing what data is where: there
- are generally only 24 blocks to keep track of. Note that
- is it up to your program to manage the data and what is
- stored where.
- 4) Unless you are using this in your application on your
- machine, you have no assurances that EXTENDED memory is
- not already in use as a spooler, ram disk or cache. To
- check this, simply perform a few ExtGets of 16k on the
- first few pages and if the entire array is NOT 0,
- something else is using it and you should NOT store any
- data anywhere in EXTENDED memory. Uninitialized EXTENDED
- memory should always be ZEROES. If ANYTHING is using ANY
- EXTENDED memory, you have no assurances that it might not
- allocate more later and overwrite your data - or worse,
- you could trash a VDisk with valuable data or wreck the
- hard disk FAT by trashing an EXTENDED memory cache. To
- determine whether a ExtGet is reading a cache, spooler or
- VDisk or possibly reading old data stored there by a dif-
- ferent application of yours, force a COLD BOOT at the end
- of your application to clear all memory or store an ID
- byte sequence at the start or end of the first block.
- 5) Use of this routine means that your program will NOT run
- under OS/2 in the DOS compatibility box.
- 6) Some 8088 PC's, low quality clones in particular, may
- crash and burn on this routine. So rather than depending
- on the return from either Extget or ExtPut to determine
- if it will work, use the GLIB functions CPUInfo and/or
- ExtMem to determine system type.
- 7) Use of these functions requires that the CPU be placed
- into protected mode, and may cause a loss of some
- interrupts. For example, one or more characters MAY be
- lost in programs that use ongoing serial communications
- when either ExtPut or ExtGet are executed.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 21
-
-
-
-
-
-
- Name: ExtMemFree Type: FUNCTION
- Syntax: AtMem = ExtMemFree
-
- Returns the amount of extended, or AT memory, that is installed in
- a 286 based machine, but NOT allocated or in use. Many applications
- that use extended memory now capture this interrupt and either return
- 0k of extended memory or that amount that is unallocated. Use of the
- ExtPut and ExtGet DO NOT alter the number returned by this routine.
- This only works on AT's or AT clones (80286 based machines).
- mem = ExtMem
- PRINT "AT/286 has ";mem;" of extended memory free."
-
-
-
- Name: ExtMemInst Type: FUNCTION
- Syntax: AtMem = ExtMemInst
-
- Returns the amount of extended, or AT memory, that is installed in
- a 286 based machine. This routine bypasses the interrupt that typi-
- cally is captured to return a modified or zero extended memory value.
- This returns the actual amount of extended memory installed and known
- to the system. This only works on AT's or AT clones (80286 based
- machines).
- mem = ExtMemInst
- PRINT "AT/286 has ";mem;" of extended memory installed."
-
-
-
- Name: FADE Type: SUB
- Syntax: CALL Fade
-
- This is an interesting alternative to CLS. It quickly reads the
- character at each location on the screen and decrements the ASCII
- value of it until it reaches 32 (space). The attribute (color)
- remains the same during and after the FADE. Because of the nature of
- this effect, it must be done quickly and without the overhead of the
- video retrace for CGAs. As a result this routine WILL cause snow on a
- CGA and should only be used on MONO, EGA or VGA systems.
-
-
-
-
- Name: FAttrGet Type: FUNCTION
- Syntax: errc = FAttrGet(fil$, fattr)
-
- Access to get the file attributes for a given file. Subsequent
- calls to SetFattr (qv) allow you to set or reset a file attribute.
- File attributes are as follows:
- 00 - Normal 04 - System
- 01 - Read Only 32 - Archive
- 02 - Hidden
-
- The archive bit is usually used by back up programs to determine
- if a file has been backed up since the last write process. To combine
- attributes, just add the values, ie: Read Only - Hidden would be 3
- because 1+2=3.
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 22
-
-
-
-
-
-
- This is a function and therefore also returns any error code in
- the name of the function that can be evaluated itself, or assigned.
- An error will result if the filename passed is not found (6). See
- also FAttrSet. Error Codes:
- -1 = Invalid File attribute
- 2 = File not found
- 3 = Path not found
- 5 = Access denied
-
- Example:
- DECLARE FUNCTION FAttrGet%(fil$, attrib%)
- .
- .
- fil$ = "myfil.txt"
- failure = FAttrGet(fil$, attrib)
- IF failure THEN PRINT "Sorry, cannot find ";fil$
-
-
-
-
- Name: FAttrSet Type: FUNCTION
- Syntax: errc = FAttrSet(fil$, fattr)
-
- FAttrSet allows you to change or modify the file attributes for
- any disk file that exists. For a table of the attributes, see
- FAttrGet. FattrSet is a function returning an error code. (DOS will
- not allow changes to volume labels or directories via this function.)
- Example:
- DECLARE FUNCTION FAttrSet%(fil$, attrib%)
- .
- .
- fil$="myprog.sys"
- attrib=3 ' make it Read Only, Hidden
- IF FAttrSet(fil$, attrib) THEN
- PRINT "Error - possible invalid file attribute."
- ELSE
- PRINT "Change succeeded."
- END IF
-
-
-
-
- Name: FClose Type: FUNCTION
- Syntax: errc = FClose(handle)
-
- As expected, FCLOSE performs the opposite of FOPEN, close out a
- file handle opened via FOPEN. FCLOSE does some positive error check-
- ing to make sure that you do not attempt to close one of the standard
- DOS file handles (like the keyboard, monitor etc) and will return a
- error code of 6 - Invalid File handle.
-
- See also FOpen FUnique, FCreat, FSetPtr, and DOS File Functions.
- Example:
- DECLARE FUNCTION FClose%(fhandle%)
- .
- .
- result = fclose(fhandle)
- IF result THEN GOSUB ErrorControl
-
- Copyright (C) InfoSoft, 1986-1990, 1991 23
-
-
-
-
-
-
-
-
-
- Name: FCopy Type: FUNCTION
- Syntax: errc = FCopy(source$, dest$, buffer$)
-
- This function copies a disk file using a buffer supplied by the
- main program, to perform about as fast as the DOS COPY command. You
- also pass it a source and destination string (paths / drives are ok).
- The FUNCTION returns a variety of error conditions:
- -1 = Null string passed as source or destination
- 2 = File Not Found
- 3 = Path not Found
- 4 = No Handle ("Too Many Files")
- 5 = Access Denied
-
- Example:
- DECLARE FUNCTION FCopy%(source$, dest$, buffer$)
- .
- .
- result = fcopy("GLIB.ARC","\GOODSTUFF\GLIB.ARC", SPACE$(4096))
-
- IF result THEN PRINT "Oops! Error - Check parameters!"
-
- * Note the use of SPACE$ to supply the buffer. This automatically
- creates a temporary buffer - upon the return from FCOPY, the buffer
- memory is released.
-
-
-
- Name: FCount Type: FUNCTION
- Syntax: NumFiles = FCount(fil$)
- FCount may also be invoked as FilCnt.
-
- This is can be an indispensable tool - it quickly returns a count
- of the number of files matching the given mask. This is extremely
- useful in determining how large an array should prior to a Dir or
- DirFLS call. If an invalid path or drive is included in the mask$, no
- files will be found.
-
-
-
- Name: FCreat Type: FUNCTION
- Syntax: errc = FCreat(fil$, attrib, handle)
-
- FCREAT is similar to FOPEN except that instead of opening an
- existing file, we are CREATING a NEW file. As with FOPEN, and all the
- DOS File Functions, error codes returned in the BASIC FUNCTION format
- and are:
- -1 Null string passed
- 3 Path not found
- 4 No handle available ("Too many files")
- 5 Access denied (this is returned when attempting to
- FCreat a file that already exists - use FOpen in this case).
-
- Note: You are encouraged to use FEXIST first to see if the file
- already exists, executing FCREAT on an existing file truncates it to 0
- bytes.
-
- Copyright (C) InfoSoft, 1986-1990, 1991 24
-
-
-
-
-
-
-
- Example:
- DECLARE FUNCTION FCreat%(fil$, attrib%, fhandle%)
- .
- .
- fil$="mainprg.sys": attrib=0
- IF fcreat(fil$, attrib, fhandle)=0 THEN
- PRINT "New file, ";fil$;" successfully created!"
- ELSE
- GOSUB WhatsGoingOn
- END IF
-
-
-
-
- Name: FDateGet/FDateSet Type: FUNCTION
- Syntax: errc = FDateGet(handle%, mo%, day%, yr%)
- errc = FDateSet(handle%, mo%, day%, yr%)
-
- These allow you to SET or GET the date for a file for which you
- have an open handle. (Use FOpen or BASIC's FILEATTR to get a handle).
- You may set the file date for a handle, then continue to perform I/O
- on that file and be assured that once closed, the file will be set
- with the desired date. The only likely return code would be that the
- handle% parameter is not a valid DOS handle. The year parameter may
- be either 2 or 4 digits (ie 1989 or 89). Eg:
- OPEN "foo.bar" FOR RANDOM AS #1
- handle = FILEATTR(1,2)
- errc = FDateSet(handle, 1, 1, 80) ' set date to 1/1/1980
-
-
-
- Name: FDelete Type: FUNCTION
- Syntax: errc = FDelete(fil$)
-
- Simply deletes the file indicated by fil$ from the disk. The file
- should NOT be open. This uses the DOS function UNLINK to simply
- remove the first character so it may be UNDeleted with any of a number
- of Disk tools. Example:
- errc = FDelete("foo.bar")
-
-
- Name: FDiskType Type: FUNCTION
- Syntax: NumHDs = FDiskType(DrvNo, Cyl, Sectors, Heads)
-
- Returns information regarding the installed fixed disk. On entry,
- set DrvNo to the drive to poll (0 = first hard disk etc). The func-
- tion returns the total number of fixed disks installed, and the
- Cylinder, Sector and Head count of the drive requested. Example:
- NumDrvs = FDiskType(0, Cyls, Secs, Hds)
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 25
-
-
-
-
-
-
- Name: FEOF Type: FUNCTION
- Syntax: errc = FEOF(fhandle)
-
- Sets the file pointer to the end of a file opened via FOPEN.
- This actually sets the pointer to ONE BYTE less than the end of the
- file. This is to be sure that subsequent FWRITE funtions overwrite
- any hard EOF markers (ASCII 26) left by many text editors. FEOF also
- checks for invalid handles as well as the 4 standard DOS handles and
- aborts to return an error code of 6 - Invalid handle. Using FOPEN and
- then FEOF is the equivalent of opening a file in APPEND mode using
- BASIC's intrinsic file functions. See also: FSetPtr. Example:
- DECLARE FUNCTION FEOF%(fhandle%)
- .
- IF FOpen("longtext.fil", 0, fhandle) THEN
- GOSUB StartNewFile
- ELSE
- j= feof(fhandle)
- IF j THEN GOSUB WeirdError
- GOTO AppendToText
- END IF
-
- Name: FExists Type: FUNCTION
- Syntax: ExistCode = FExists(fil$)
- This may also be called as FileExists
-
- Sets the return code (non zero) if the given file exists and no
- path or other error is encountered. See also FileDNE.
- Example:
-
- DECLARE FUNCTION FExists%(fil$)
- ..
- fil$ = "foo.bar"
- IF FExists(fil$) THEN
- PRINT fil$;" already exists! Overwrite?"
- END IF
-
-
-
- Name: FFlush Type: FUNCTION
- Syntax: errc= FFlush(Fhandle)
-
- FFlush will dump any buffered data to disk much faster than
- closing and then reopening the file will. FFlush will NOT dump the
- buffer for files opened using QB functions - QB does some significant
- buffering of its own that does not respond to FFlush. Pass FFlush the
- handle associated with the file, any return indicates an error code
- the same as the other DOS file functions. Example:
- errc = FFlush(fhandle)
-
-
-
- Name: FFlushAll Type: SUB
- Syntax: CALL FFlushA
-
- Flushes all DOS file buffers to disk and updates disk directories.
- This will not update the directories of files that are currently open.
- This is in contrast to FFlush that both commits a file to disk and
- updates the disk directory for a specific open file handle.
-
- Copyright (C) InfoSoft, 1986-1990, 1991 26
-
-
-
-
-
-
-
- Name: FHFree Type: FUNCTION
- Syntax: FreeH = FHFree%
-
- Returns an integer representing the number of file handles free or
- unallocated or available. See also FHMax, FHUsed.
-
-
- Name: FHMax Type: FUNCTION
- Syntax: MaxH = FHMax%
-
- Returns the number of maximum file handles available to the
- system. DOS by default allows 20 handles, but more or less can be
- available by using the FILES command in CONFIG.SYS. FHMax returns the
- number configured by CONFIG.SYS. See also FHFree and FHUsed.
-
-
- Name: FHUsed Type: FUNCTION
- Syntax: HUsed = FHUsed
-
- Returns the number of file handles in use by the system or other
- processes. By default, DOS will use several handles for the standard
- devices (stdaux, stdprn, stderr, stdout and stdin), and others may be
- in use by TSR's, or other processes. Note that FHMax less FHUsed will
- equal FHFree. See also FHFree, FHMax.
-
-
-
- Name: FileDNE Type: FUNCTION
- Syntax: errc = FileDNE(fil$)
- This may also be called as FNotFound
-
- This provides the inverse to the logic found in FExists. Instead
- of testing if a file DOES exist, it returns non zero if the file DOES
- NOT exist. This can be handy for logic or statements that work better
- with the non zero return. See also FExists. Example:
-
- 'REM Instead of:
- IF NOT FExists(Fil$) or IF FExists(fil$) = 0
- IF FileDNE(fil$) THEN
- PRINT "File Does Not Exist."
- END IF
-
-
-
- Name: FInfo Type: FUNCTION
- Syntax: errc = FInfo(FilMask$, SEG FileInfo AS structf)
-
- Returns compleat information about the file specified by FilMask$.
- The information is returned in a user defined data structure (TYPE)
- that is as follows (feel free to change names, but NOT the order!):
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 27
-
-
-
-
-
-
- TYPE structf
- FilAttr AS INTEGER ; the file attribute
- FilHour AS INTEGER ; the file time Hour
- FilMin AS INTEGER ; the file time Minute
- FilSec AS INTEGER ; the file time Seconds
- FilMon AS INTEGER ; the file date Month
- FilDay AS INTEGER ; the file date Day
- FilYr AS INTEGER ; the file date Year
- FilSiz AS LONG ; the size (in bytes) of the file
- FilSpec AS STRING * 12 ; the file name (no wildcards)
- END TYPE
-
- DIM FilInfo AS Structf
- errc = FInfo("*.exe", FilInfo)
- PRINT USING "Name: & Size: ########";FilInfo.FilSpec;_
- FilInfo.FilSiz
-
- errc returns any error condition found by FInfo:
- -1 = File not found (check the path)
- -3 = Mask error (FMask$ may be "")
-
- The biggest use for this function is to fetch more compleat
- information on a known file. While using wildcards are OK, only the
- first file matching the mask is returned, ie there is no FindNextFInfo
- routine. Once your program is sure of the location (path) and name
- use FInfo to fetch the rest of the name or use FInfoA (see also).
-
-
-
- Name: FInfoA Type: FUNCTION
- Syntax: errc = FInfoA(FilMask$, SEG FileInfo() AS structf)
-
- This works identically to Finfo except that it fetches the file
- information into a user defined data structure ARRAY. Useful when you
- need complete information on all .EXE files, or all .DAT files. The
- TYPE structure is identical to that in FInfo (see also). Wildcards
- are advisable and BE SURE to dimension the array large enough to hold
- all the files that will may found:
-
- fmask$ = "*.dat" ' fetch data files
- QFiles = FCount(fmask$) ' (qv) count number of files
-
- REDIM FilInfo(QFiles) AS Structf ' large enough and right type
-
- errc = FinfoA(FMask$, FilInfo(1))
-
- FOR x = 1 TO QFiles
- ' print name and size
- PRINT FilInfo(x).FilSpec; FilInfo(x).FilSiz
- NEXT x
-
-
- Name: FlexMenu Type: FUNCTION
- Syntax: item = MenuChoice% (Menu$(), Trow%, LCol%, Nattr%,_
- Hattr%, Title$, Mark%(), XtdChc%)
-
- Extensive Menuing function fully documented in MACROxx.DOC.
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 28
-
-
-
-
-
-
-
-
- Name: FindFirst Type: FUNCTION
- Syntax: errc = FindFirst(mask$, ret$)
- FindFirst may also be called as FileFirst
-
- This provides a simple, easy and straight forward access to disk
- directories by seeking the first file matching the given mask. Things
- such as an invalid path or drive will force an error return. If errc
- is clear (zero), then ret$ will hold the name of the first file found.
- Since FirstF is in assembler, you must initialize ret$ to 12 spaces to
- hold the returned name (Fewer than 12 spaces, and FirstF will provide
- as many characters as possible, and set the Error Flag - but no way,
- no how will your error result in String Space Corrupt errors with
- GLIB!). Use FindNext to get subsequent matching files. FindFirst can
- be used as a form of finding out if a file exists and even if a path
- is valid or not. Example:
- DECLARE FUNCTION FindFirst%(mask$, retf$)
- ..
- retf$ = SPACE$(12)
- mask$ = "\BIN\UTILITIES\*.COM" ' try for list of COM files
- ' in \BIN\UTILITIES dir
-
- errc = FindFirst(mask$, ret$)
- IF errc THEN
- .. something is wrong: path, none found etc
- ELSE
- ... retf$ holds filename of first \BIN\UTILITES\COM 'files
- END IF
-
-
-
-
- Name: FindNext Type: FUNCTION
- Syntax: errc = FindNext(ret$)
- FindNext may also be called as FileNext
-
- This returns subsequent filenames matching the mask passed in
- FindFirst. The mask need not be passed again, but ret$ must be
- initialized to 12 or more spaces. Once a successful FindFirst is
- executed, the only likely error return in errc is 18 that signals "no
- files found". Example: (more code intensive than DirA or DIRFLS)
- DECLARE FUNCTION FindFirst%(mask$, retf$)
- DECLARE FUNCTION FindNext%(ret$)
- ..
- retf$ = SPACE$(12)
- mask$ = "\BIN\UTILITIES\*.COM" ' look thru COM files
- ' in \BIN\UTILITIES dir
- errc = FindFirst(mask$, ret$)
- IF errc THEN
- .. something is wrong: path, none found etc
- ELSE
- DO
- ret$ = SPACE$(12)
- errc = FindNext(ret$)
- LOOP UNTIL (errc=18) or ( INSTR(ret$, "FOOBAR.COM") )
- ' loop until no more file found, or a specific file is found
- END IF
-
- Copyright (C) InfoSoft, 1986-1990, 1991 29
-
-
-
-
-
-
-
- Name: FlexType Type: FUNCTION
- Syntax: FlexCode = FlexType(drv, NumFlex)
-
- Returns the number of installed flex disk drives ("floppies") and
- a type code for the specified drive. NumFlex returns with the actual,
- physical number of flex drives installed, FlexCode returns a code
- identifying the type of flex DRIVE (NOT flex DISK!) installed:
- -1 = Invalid drive requested
- 00 = Unknown drive type or function not supported (See note)
- 01 = 360k 5.25"
- 02 = 1.2MB 5.25"
- 03 = 720k 3.5"
- 04 = 1.4MB 3.5"
- Note: Older 8088 PC BIOSes, do not support this function, and
- return -1 noting this; cheaper clones may even lock up, so invoke this
- on 8088 systems at your own risk (A PC most likely has a 360k drive).
-
-
-
- Name: FMove Type: FUNCTION
- Syntax: errc = FMove(source$, dest$, buffer$)
-
- This works the same as a FCopy/FDelete combination with source
- file being deleted after the destination file is created. As with
- FCopy and FPrint, you supply the buffer by simply passing a string or
- temporary variable. Any errc return indicates an error such as disk
- full, file already exists and is Read Only, or disk is write protect-
- ed. The source and destination file name may be on different devices.
- Example:
- errc = FMove("foo.bar", "A:foo.bak", SPACE$(4096))
-
-
-
- Name: FOpen Type: FUNCTION
- Syntax: errc = FOpen(fil$, mode, fhandle)
-
- FOPEN is a standard DOS function to open a file via a file
- handle. FOPEN requires a 'mode' be passed, 1 = multitasking or
- networking, 0 = normal. There is a way to set access rights (read,
- write, read/write) that also may be implemented later. DOS even
- reserves a special handle for your printer (see: "Dos File Functions")
- In order to keep the number of parameters down, the fhandle parameter
- is used to pass back the file handle and FOPEN is designed as a
- FUNCTION in assembler to return any error codes the same as a FUNCTION
- operates in BASIC.
- An error can occur if the file handle is invalid, the file is already
- open, file not found etc. In this case, the errorcode or result will
- indicate what happened and any fhandle number should be ignored.
- Example:
- DECLARE FUNCTION FOpen%(fil$, mode%, fhandle%)
- ..
- fil$="myprog.dat" : mode=0
- IF fopen(fil$, mode, fhandle) THEN
- GOSUB FileError
- ELSE
- PRINT fil$;" opened with a handle of ";fhandle
- END IF
-
- Copyright (C) InfoSoft, 1986-1990, 1991 30
-
-
-
-
-
-
-
- Name: FPrint Type: SUB
- Syntax: CALL FPrint(doc$, buffer$)
-
- Send a file from disk to the first printer (LPT1, PRN etc).
- This is a much handier way to print a file rather than reading it line
- by line and LPRINTing it, and takes as much memory as you lend it by
- way of the buffer. Regardless, it takes less memory than to SHELL to
- DOS and copy it to the printer and is faster than to LINE INPUT each
- line and LPRINT it. This routine will not abort if the printer is
- not ready, test for printer readiness with PtrStat. Example:
- printfil$="GLIB16.DOC"
- CALL FPrint(printfil$, SPACE$(4096))
-
-
-
-
- Name: FReadArray Type: FUNCTION
- Syntax: errc = FReadArray(SEG arry, Fhandle, BYTES)
-
- FReadArray reads data from a disk file directly into an array.
- The file must have a valid DOS File Handle which is accomplished
- either by using FOpen or FILEATTR on a BASIC file number. Elements
- indicates the number of BYTES to fill (remember that each elements in
- the array is 2 Bytes), upon return from the function BYTES is reset to
- the actual number read (in case EOF is encountered before all the
- requested bytes can be read). ERRC is set to indicate any DOS error
- encountered. See the complimentary function FWriteArry; GLIBDEMO
- shows a practical use - binary screen libraries.
- Example:
-
- DECLARE FUNCTION FReadArry%(SEG arry%, Fhandle%, Bytes%)
- ..
- ..
- REDIM ScrnArry(2000) ' 2000 elements = 1 screen
- fil = FREEFILE ' get next BAS file no
- OPEN "screens" FOR OUTPUT AS #fil
- handle = FILEATTR(fil,2)
- Bytes = 4000 ' 2000 * 2
- errc = FreadArray(ScrnArry(1), handle, Bytes)
-
-
-
- Name:FReadByte/FWriteByte Type: FUNCTION
- Syntax: errc = FReadByte(handle, byte)
- errc = FWriteByte(handle, byte)
-
- This is similar to BASIC native BINARY file I/O, allow single byte
- file access. This is not a character but a byte, or the ASCII value
- of the byte ( ASC(ch$) ) to be sent or read from disk.
- You must have a valid, open handle for the destination file - use
- FOpen or BASIC's FILEATTR for this. This can be considerably quicker
- for byte I/O than BASIC's BINARY method of allocating a string, then
- GETting and so forth. Example Read 5 bytes:
- FOR x = 1 TO 5
- errc = FReadByte(handle, byte)
- PRINT "Byte #";x;" is: "; byte
- NEXT x
-
- Copyright (C) InfoSoft, 1986-1990, 1991 31
-
-
-
-
-
-
-
- Name: FReadStr Type: FUNCTION
- Syntax: errc = FReadStr(Thing$, Fhandle, chars)
-
- FReadStr reads data from a disk file directly into a string
- variable. The file must have a valid DOS File Handle which is ac-
- complished either by using FOpen or FILEATTR on a BASIC file number.
- Elements indicates the number of CHARACTERS or BYTES to read, upon
- return from the function, CHARS is reset to the actual number read (in
- case EOF is encountered before all the requested characters can be
- read). ERRC is set to indicate any DOS error encountered. Because
- FReadStr is in high-speed assembler, you must initialize the buffer or
- string that will hold the read data to at least as long as the number
- of characters to read or an error will occur. See the complimentary
- function FReadStr.
-
- Example:
- DECLARE FUNCTION FReadStr%(Buffer$, Fhandle%, Bytes%)
- ..
- ..
- message$ = SPACE$(25)
- chars = 25
- fil = FREEFILE ' get next BAS file no
- OPEN "screens" FOR OUTPUT AS #fil
- handle = FILEATTR(fil,2)
- errc = FReadStr(Message$, handle, chars)
-
-
-
-
- Name: FRecGet/FRecPut Type: FUNCTION
- Syntax: errc = FRecGet(handle, size, SEG struct)
- errc = FRecPut(handle, size, SEG struct)
-
- These perform essentially the same function as QB's GET # and PUT
- # by reading a single record from the current location of the file
- pointer represented by the handle passed. Use FsetPtr (qv) to set the
- file pointer to the desired location. These are the single record
- version of FRecGetA/FRecPutA (qv). In using these over PUT/GET, you
- can completely bypass QB's file I/O, buffering and obnoxious error
- routines and interpret the return code for errors. The biggest ad-
- vantage to using these will be to those who are also using the multi-
- ple record I/O routines (FGet/PutRecA). Note that while these are
- setup for TYPEd file I/O, they will work for FIELDed files, though the
- hassle involved with this is probably not worth the effort. An error
- return indicates failure, generally an invalid handle was passed (6).
-
- See also FGetRecA/FSetRecA, FSetPtr. See MFEDDEMO.BAS for examples.
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 32
-
-
-
-
-
-
- Name: FRecGetA/FRecPutA Type: FUNCTION
- Syntax: errc = FRecGetA(handle, Quan, size, SEG struct)
- errc = FRecPutA(handle, Quan, size, SEG struct)
-
- These perform essentially the same function as QB's GET# and PUT#
- but rather than reading a single record, they will fill a TYPE array
- with the number of records designated by Quan. That is, rather than
- reading (or writing) many records from within a QB FOR...NEXT loop,
- you can read as many as desired in one pass and much quicker, making
- it ideal for large database operations:
-
- errc = FGetRec(handle, 128, LEN(Emp(1)), Emp(1))
-
- This would read 128 records from the file handle (starting at the
- current location) and place them in the TYPE array Emp beginning at
- subscript 1. The size of the (TYPE) structure is passed so that the
- functions can calculate the number of bytes to read.
-
- At this point, care must be taken that the read or write (trans-
- fer) request does not exceed 64k (Quan recs times Size of struct). On
- the low end that means a max of 65536 1 bytes records or 32,768 2 byte
- records which is pretty reasonable. On the high end, with large
- structures, you will need to make multiple 64k passes so the data is
- read from (or written to) the correct memory segment (large type
- structures straddle or cross segment boundaries). Example:
-
- ' assume LEN(RecStruct) = 512 bytes, and we want to read 256 '
- of them to fill a 128k array:
-
- ' read 64k (128 * 512) to RecStruct(1)
- errc = FGetRec(handle, 128, LEN(RecStruct(1)), RecStruct(1))
-
- ' read next 64k to RecStruct(129)
- errc = FGetRec(handle, 128, LEN(RecStruct(1)), RecStruct(129))
-
- Note that RecStruct subscripts would be 0 and 128 under OPTION BASE 0.
- The point is that even though it is one array, the destination
- segment for RecStruct(1) is different from that of ResStruct(129)
- (though they have adjacent addresses). Should you attempt this:
-
- ' try to read 128k (256 * 512 struct size)
- errc = FGetRec(handle, 256, LEN(RecStruct(1)), RecStruct(1))
- the routine would indeed read 128k but the last 64k would overwrite
- the first 64k ie: records 128 to 256 would be stored at RecStruct(1)
- to RecStruct (128). We plan to modify this in the future to properly
- recognize the end of a segment so that more than 64k can be read in
- one call.
- The only likely return code placed in errc, generally signals an
- invalid handle (6) or a SHARE violation (5).
-
- NOTE: Records or data are read from the file at the current DOS
- file pointer position. Use FSetPtr to locate this to the desired
- spot: QB's SEEK may not always do the equivalent on random files.
-
- See also FGetRecA/FSetRecA, FSetPtr. See MFEDDEMO.BAS for examples.
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 33
-
-
-
-
-
-
- Name: FRename Type: FUNCTION
- Syntax: errc = FRename(oldf$, newf$)
-
- This allow you to rename a disk file. Since a simple DOS function
- is used, both the source and destination files must reside on the same
- device (you may not move the file from one drive to another with this
- function - see FMove, FReplicate or FCopy for that). Any return
- indicates an error such as an attempt to span drives. Example:
- errc = FRename("foobar.new", "foobar.old")
-
-
-
- Name: FReplicate Type: FUNCTION
- Syntax: errc = FReplicate(source$, dest$, buffer$)
-
- This works very similarly to FCopy, except the file date and time
- are preserved on the destination file. As with FCopy and Fprint, you
- supply the buffer by simply passing a string or temporary variable.
- Any errc return indicates an error such as disk full, file already
- exists and is Read Only, or disk is write protected. Eg:
- errc = FReplicate("foo.bar", "A:foo.bak", SPACE$(4096))
-
-
-
- Name: FSetPtr Type: FUNCTION
- Syntax: errc = FSetPtr(Fhandle, RecNo&, RecSize)
-
- Moves the DOS file pointer to a specified location in a file
- (usually to a specific record in a random file) opened with a handle.
- Note that RecNo is a LONG INTEGER so that very large files can be
- addressed. This function is used with FGetRec, FPutRec, FGetRecA and
- FPutRecA (qv) to locate the DOS file pointer to a specific location.
- Note that this acts directly on the DOS file pointer and therefore
- acts differently than QB's native SEEK would (due to significant file
- buffering performed by the QB RTL itself). The use of this function
- is a prerequisite to calls to FGetRec, FPutRec, FGetRecA and FPutRecA.
- See also FEOF, FRecGet, FRecPut, FRecGetA, FRecPutA.
-
- Example: (TYPE Method)
-
- TYPE struct
- AName AS STRING * 25
- BStuff AS STRING * 15
- FooBar$ AS STRING * 15
- END TYPE
- DIM RecThing AS STRUCT
-
- RSIZE = LEN(RecThing) ' do 1ce rather than many LEN calls
-
- OPEN datfil$ for RANDOM as #f LEN = RSize
- Fhandle = FILEATTR(f, 2) ' Ask BASIC for handle of file
- ..
- ..
- errc = FSetPtr(FHandle, RecNo&, RSize) ' seek to RecNo
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 34
-
-
-
-
-
-
-
- Name: FTimeClear Type: FUNCTION
- Syntax: errc = FTimeClear(fhandle)
-
- This allows you to 'clear' a file time so that the time will not
- display when using the DOS DIR command. The handle must be a valid,
- open handle using either FOpen or BASIC's OPEN and FILEATTR. Example:
- fhandle = FILEATTR(BasNo, 2)
- errc = FTimeClear(fhandle)
-
-
-
-
- Name: FTimeGet/FTimeSet Type: FUNCTION
- Syntax: errc = FTimeGet(fhandle, hour, min, sec)
- errc = FTimeSet(fhandle, hour, min, sec)
-
- Like the name implies, these allow you to set or get the time of a
- file - actually the last time it's directory entry was updated. You
- must have a valid, open handle for the file via FOpen or BASIC's
- FILEATTR function. All parameters must be integers and the only
- likely error code is if the handle is not valid (file is closed). If
- you perform I/O on a file AFTER setting the time, that time request is
- used when the directory entry is updated when the file is closed. See
- also FTimeClear. Example:
- handle = FILEATTR(BasNo, 2)
- errc = FTimeSet(handle, 10, 10, 10) ' set time to "10:10:10"
-
-
-
-
- Name: FuncResp Type: FUNCTION
- Syntax: RetCode = FuncResp
-
- Returns an integer representing a function key press. The routine
- does not return until one is pressed.
- 1 - 10 = F1 to 10
- 11 - 20 = Shift + F1 to 10
- 21 - 30 = Alt + F1 to 10
- 31 - 40 = Control + F1 to 10
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 35
-
-
-
-
-
-
-
-
- Name: FUnique Type: FUNCTION
- Syntax: errx = FUnique(fil$, attr, fhandle)
- This may also be invoked as FUniq
-
- This DOS disk file function creates a file with a unique name,
- which makes it ideal for scratch data files. Rather than HOPING that
- "mydat.@@@" is a unique filename, FUNIQUE makes SURE that a file is in
- fact unique. DOS will create such a file in the specified directory
- and open it with read write access with the attributes you specify.
-
- Furthermore, FUNIQUE can, at your option, return the actual
- file NAME as well as the handle. Enter the call with a string con-
- taining the desired drive and path where you want the unique file
- created, BE SURE to include a trailing backslash ("\")! FUNIQ will
- return a file handle or error code, and if you add 12 trailing spaces
- to the pathname, it will return the filename. More often than not,
- the unique name will be just 8 chars long, but if not, it would only
- return part of the name. When the unique name IS less than 12 char-
- acters the name will be padded with spaces which allows you to use
- BASIC's native RTRIM$ to fix it.
-
- NOTE: The unique file is OPEN with a handle! Subsequent file
- access should be thru FWriteArray or FReadArray, or FCLOSE the handle,
- reopen the filename with BASIC's OPEN so as to access the filename via
- BASIC functions.
-
-
- NOTE: Use of FUNIQUE requires DOS 3.0 or greater.
-
-
- Example:
-
- DECLARE FUNCTION FUnique%(fil$, attrib%, fhandle%)
- ..
- ..
- tempfil$="C:\BIN\ "
- IF FUnique(fil$, 0, fhandle) THEN ' path, normal file
- GOSUB InvalidInfo
- ELSE
- j=fclose(fhandle) ' close the handle
- tnum=FREEFILE ' get BASIC handle
- OPEN tempfil$ FOR APPEND AS #tnum ' reopen file in
- END IF ' BASIC mode
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 36
-
-
-
-
-
-
- Name: FWriteArry Type: FUNCTION
- Syntax: errc = FWriteArry(SEG arry%, Fhandle%, BYTES%)
-
- FWriteArray writes data from an array directly to a disk file.
- The file must have a valid DOS File Handle which is accomplished
- either by using FOpen or FILEATTR on a BASIC file number. 'Chars'
- indicates the number of BYTES to write (remember that each elements in
- the array is 2 Bytes), upon return from the function BYTES is reset to
- the actual number written (in case of a lack of diskspace, or invalid
- handle, the number written will be less than that requested). ERRC
- is set to indicate any DOS error encountered. See the complimentary
- function FReadArry; GLIBDEMO shows a practical use - binary screen
- libs. Example:
-
- DECLARE SUB SvScrn(SEG Arry%)
- DECLARE FUNCTION FWriteArry%(SEG arry%, Fhandle%, Bytes%)
- ..
- ..
- REDIM ScrnArry(2000)
- CALL SvScrn(ScrnArry(1)) ' save screen to array
- fil = FREEFILE ' get next BAS file no
- OPEN "screens" FOR OUTPUT AS #fil
- handle = FILEATTR(fil,2)
- count = 4000 ' 4000 bytes in 2000 elements
- errc = FWriteArry(ScrnArry(1), handle, count)
-
-
-
-
- Name: FWriteStr Type: FUNCTION
- Syntax: errc = FWriteStr(SEG arry, Fhandle, Chars)
-
- FWriteStr writes data from a string buffer directly to a disk
- file. The file must have a valid DOS File Handle which is accomplish-
- ed either by using FOpen or FILEATTR on a BASIC file number. 'Chars'
- indicates the number of characters to write, upon return from the
- function Chars is reset to the actual number written (in case of a
- lack of diskspace, or invalid handle, the number written will be less
- than that requested). ERRC is set to indicate any DOS error en-
- countered. See the complimentary function FReadStr. Example:
-
- DECLARE FUNCTION FWriteStr%(Buffer$, Fhandle%, chars%)
- ..
- ..
- LINE INPUT "Your name, age and occupation: ", info$
- fil = FREEFILE ' get next BAS file no
- OPEN fil$ FOR OUTPUT AS #fil
- handle = FILEATTR(fil,2) ' convert File No to handle
- count = LEN(info$) ' get number to write
- errc = FWriteStr(info$, handle, count)
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 37
-
-
-
-
-
-
- Name: GetCmdTail Type: FUNCTION
- Syntax: errc = GetCmdTail(tail$)
-
- Fetches the unparsed command tail from the PSP (Program Segment
- Prefix). Unlike BASIC's COMMAND$, this is not converted to uppercase
- or otherwise touched: it is exactly as the user typed it, allowing
- your program to act on case sensitive switches. Initialize tail$ to
- 128 spaces or use GetCmdTLen (qv) to determine the size of the command
- tail. Note that using this under the QB environment will return the
- command line to invoke QB, use QBLoaded (qv) to determine how to
- interpret the tail$ return. The return code indicates possible error
- conditions: -1 = String too short: there is not enough room to store
- the entire command tail in the string. In this case, GetCmdTail
- returns as much as it can, and sets the error code. See GetCmdTLen
-
-
-
- Name: GetCmdStr Type: FUNCTION
- Syntax: CmdStr$ = GetCmdStr$
-
- This is a hybrid of GetCmdTail and ArgVar$ wherein the function
- returns the unparsed command tail (like GetCmdTail) and returns it as
- a function (like ArgVar). This will most likely replace GetCmdTail in
- a future version. Example:
- CmdLine$ = GetCmdStr$
-
-
-
-
- Name: GetCmdTLen Type: FUNCTION
- Syntax: TailSize = GetCmdTLen
-
- Returns the string length required to store the command tail.
- Allows you to initialize a string to the right length prior to a call
- to GetCmdTail rather than assuming 128 and then trimming it. The
- return is either the length required or -3 indicating incorrect DOS
- version (GetCmdTLen requires DOS 3.0).
- Example: (assume we checked DOS Version already)
- size = GetCmdTLen ' get size required
- SELECT CASE size
- CASE 0 ' no command line passed
- PRINT "No Command Line !"
- CLOSE
- SYSTEM
-
- CASE IS > 0
- tail$ = SPACE$(size) ' initilize space
- errc = GetCmdTail(tail$) ' get tail
- IF QBLoaded THEN ' test if running under
- ' the QB env
- GOSUB AjustTail ' adjust the return
- END IF
- GOSUB ParseArgs ' get options
-
- CASE ELSE
- PRINT "Weird error"
- SYSTEM
- END SELECT
-
- Copyright (C) InfoSoft, 1986-1990, 1991 38
-
-
-
-
-
-
-
- Name: GetCH Type: FUNCTION
- Syntax: ret$ = GetCH$(okay$)
-
- Return keystroke from allowable string of selections. Pass
- this routine a string of okay characters (in upper case) it will
- return which of those were pressed. GETCH ignores input other than
- those characters in the okay$. If passed a null GETCH string or a
- null return string, GetCh will return the first key pressed. Addi-
- tionally, 2 features found in GETCH not in other routines of this
- nature, is that it will not get confused by any ANSI keyboard redefin-
- itions and when used on a network, will not hang the terminal or
- server when called. Note: GetCh purges the type ahead buffer first.
- See also PGetCH, DialogBox. Example:
- PRINT "Are You Sure?": ky$=" "
- CALL getch("YN", ky$) ' allows input of Y or N only
-
-
-
- Name: GetDrv Type: FUNCTION
- Syntax: drv = GetDrv
-
- This gets the default disk drive. It returns the ASCII code of
- the letter to avoid the confusion of drive numbering. Converting to a
- character is simple with BASIC's CHR$ function.
-
-
- Name: GetDSeg Type: FUNCTION
- Syntax: DS = GetDSeg
-
- This is more a development utility than a usable subroutine.
- This returns BASIC's default Data Segment (DS). In tinkering with
- calling C and routines from other languages, I've found this useful in
- making sure that the default data segment is not changed.
-
-
- Name: GetStack Type: FUNCTION
- Syntax: SP = GetStack
-
- Returns the state of BASIC's stack. This is very helpful in
- determining what (if any) the stack should be set to, via a
- 'CLEAR,,xxxx' statement at the start of your program. The stack grows
- DOWNWARD with each successive GOSUB, so at strategic points in your
- code, calling GETSTACK and comparing it to the state of the STACK at
- the start of the program, aids in determining if you do need to
- include a stack statement at the start.
-
-
-
- Name: HALT Type: SUB
- Syntax: CALL HALT
-
- Stops the system cold, requiring it to be shut off. This can be
- handy in security situations or when you want to be sure that memory
- is cleared after your program is run. This is similar to ShutDown
- except that there is no disk parking and no graphics.
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 39
-
-
-
-
-
-
-
- Name: IACRead/IACSet/IACClear Type: FUNCTION
- Syntax: errc = IACRead(s$, iopt)
- errc = IACSet(s$, iopt)
- errc = IACClear
-
- Your machine's BIOS reserves a small amount of room (very small)
- in low memory specifically for Inter Application Communications ie to
- pass data between each other. This area is limited to 16 bytes, but
- this is enough to pass or store a 12 character filename and up to 2
- integer variables. The problem is that if you store a filename or
- string here for a later program, and before it can be read, another
- program uses this area first, our info is lost (though very few
- programs use this). While a boot obviously destroys anything stored
- in the IAC, we have stored things there and found them to be intact at
- the end of the day.
-
-
- To detect any corruption of the IAC area, we will use 2 bytes of
- the space to store a 16 bit checksum. When reading data from the IAC
- area if the checksum does not match, an error code of -3 is returned.
-
-
-
- IACSet: errc = IACSet("string var", mopt)
- Saves the string variable indicated as well as the
- integer value to the IAC area.
-
-
- The string variable may be of any length up to 12 characters, but
- not more than that. If the string passed is larger than 12 char-
- acters, the process is not carried out and an error code of -1 is
- returned. This allows at least a complete filename to be stored or a
- decent size string.
-
-
- IACRead: errc = ReadIAC(stringvar$, intvar)
-
- Reads the Intra-Application Communications Area, and stores the
- first 12 bytes into the string variable, and fills the integer var-
- iable with any value previously saved to the ICA area. If a string of
- less than 12 spaces is passed, nothing is returned and an error code
- of -2 is returned.
-
-
- IACClear CALL IACCLear
-
- This unambiguously overwrites the string area of the IAC with
- spaces and the integer area with zeroes and resets the checksum.
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 40
-
-
-
-
-
-
- Name: INCR / DECR Type: FUNCTION
- Syntax: result = INCR(x, y)
- result = DECR(x, y)
-
- There are people out there who made the tragic mistake of
- getting into one of those "other" BASIC dialects, and are having
- trouble adapting to QB. INCR and DECR are meant to help alleviate
- this. If DECLARED as a SUB, they will work just like Turbo BASIC's
- native functions of the same name.
-
-
- Name: InsOn / InsOff Type: FUNCTION
- Syntax: CALL InsOn : CALL InsOff
-
- This subroutine, simple puts the keyboard into INSERT ON state
- (INSON) or turns the insert toggle off (INSOFF). Example:
- CALL InsOn
- CALL InsOff
-
-
-
- Name: INSTRI Type: FUNCTION
- Syntax: result = INSTRI(Start, FindIn$, LookFor$)
-
- This function is identical to the BASIC native INSTR except that
- it is case insensitive. That is, INSTRI will return an integer
- pointing to the first occurrence of either "CD" or "cd" in "ABCDEF" or
- "abcdef". Like INSTR, INSTRI allows the use of a starting point to
- begin the search within the string to BE searched, unlike BASIC, this
- is not optional, a 0 will point to the same starting point. Like
- BASIC, the return is a relative pointer from the starting point.
- Further, the routine will recognize "?" in the search string as a
- match-all wild card. Example:
- DECLARE FUNCTION INSTRI%(start%, a$, b$)
- ..
- PRINT INSTRI(1, "AbCdEFGhiJkL", "cDe?") ' prints 3
-
-
-
- Name(s): ISxxxxxx Type: FUNCTION(s)
- Syntax: status = IsXxxxx(c$)
-
- The 'izzy' collection provides for assembler level replication of
- the highly useful IS??????? macros found in 'C'. Where the 'C' macros
- work only on a single character, the InfoSoft assembler implementation
- works on either a character or a string. When using a string however,
- a single non matching character forces a false return. Example:
-
- IF IsAlpha("The quick brown fox is really a lazy dog.") THEN
- PRINT "All Alpha chars!"
- ELSE
- PRINT "Non alpha chars in string!"
- END IF
-
- In this example, the return is FALSE, the string is NOT all alpha
- characters - the spaces and period in the string cause a zero (FALSE)
- return. All the IZZY functions return a 0 or -1 based on the func-
- tion. The IZZY functions are:
-
- Copyright (C) InfoSoft, 1986-1990, 1991 41
-
-
-
-
-
-
-
- IsASCII - Test if the string or character passed is
- > 0 and < 128 or ASCII
-
- IsAlpha - Test if the string or character is between A-Z or
- a-z.
-
- IsAlNum - Test if the character or string is made of
- characters A-Z, a-z or 0-9.
-
- IsCntrl - Test if the string or character is in the range 0
- to 31 or 127.
-
- IsDigit - Test if the character or string is a decimal digit,
- (0-9).
-
- IsGraph - Test if the string or character is a printable.
- The space is not considered a printable character.
- In general, this means the characters ASCII 33 to
- 127.
-
- IsPrint - Same as IsGraph except the space is allowed: ASCII
- 32 to 127
-
- IsPunct - Tests for whether a string or character is a
- punctuation mark: ~!@#$%^&*(){}[]:;"'?/><.,
-
- IsSpace - Test a character or string to see if it is a
- whitespace character (ASCII 9 to 13 or 32).
-
- IsUpper - Tests to see if the string or character is Upper
- case. Very useful when you want to preserve the
- case of some input or want to avoid generating
- string garbage in reassigning UCASE(x$) to a new,
- temporary variable.
-
- IsLower - Similar to IsUpper - tests for lower case.
-
- IsxDigit - Test for a string or character is a hex digit.
- 0-9, A-F and a-f are valid hexadecimal digits.
-
- IsGrafx - Tests if a string or character is a graphic box type
- character. These are ASCII 176 to 223.
-
- IsText - Determines if a string is text: alpha numeric, Carriage
- return, line feed, FormFeed character or graphic line
- characters (ASCII 10, 12, 13 and 176 to 223). Typical-
- ly, this could be used on a string read from a file to
- determine the type of file it is.
-
-
- IsDocs - Determines if a string is document format: All ASCII
- characters 0 - 127, and box characters (alphanumeric,
- control characters and ASCII 176 to 223). Typically,
- this could be used on a string read from a file to
- determine if the file is possibly some sort of word
- processing format.
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 42
-
-
-
-
-
-
- Name: IsLeap Type: FUNCTION
- Syntax: LeapChk = IsLeap(Year)
-
- Returns a code indicating if the year passed is a leap year (-1)
- or not (0). Note that not all years evenly divisible by 4 are leap
- years: centennial years (1700, 1800, 1900) are NOT leap years except
- those that are divisible by 400 (1600, 2000, 2400). IsLeap is
- accurate for years 1200 AD and after.
-
-
-
-
- Name: Julian Type: FUNCTION
- Syntax: JDay& = Julian&(month, day, year)
-
- Returns the _TRUE_ julian date for the passed month/day/year.
- What many dating schemes call "julian" is merely an ordinal day code
- or an ordinal code serialized with the year such as 89102 which is
- supposed to indicate the 102nd day of 1988. Even worse, there are
- some that return a SERIAL date by calculating the number of days since
- 1/1/1. These are invariably wrong since they do not take into account
- that leap years are NOT every 4 years (years such as 1700, 1900 and
- 2100 are not leap years); also they tend to ignore that there were 11
- days suppressed in 1582 (you went to bed on Oct 4, you woke up on Oct
- 15).
-
- A modified form of serial dating that is widely used is to
- calculate the number of days elapsed since Jan 1, 1900. This modified
- julian date method is used by LOTUS 1-2-3 (however they erroneously
- recognize 1900 as a leap year probably for simplicity). This is
- generally used because invoicing needs and such usually need not
- extend back to before 1900 and returns a smaller number (on the order
- of 32,000).
-
- A _TRUE_ julian date such as those returned by Julian&, repres-
- ent the number of days passed since Jan 1, 4713 BC. Note that Julian&
- returns a long integer representing this Julian date. Because
- Julian& will not accept dates before Jan 1, 0001 AD, the smallest
- number returned is 1721424. That is, Julian does not convert BC dates.
-
-
- Such a dating method allows for significant, long range date
- calculations, such as getting the date for a day x days in the future
- or x days ago. Note that in passing the year to Julian, nothing is
- assumed. That is, yr = 89 DOES NOT equate to 1989 but 88 AD.
- See JulianCvt for examples.
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 43
-
-
-
-
-
-
- Name: JulianCvt Type: FUNCTION
- Syntax: errc = JulianCvt(Ser&, mo, day, yr)
-
- Reconstitutes a long integer formulated by Julian (qv) into a
- valid date. The long integer is a _TRUE_ julian date not an ordinal
- or serialized date from an arbitrary point. The use of Date, Julian,
- JualianCvt and/or DFrmat allow for extensive date calculations. The
- function return is non zero for unsupported dates (such as any BC
- date). Example:
-
- REM 1. Find the maturity date for a 90 Certificate of '
- Deposit purchased 4/5/1989
-
- MatDate& = Julian(4, 5, 1989) ' get julian date for 4/5/1989
- CALL JulianCvt(MatDate& + 90, m, d, y) ' convert it + 90
-
- PRINT USING " CD matures in 90 days on ##_/##_/#### ";m;d;y
- CALL DFrmat(m, d, y, Mat$)
- PRINT "That day is ";Mat$
-
-
- REM 2. Calculate difference in 2 dates
-
- CALL Date(tm, td, ty) ' get today's date
- Today& = Julian(td, tm, ty) ' julian date for today
-
- DueDate& = Julian(dd, dm, dy) ' julian date for a past date
-
- Diff& = ABS(Today& - DueDate&) ' get difference in counts
-
-
- IF DueDate& > Today& THEN
- PRINT "Library book is not due for "; Diff& ; " more days."
- ELSE
- PRINT "Library Book is "; Diff&; " days overdue!"
- PRINT " Pay up $"; (Diff& * LateChg); " or be shot!"
- END IF
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 44
-
-
-
-
-
-
- Name: KBStuff Type: FUNCTION
- Syntax: errc = KBStuff(kb$)
-
- This stuffs the keyboard buffer with a string. The default KB
- buffer is 16 characters long, but many KB enhancers are available and
- used to enlarge this. If this enhancer stores the buffer start-end
- addresses in place of the standard low memory location, KBStuff will
- recognize it. If the string to stuff is longer than the buffer, the
- FUNCTION stuffs as much as the buffer allows and return a code of -2.
- If the string to stuff is NULL, the return code is -1. In the case of
- -2 returns, you should shorten clear the keyboard and/or parse the
- stuff string to smaller sub strings.
-
- Note: Because of the way the BIOS expects to find the buffer start
- and end addresses, many enhancers set up a secondary buffer and feed
- the low-memory buffer from their own. The size of the buffer in
- characters is available from the function KBBuffSize. Also, for some
- reason, you may need to add a trailing space if the last character is
- a carriage return. Example:
- kb$ = "MASM KBStuff" + CHR$(13) + "exit" + CHR$(13) + " "
- SHELL ' assemble the program, exit to main program. Note
- ' trailing space
-
-
-
-
- Name: KBBuffSize Type: FUNCTION
- Syntax: size = KBBuffSize
-
- Return the recognized keyboard buffer in low memory. The buffer
- can be enlarged, and moved from the DOS default area by a keyboard
- enhancer. In most cases, KBBuffSize will not return the size of this
- enhanced/enlarged buffer because the KB utility is 'feeding' the low
- memory buffer from it's own buffer, in this case, the default 16
- character size. Use the return of this function to determine the max
- length of string allowed in KBStuff. Example:
- MaxChars = KBBuffSize
-
-
-
- Name: KeyReady Type: FUNCTION
- Syntax: status = KeyReady
-
- Returns zero or non zero to indicate if a key is waiting to be
- read from the keyboard input buffer. The advantage to this is that
- you can test for the situation WITHOUT actually removing the key from
- the buffer - also for users of QB 4.00 and (a), it performs similar to
- SLEEP. Example:
- IF KeyReady THEN GOSUB MenuFunc
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 45
-
-
-
-
-
-
- Name: KeyLockCap, KeyLockNum, Type: FUNCTION(s)
- KeyLockScrl, KeyLockIns
- Syntax: chk = KeyLockCap%
- chk = KeyLockNum%
- chk = KeyLockScrl%
- chk = KeyLockIns%
-
- Checks a specific keyboard lock key (CapsLock, NumLock, Scroll
- Lock or Insert) and returns non zero (-1) if it is currently engaged
- or zero if it is not. See also KeyShift---.
-
-
-
- Name: KeyRateSet/KeyRateClr Type: FUNCTION/SUB
- Syntax: errc = KeyRateSet(delay%, rate%)
- CALL KeyRateClr
-
- AT systems (as well as PCjr) have the ability to adjust the
- keyboard sensitivity rate, (Typematic rate). Sources indicate that
- this is an AT capability as opposed to a 80286 feature, so I am unsure
- whether this is available to XT/286 systems. KeyRateSet allows you to
- tailor the keyboard response so that your program can appear to be
- incredibly responsive and ZOOM the cursor to and fro across the
- screen. The Delay parameter controls how long after a key is held
- down before Typematic begins in the range 0 to 3:
- 0 - 250 milliseconds 2 - 750 milliseconds
- 1 - 500 milliseconds 3 - 1000 milliseconds (1 sec)
-
-
- The Rate parameter controls the Typematic speed or how many characters
- per second will be generated. Valid parameters are 0 to 31; parameter
- speeds in characters per second (cps):
- 00 = 30.7 08 = 15.0 16 = 7.5 24 = 3.7
- 01 = 26.7 09 = 13.3 17 = 6.7 25 = 3.3
- 02 = 24.0 10 = 12.0 18 = 6.0 26 = 3.0
- 03 = 21.8 11 = 10.9 19 = 5.5 27 = 2.7
- 04 = 20.0 12 = 10.0 20 = 5.0 28 = 2.5
- 05 = 18.8 13 = 9.2 21 = 4.6 29 = 2.3
- 06 = 17.1 14 = 8.6 22 = 4.3 30 = 2.1
- 07 = 16.0 15 = 8.0 23 = 4.0 31 = 2.0
-
- To reset BIOS default delay and typematic rate, use KeyRateClr:
- CALL KeyRateClr
-
- Note that SMALLER parameters indicate LARGER cps rates and there-
- fore FASTER keyboard rates. Also, passing invalid parameters seem to
- produce no change in the TypeMatic rate (the BIOS seems to ignore
- them). Neither of these routines will execute if a 80286 processor is
- not present and KeyRateSet will return an error code of -1 if there is
- no 286 present.
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 46
-
-
-
-
-
-
- Name: KeyShiftAlt, KeyShiftCtrl Type: FUNCTION(s)
- KeyShiftRgt, KeyShiftLft
- Syntax: chk = KeyShiftAlt%
- chk = KeyShiftCtrl%
- chk = KeyShiftRgt%
- chk = KeyShiftLft%
-
- Checks a specific shift key (Alternate, Control, Left-Shift or
- Right-Shift) and returns non zero (-1) if it is currently pressed or
- zero if it is not. See also KeyLock---.
-
-
-
-
- Name: LCount Type: FUNCTION
- Syntax: NumLines = LCount(fhandle, buffer$)
- This may also be called as LineCount.
-
- This is a nifty routine to swiftly scan an existing disk text
- file for ASCII 13 (carriage return) and count them (which is a short
- cut way of determining lines in a file...). This is handy for
- sequential file I/O where you might want to inform the user how long
- processing will take or to replace a loop thaty includes a BASIC
- function evaluation:
-
- WHILE NOT EOF(x) ' BASIC will execute EOF function
- .... ' many times
- WEND
-
-
- FOR x=1 to NumLines ' no basic function!
- ....
- NEXT x loop.
-
- LCOUNT is a function that requires a valid file handle via
- FOpen (or the return from FILEATTR) and a scratch buffer - typically,
- you will find that a buffer of 4096 characters is sufficient).
-
-
- An attempt to LCOUNT a standard DOS handle (1-4) is trapped by
- LCount and will return an error of -1. LCOUNT is incredibly fast: a
- 50K test file takes only .5 seconds to count on a 286 system.
-
-
- LCount leaves the DOS file pointer at the end of the file, so
- prior subsequent INPUT and LINE INPUT statements should be preceded by
- a BASIC SEEK or a GLib SetFPtr to relocate it to where you want it.
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 47
-
-
-
-
-
-
- Name: LNameF Type: FUNCTION
- Syntax: SwappedName$ = LNameF$(text$)
-
- This data entry routine is handy for rearranging names from some
- other source to convert them to "Lastname, FirstName". It works on
- names of all types, those with middle initials, just first and middle
- initials, multiple middle names. It does not work correctly on Jrs,
- people who are the II, III or IV (ad nauseum). In this case, I'd
- suggest using BASIC's INSTR and LEFT$ to trim off the Jr or II etc and
- append it after the LNAMEF call.
-
- All that is required is that the name have one single trailing
- space and another space where the names get swapped. The function
- will fail and return a -1 if either condition is found to be not true.
-
- Examples:
-
- "Mary Beth J. Sandra Brooks " => "Brooks, Mary Beth J. Sandra"
- "P. T. Barnum Bailey " => "Bailey, P. T. Barnum"
- "Thomas Q. McFly III " => "III, Thomas Q. McFly"
- "John Public" => "John Public"
- This one fails due to no trailing space$
-
-
-
-
- Name: LPrintX Type: Function
- Syntax: errc = LPrintX(text$, printer)
-
- Send the string 'text$' to the designated printer (1 - 4). After
- each character is printed, it tests to see if it is online and if not,
- aborts the operation and returns a non zero error code. This works
- fine for Out of Paper and Power Off situations, but those that are
- simply offline, it may take quite a while for it to timeout (See
- LPTDelay).
-
-
-
-
- Name: LPTDelay Type: SUB
- Syntax: CALL LPTDelay(printer, DelayValue)
-
- The system BIOS stores a Time-Out value in low memory that tends
- to represent a relative number of seconds required before a time-out
- can be detected. The actual value in low memory tends to represent
- seconds on 8088/8086 machines and (seconds/4) on 286 systems. This
- value is usually 20 meaning anything from a 20 second to 60 or 70
- second delay for a timeout. The sub program LPTDelay allows you to
- alter this value which can be pretty handy, particularly during
- testing and debugging of printer I/O routines and error handlers
- (see LPRINTX). The new DelayValue is placed in the time-out table for
- the printer specified and would be used in future (parallel) printer
- operations. You should either restore this value to 20 or reboot when
- done. Remember, that value is not actual seconds to time-out, but
- lower numbers will timeout more quickly than higher numbers.
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 48
-
-
-
-
-
-
- Name: MCsrInc/MCsrDec Type: SUB
- Syntax: CALL MCsrInc
- CALL MCsrDec
-
- Mouses are curious things. Each call to turn off the mouse
- cursor requires an equal number of cursor-on calls to redisplay the
- cursor. The mouse driver tracks what is called an internal cursor
- flag. Each call to turn off the cursor decrements the counter, each
- cursor-on call increments it and if (and only if) the internal flag is
- 0, the cursor is displayed. Therefore each call to decrement the
- flag, needs one increment call if the cursor is to be displayed. And
- this does NOT work the other way, if the cursor is on (flag=0) an
- additional call to increment the flag has no effect. Finally, we have
- no access to be able to read what the cursor flag is to know how many
- MCSRINC calls we need to make to display the cursor.
-
- If you are new to mouse programming, take care updating the
- screen with the mouse cursor on, it can leave little reverse video
- blocks all over, and at times, doing a MSETXY with the cursor on will
- produce 2 cursors: one at the old and another at the new location. To
- avoid this, turn the mouse cursor off before screen updates, including
- (indeed, especially with) screen saves and restores and forced mouse
- cursor relocations.
-
- MCSRINC and MCSRDEC increment or decrement the cursor. Knowing
- what you do now, it would make sense to track a copy of the internal
- flag in your program. If in the course of your program you want to BE
- SURE that the cursor is on or off, performing a call to MCSRON or
- MCSROFF will do so. However in so doing, the mouse is reset: x and y
- range limits, cursor masks, mickey factors, the works. SEE ALSO
- MCSRON, MCSROFF
-
- Example: Logical Equivalence
-
- CALL MCsrInc ' InternalFlag=InternalFlag + 1
- ' IF InternalFlag=0 THEN ShowCursor
-
- CALL MCsrDec ' InternalFlag=InternalFlag - 1
- ' IF InternalFlag<>0 THEN HideCursor
-
-
-
-
- Name: MCsrOn / MCsrOff Type: SUB
- Syntax: CALL MCsrOn
-
- Reset the mouse to power on state and force an unconditional
- cursor on or off. This Unconditional Cursor On function also initial-
- izes the cursor thus erasing XY ranges, and resetting the mouse cursor
- location. See also MCSRINC/MCSRDEC.
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 49
-
-
-
-
-
-
-
-
-
- Name: MGetXY Type: SUB
- Syntax: CALL MGetXY(TextFlag, Mx, My)
-
- As you might expect, this gets the current X,Y location of the
- mouse. The location of the text cursor has no bearing on what this
- returns. Nor does it matter if the mouse cursor is on or off: MGetXY
- returns the CURRENT location of the cursor, NOT the LAST SEEN loca-
- tion. Unlike some "other" QB libraries, MGetXY and MSetXY (see also)
- use and act upon either 80x25 coordinates or pixel mode thru the use
- of a flag. Setting TextFlag to 1 instructs the code to convert the
- return to 80x25 coordinates, 0 returns pixel based locations.
- Example:
-
- REM get mouse cursor
- CALL MGetXY(1, MouseRow, MouseCol)
-
-
-
-
-
- Name: MLong / MNorm Type: FUNCTION
- Syntax: CALL Mlong : CALL MNorm
-
- Control of the sensitivity of the mouse is the ratio by which
- one mouse inch moves x number of characters or pixels on the screen
- and is called the Mickey Factor.
- The default Mickey Factor of the New Microsoft Mouse is about 2
- inches per 80 horizontal characters and 1 inch per 25 rows vertically.
- MLONG alters the Mickey Factor so that it takes about twice as much
- desk space to travel the same screen distance: 4 inches horizontally,
- 2 inches vertically, while MNORM resets the Mickey back to 2 horizon-
- tally, 1 vertically, as does a call to MCSRON (qv).
-
-
-
-
-
- Name: MRelease/MPress Type: SUB(s)
- Syntax: CALL MRelease(lft, rgt)
-
- These mouse routines return the number of mouse button RELEASES
- or PRESSES since the last time the mouse driver was polled. One
- obvious use of these two routines is to poll the driver to see if a
- double click has been executed since the last poll (say, while the
- program was off doing a disk access or such). Example:
- CALL MRelease(lbutton, rbutton)
- CALL MPress(lbutton, rbutton)
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 50
-
-
-
-
-
-
-
-
-
- Name: MSetXRng / MSetYRng Type: SUB
- Syntax: CALL MSetXRng(TextFlag, min, max)
- CALL MSetYRng(TextFlag, min, max)
-
- MSetXRng and MSetYRng allow you to limit the minimum and
- maximum X and Y range that the mouse cursor is to be allowed to roam
- in. A use for this would be to limit the mouse to an area in a window
- or a menu. Further, this routine is suitable for use in either text
- or graphics modes thru a flag. Example:
-
- REM limit mouse area to a box of 5,1 to 12,40 in 80x25 mode:
- TextMode = 1
- MinR = 5: MaxR = 12
- CALL MSetXRng(TextMode, MinR, MaxR)
- MinC = 1: MaxC = 40
- CALL msetyrng(TextMode, MinC, MaxC)
-
-
-
-
- Name: MSetXY Type: SUB
- Syntax: CALL MSetXY(TFlag, row, col)
-
- This is the simple inverse of MGetXY, setting the current mouse
- cursor position. MSetXY works off of either 80 x 25 based coordinates
- (if TFlag = 1) or pixel based locations.
- Note that the mouse cursor normally seems to default to center
- screen (12,40) with a simple cursor on call (MCSRINC, MCSRON).
- Example: ' set Mcursor position to row 20, column 60
- CALL MSetXY(1, 20, 60)
-
-
-
-
- Name: MSMouse Type: SUB
- Syntax: CALL MSMouse(ax, bx, cx, dx)
-
- While the mouse functions incorporated into GLIB are fairly
- comprehensive, there may be times when you want to execute one of the
- more esoteric ones like cursor customization. MSMouse provides for a
- way of executing any general mouse function directly to the Microsoft
- Mouse Driver. AX, BX, CX and DX are the registers (also referred to
- as M1, M2, M3 and M4 in some mouse references). AX (or M1) is used to
- indicate the function to execute and the others may need to be loaded
- with other required parameters. After executing the interrupt, the
- parameters are replaced with the register contents after that inter-
- rupt. If you do not have a decent mouse reference there are a few on
- the Information Booth - or call and leave a note and we will look it
- up for you.
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 51
-
-
-
-
-
-
-
-
- Name: MSetCsr Type: SUB
- Syntax: CALL MSetCsr
-
- This is a rather specialized routine for the mouse. Some of
- the less compatible mice require a little tweaking to get the cursor
- to display. If you have trouble getting a cursor to display, calling
- MSetCSR should set the mask so that it does display when the cursor is
- on. It appears to have no ill effect on mice who do not need it.
-
-
-
-
- Name: MStatus Type: SUB
- Syntax: CALL MStatus(lft, rgt)
-
- This returns a 0/1 indicating if the left or right mouse button
- is currently being pressed.
-
-
-
-
- Name: MType Type: FUNCTION
- MouseType = MType
-
- This routine returns whether a mouse exists or not as the
- number of mouse buttons. Naturally, that means 0, 2 and 3 are the
- only MTYPE returns you should expect.
- Example:
- MouseExist = MType
- IF MouseExist THEN
- ..
- ..
- END IF
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 52
-
-
-
-
-
-
- Name: MemCompA Type: FUNCTION
- Syntax: code = MemCompA(SEG Arry1, SEG Arry2, words)
-
- Compares the listed number of WORDS of two memory sections (ty-
- pically this would be elements of 2 arrays) and returns the BYTE
- offset where they mismatch or 0 if the 2 things to compare are ident-
- ical. This can be helpful in UnDo type functions or to determine if
- I/O in a SUB altered an array. See also MemCompV. Eg:
- REDIM AArray(10), BArray(10)
- code = MemCompA(AArray(1), BArray(1), 20) ' 10 * 2 = 20 bytes
- IF Code THEN
- PRINT "Arrays are not identical"
- END IF
-
-
-
-
- Name: MemCompV Type: FUNCTION
- Syntax: offs = MemCompV(SEG Arry)
-
- Compares the video display to the next 4000 bytes in the array
- passed and returns an offset of where they differ or 0 if they are
- identical. Snow is checked for if a CGA is detected. Note that the
- return will indicate a screen OFFSET from (1,1) where the screen
- differs from the array. Note also that the array offset passed can be
- any position. The returned value is a WORD offset that allows us to
- easily convert to Row/Column coordinates. See also MemCompA.
- Example:
-
- scrn = 4001 ' point to screen offset 3
- CALL SaveScrn(Array(scrn)) ' save video to position 3
- GOSUB DoStuff
- offset = MemCmpV(Array(scrn))
- IF offset THEN
- PRINT "Screen altered at offset: ";offset
- END IF
-
-
-
-
-
- Name: MemMove Type: SUB
- Syntax: CALL MemMove(SEG src, SEG dest, words)
-
- MemMove works like the standard 'C' function of the same name - it
- moves a block of memory from the source to the destination. One
- excellent use for this is to replicate arrays. Make sure that the
- destination array is large enough for the number of bytes to copy so
- as not to write to an unallocated block of memory. Example:
- DECLARE SUB MemMove(SEG Src%, SEG Dest%)
- ..
- ..
- REDIM Arry1(2000), Arry2(2000)
- ..
- CALL MemMove (Arry1(1), Arry(2), 2000) ' 2000 = 2000 elements
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 53
-
-
-
-
-
-
-
- Name: MenuCtrl Type: FUNCTION
- Syntax: code = MenuCtrl
-
- MENUCTRL is a keyboard / menu control module that is totally
- network compatible to trap specific keys. As such, it is ideal for
- menu driven routines. When called, the routine intercepts all key-
- board activity exiting only if a number key or function key is pressed
- - any other input is ignored. MENUCTRL returns the value of the key
- or function key pressed, ie '1' and/or '[F1]' return 1, '2' and/or
- '[F2]' returns 2 etc. Pressing [Esc] returns 15.
-
-
-
-
- Name: MergeArray Type: SUB
- Syntax: CALL MergeArray(SEG Mask, SEG Dest, Words)
-
- Given two arrays (presumably screen images), all characters in
- MASK array are transferred to the destination array EXCEPT when they
- are a space. One use for this would be to superimpose a grid or other
- mask over an image then ScrnRest it to the video for reference points.
- If you retain an unaltered image of it, you could allow the user to
- flip back and forth. Pseudo Animation is another possibility. Note
- that the number of WORDS or INTEGERS is used rather than BYTES. See
- also MergeScrn. Example:
- DECLARE SUB MergeArray(SEG Mask, SEG Dest, ByteCnt)
- REDIM Scrns(2000), Grid(2000) ' allocate memory
- GOSUB FillGrid ' put lines in Grid()
-
- GOSUB GetScrn ' put whatever in array
- CALL MergeArray(Grid(1), Scrns(2001), 2000)
- ' Merge Grid over Screen
- CALL RestScrn(Scrns(1)) ' display end result
-
-
-
-
-
-
-
- Name: MergeScrn Type: SUB
- Syntax: CALL MergeScrn(SEG Mask)
-
- This is similar to MergeArray except the mask is merged directly
- to the screen and 4000 bytes is assumed. Example:
- DECLARE SUB MergeScrn(SEG Mask%)
- REDIM Grid(2000) ' allocate memory
- GOSUB FillGrid ' put lines in Grid()
-
- CALL MergeScrn(Grid(1)) ' place GRID over CRT display
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 54
-
-
-
-
-
-
- Name: MFED Type: FUNCTION (BASIC)
- Syntax: FCode = MFed(ed$, fsiz, Macro$())
-
- (Complete documentation and use is in MACROxx.DOC)
- This is a very comprehensive text input routine that allows you
- extensive control over user input. It is used to exert total control
- over the user's input, recognizing all cursor and function keys.
- Ed$ - string to edit
- fsiz - maximum length allowed
- Macro$() - array of strings to be invoked with [Alt- ] key
- strokes.
- Be sure to carefully read MACROxx.DOC for set up of the COMMON block!
-
-
-
-
- Name: MHZ Type: FUNCTION
- Syntax: speed = MHZ
-
- This returns the approximate, effective MegaHertz the system is
- run at. Sound vague enough? This return is the result of a very
- quick benchmark. It is "approximate" and "effective" Mhz because it
- will be off a little depending on the number of wait states of the
- machine, and some faster PC clones return falsely high numbers.
- MHZ returns the speed factor as a whole number: that is a
- return of 935 means an effective MHZ speed of 9.35. Divide the return
- by 100. It is advised that you cross reference the speed with the
- chip: if MHZ returns 1400 but CPUINFO indicates a 8088 machine, you
- know the speed is wrong and that the PC is more likely 8 to 10 MHz.
-
-
-
-
- Name: MilliDelay Type: SUB
- Syntax: CALL MilliDelay(millisecs)
-
- MilliDelay works like DELAY in that it enables you to insert
- controllable delays or slow downs into your code for effect or to
- allow the end user time to digest the screen. This halts processing a
- given number of milliseconds (100 milliseconds minimum) and works out
- great when a full second is too long. Example: CALL mdly(100)
- ' delay .1 seconds
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 55
-
-
-
-
-
-
- Name: NFrmat Type: FUNCTION (BASIC)
- Syntax: errc = NFrmat(numst$, mode, point)
-
- This routine allows for extensive numeric string processing. You
- can format a numeric string to pre determined formats such as 7 or 10
- digit phone numbers, social security or an account number type format.
- Parameters:
- numst$ = string to process (presumably numeric)
- p = position of a single "-" for mode 4 (account number
- numbers...)
- m = mode or level of processing to perform:
- Mode 1 = Seven digit phone number ie: ###-####
- 2 = Formatting to 10 phone type ie: (xxx) xxx-xxxx
- 3 = Formatting to social security style ie: xxx-xx-xxxx
- 4 = Format with "-" in position p.
-
- To get (316)-684-8744 out of 3166848744:
- errc = NFrmat(st$, 2, 0)
-
- Mode 4 Example:
- INPUT "Account Number:", st$ ' they key in 3145678
- errc = NFrmat(st$, 4, 3)
- PRINT st$ ' output would be 31-45678
-
- Errc returns -1 on an unknown mode or format code.
-
-
-
-
- Name: NLON / NLOFF Type: FUNCTION
- Syntax: CALL NLOn : CALL NLOff
-
- Sets the Keyboard Num Lock key to on (NLON) or off (NLOFF).
-
-
-
- Name: NoBoot Type: SUB
- Syntax: CALL NoBoot(func)
-
- This "steals" the keyboard interrupt to watch for the simultaneous
- press of Ctrl-Alt-Del, which it promptly disregards. Since this does
- act to replace the keyboard handler, it is imperative that you un-
- install it before your program terminates, as well as part of any
- error handler you have and certainly before hitting Ctrl-Break to drop
- to QB editor level when running in the QB environment. Function 0 un-
- installs NoBoot, any non zero value installs it - take care not to
- install multiple copies! Example:
- CALL NoBoot(1) ' install it
- CALL NoBoot(0) ' uninstall it
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 56
-
-
-
-
-
-
- Name: Painter Type: SUB
- Syntax: CALL Painter(Trow, Lcol, Brow, Rcol, newattr)
-
- This re-colors the specified area of the screen with the new color
- specified in newattr. This is ideal and well suited for bar menu
- type functions to recolor or hi-light the current selection, or for
- modifying a color screen for mono use (Turn off the video, repaint it
- and turn it back on - then SAVE it for future use!) Example: Recolor
- right half of screen to yellow on red:
- CALL Painter(1, 40, 25, 80, 78)
-
-
-
- Name: ParseFileSpec Type: FUNCTION
- Syntax: errc = ParseFileSpec(raw$, drv$, path$, fil$, ext$)
-
- Given a legal filename, this will parse it into it's component
- parts and devoid of trivial punctuation (colons and dots are removed,
- backslashes are not). Being in assembler, you must initialize the
- return parameters to avoid string space corrupt errors:
- Drv$ - minimum 1 for drive character storage
- Path$ - Up to 64 characters
- fil$ - up to 12 characters
- ext$ - 3 characters
- If the actual size in raw$ exceeds the amount you pass, as much as
- will fit will be returned, and an error code will be returned to
- indicate you passed a short string: ext$ = -1, fil$ = -2, path$ = -3,
- drv$ = -4. Additionally, if raw$ is NULL, -5 is returned.
-
-
-
-
- Name: PCase Type: FUNCTION
- Syntax: p$ = PCase$(p$)
- PCase can also be invoked with the longer name ProperCase.
-
- Converts a passed test string to 'proper case'. That is, "bob
- smith" is returned as "Bob Smith". Prior to calling PCASE convert the
- string to lower case:
- x$ = "TIMOTHY FOOBAR"
- x$ = LCASE$(x$)
- CALL PCase(x$)
-
-
-
- Name: PGetCh$ Type: FUNCTION
- Syntax: ret$ = PGetCH$(prompt$, row, attr, okay$)
-
- This routine is similar to GETCH in that it allows keyboard
- input only from a predefined string, is ANSI compatible and network
- functional, but additionally allows the addition of an automatically
- centered prompt. By predefining a number of prompts and input masks,
- a variety of easy to use prompt-and-allowable-input-masks can be setup
- for very easy use. See also GETCH, DialogBox. Example: Display a
- prompt on line 24, in yellow on red, allowing only "YNA" input:
- prompt$ = "Are You Sure Y/N/Abort"
- okay$ = "YNA": ky$ = " "
- CALL pgetch(prompt$, 24, 78, okay$, ky$)
-
- Copyright (C) InfoSoft, 1986-1990, 1991 57
-
-
-
-
-
-
-
-
- Name: PhDrvSet Type: SUB
- PhDrvClr Type: SUB
- PhDrvStat Type: FUNCTION
- Syntax: CALL PhDrvSet
- CALL PhDrvClr
- flag = PhDrvStat
-
- Since DOS uses Drive A: as both A: and B: on single floppy sys-
- tems, it uses a flag to keep track of what state it is in. PhDrvClr
- and PhDrvSet allow you to manipulate this flag to avoid the "Insert
- disk in drive B:..." message in operations where you wish to use a
- single floppy as both A: and B:. PhDrvSet sets the flag to indicate
- that drive A: is acting as B:, PhDrvClr clears it to A: acting as A:.
- PhDrvStat returns the current status of the flag 0 (clear) or 1
- (set). Note that should supply your own message and keypress routine
- to allow the end user time to swap disks, but certainly, you can do a
- better job than DOS. Also, you should reset the flag when done.
- Example:
- ..
- CopyToB:
- CALL PhDrvSet ' Set A: to B:
- IF DrvError("B") THEN
- GOSUB DrvNotReady ' test it
- END IF
- GOSUB CopyBlock ' perform operation
- CALL PhDrvClr ' clear flag (A: = A:)
- RETURN
-
-
- Name: PrgName Type: FUNCTION
- Syntax: errc = PrgName$
-
- When we wrote BCLock (a program that makes your compiled program
- aware of changes to itself either from tampering or virus infections),
- we needed a way to get our OWN file/path name. This function is
- functionally identical to C's 'argv[0]', returning the full drive and
- path name of the program executing. This can be very useful for those
- that wish to store operating parameters in the EXE file itself rather
- than in a CFG or INI file. (The questionable theory of this is to
- open the EXE file and store a TYPE structure of parameters at the end
- of the EXE. This is all fine until the user attempts to run the
- program outside the current directory (via path) or they rename your
- .EXE file - then this nifty idea comes crashing to an insolvable
- halt).
-
- The return from PrgName will contain the drive/pathname of the
- currently executing program. This return string can then be parsed
- into components if desired. (See also ArgCnt, ArgVar and GetCmdStr$
- et al). Note: PrgName will return different information in the QB
- environment than as a .EXE file, because the program running is QB.EXE
- and NOT your program - yet. Example:
- MyName$ = PrgName$ ' returns "C:\DIRNAME\FOOBAR.EXE"
- PRINT "Program running is: "; MyName$
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 58
-
-
-
-
-
-
- Name: PrtQueStat Type: FUNCTION
- Syntax: RetCode = PrtQueStat
-
- Fetches the status of the DOS print queue. Note that this is the
- PRINT.COM file that comes with DOS and the function is informing you
- if PRINT is resident and therefore other PrtQue functions are avail-
- able to you. Possible returns are:
- -1 = PRINT.COM is installed and resident
- 1 = PRINT.COM not installed and it is NOT ok to install
- 0 = PRINT.COM not installed, ok to install
-
- NB: AT LEAST QB 4.0 (maybe 4.00(a) and possibly 4.00(b)) has a
- problem getting along with PRINT.COM. Our testing with PRINT.COM from
- DOS 3.1 and QB 4.00(b), BASCOM 6.0 and QB 4.5 has resulted in no
- problems but this is no guaranty of your results.
-
-
- Name: PrtQueSubmit Type: FUNCTION
- Syntax: errc = PrtQueSubmit(fil$)
-
- Submits a file to the DOS print spooler. The file must exist, and
- occasionally it has seemed that we needed to pass a fully qualified
- drive/path name before PRINT.COM would accept it (see ExpandPath),
- however the name may not include wildcards (? or *). Any return other
- than 0 indicates an error:
- 0 = File accepted into PrtQue
- 1 = Error accepting file
-
-
-
-
- Name: PrtQueDelete Type: FUNCTION
- Syntax: errc = PrtQueDelete(fil$)
-
- Deletes the specified filename from the Printqueue, the file must
- have been previously submitted via PrtquSubmit, and while it responds
- to wildcards, a fully qualified drive/pathname may be required (see
- ExpandPath). Note that if the file you wish to delete or remove from
- the Print Queue is currently being printed, that printing may not halt
- immediately due to any buffering done by the printer. Any return
- other than 0 indicates an error.
-
-
-
- Name: PrtQueCancel Type: FUNCTION
- Syntax: errc = PrtQueCanel
-
- Cancels ALL files currently in the print queue (these would have
- been submitted via PrtQueSubmit). Note that in cancelling all files
- queued, that PRINT.COM prints a message on the printer noting the
- cancellation. This is DOS or PRINT.COM's doing, not mine. Any return
- other than zero indicates an error.
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 59
-
-
-
-
-
-
- Name: PrtScrn Type: SUB
- Syntax: CALL PrtScrn
-
- This very simply sends the current display to the printer.
-
-
-
- Name: PrtScEnable Type: SUB
- PrtScDisable Type: SUB
- Syntax: CALL PrtScDisable
-
- These 2 routines act to toggle the ability of the system to
- perform a Print Screen function. This can be handy in cases where the
- information on screen is sensitive to the extent that your application
- needs to prevent it from being printed. Note that TSR type dump-to-
- disk utilities will still work, but once installed Shift-PrtSc will
- not work until the system is re-booted or PrtScEnable is called.
-
-
- Name: PtrInit Type: SUB
- Syntax: CALL PtrInit(prtnum)
-
- Initialize the printer, and if the offline button is set to
- OFFLINE, it will put it online (most Epsons anyway) and set the
- printer to TOF (Top Of Form). Call it with the designated printer
- port to initialize (1 to 3). See also PtrStat. Example:
- CALL PtrInit(PrinterNum)
-
-
-
-
- Name: PtrStat Type: FUNCTION
- Syntax: status = PtrStat(PtrNum)
-
- Where PtrInit intializes the printer, PtrStat returns the status
- of a designated printer in the form of 0, -1 so you can evaluate the
- printer status prior to a print function.
- Pass PtrStat the printer number to test (1-3) as a variable and
- the variable will be returned as 0 or -1 indicating the status.
-
- NOTE: When testing the status immediately after calling PtrInit,
- allow 1 or 2 seconds before calling PSTAT, this is to avoid polling
- the printer while it is still initializing. PtrStat will always
- indicate the printer online if a spooler is installed. Example:
- prtnum=1 ' printer to access
- CALL PtrInit(prtnum)
- CALL dly(2) ' wait for the low tech item to finish
- stat = PtrStat(prtnum)
- IF stat THEN
- ...perform print job ...
- END IF
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 60
-
-
-
-
-
-
- Name: QCalc& Type: FUNCTION
- Syntax: Result& = QCalc&(TRow, LCol, BodyAttr, ScrnAttr,_
- SpeedFactor)
-
- (QCalc is fully documented in MACRO17.DOC). TRow and LCol is the
- Top, Left corner of the calculator, Body and Scrn are the attributes
- for the calculator body and screen and SpeedFactor controls the type
- ahead, display and beep speed.
-
-
-
- Name: QBLoaded Type: FUNCTION
- Syntax: Result = QBLoaded
- QBLoaded may also be declared and invoked as QBL.
-
- This simply checks to see if the currently executing program is
- QB.EXE. The use for this is esoteric (although users of an old QB LIB
- collection that works differently in EXE form as in the QB Editor
- should LOVE this one!) but allows you to determine of the process
- executing in memory is an .EXE or a program image being executed by
- QB.EXE. Possible returns are:
- 0 QB Not loaded - EXE file executing
- 1 QB.EXE loaded
-
-
-
-
- Name: QPrint Type: SUB
- Syntax: CALL QPrint(text$, row, col, attr)
-
- This is a replacement for BASIC's native PRINT statement. While
- QB4 and later are much quicker than earlier versions, QPrint is still
- a bit quicker and allows for other features. Parameters:
- text$ - String to print
- row - Row of screen to print text to.
- col - Column of screen to print to
- attr - color attributes to use for the text. This is calculated in
- the same manner as the attribute is for Windows, ErrMsg etc
-
- Example:
- msg$="QPRINT is very, very FAST !!"
- CALL QuikPrt(msg$, 2, 2, MakeAttr(14,4))
- or directly,
- CALL QPRINT("QUIKPRT is very, very FAST !!", 2, 2, 78)
-
- Note the nested Function: MakeAttr nested within the CALL to
- QPRINT: BASIC will execute MakeAttr first and pass the RETURN to
- QPRINT - however if you are going to use and reuse the attribute, you
- should assign it to a variable.
-
-
-
- Name: RamFree Type: FUNCTION
- Syntax: ram = RamFree
-
- Returns the amount of memory installed in the machine.
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 61
-
-
-
-
-
-
-
- Name: ReadScrn Type: SUB
- Syntax: CALL ReadScrn(text$)
-
- This is like BASIC's SCREEN function except that it is a much
- faster (on an order of magnitude) way to read text from the screen.
- ReadScrn uses the current cursor location as the starting point and
- reads as many characters as you have spaces in the passed string.
- This is critical, since ASM routines cannot alter string lengths, if
- you want 13 characters, text$ must be initialized to SPACE$(13).
- Example:
- ScrnText$=SPACE$(15)
- LOCATE 12, 15
- CALL ReadScrn(scrntext$)
-
- Name: RepAttr Type: SUB
- Syntax: CALL RepAttr(OldAttr, NewAttr)
-
- Selectively replaces attributes on the video display. All occur-
- rences of OldAttr are replaced by NewAttr.
-
-
-
- Name: ReverseString Type: SUB
- Syntax: CALL ReverseString(s$)
- May also be invoked with the shorter name RevStr
-
- Reverses all characters in a string very quickly. When used in
- conjunction with XLATE, that can be a fairly good encryption system.
- Example:
- x$ = "PassWord"
- CALL RevStr(x$) ' returns as "droWssaP"
-
-
-
- Name: RINSTR Type: FUNCTION
- Syntax: position = RINSTR(test$, ch$)
-
- Returns the LAST occurrence of a character in a string. This
- works conversely to BASIC's INSTR, which returns the first occurrence,
- and is faster and much more code efficient than a loop to keep testing
- INSTR until the end of the string is reached. The character location
- however is still returned from the left. Note: RINSTR works only
- on character seeks, not on sub strings like INSTR does. That is, in
- the case of [j = RINSTR("ABCDEFG","A@B") ], RINSTR will only seek and
- match on "A", not "A@B". Multiple passes thru RINSTR, however seeking
- each successive character in a sub string could be accomplished.
- Example:
- DECLARE FUNCTION RINSTR%(searched$, seek$)
- ..
- test$="123456x890" : char$="x"
- l = RINSTR(test$, char$) ' returns 7
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 62
-
-
-
-
-
-
-
-
- Name: RTCDateSet/RTCDateGet Type: FUNCTION(s)
- Syntax: errc = RTCDateGet(mo, day, yr)
- errc = RTCDateSet(mo, day, yr)
-
- When running on an AT/286 system, this allows you to fetch or set
- the date held by the onboard Real Time Clock. While PC's can have
- battery maintained times, they tend to vary greatly from system to
- system as to how to access the data held within. For this reason,
- this will return an error code if the system is not a 286:
- -2 = System not an AT/286
- -1 = Time/Date update in progress (try again)
-
- See also RTCTimeGet/RTCTimeSet
-
-
-
- Name: RTCTimeSet/RTCTimeGet Type: FUNCTION(s)
- Syntax: errc = RTCTimeGet(hr, min, sec, hund)
- errc = RTCTimeSet(hr, min, sec, hund)
-
- AT/286 systems include an onboard battery maintained clock that
- maintains the time and date when the system is off. This routine will
- read or set the time portion held there. This can be handy to make
- sure that no one is trying to trick your application by resetting the
- DOS time (or date), by reading the time (or date) directly from CMOS.
- For additional info see RTCDateGet/RTCDateSet.
-
-
- Name: RunCmdL Type: SUB
- Syntax: CALL RunCmdL(cmd$)
- May also be called with RunCommandLine
-
- If you have ever used QB's RUN to execute another program, you
- know that it is impossible to change or alter the command line - until
- now. As is, QB passes the original PSP (Program Segment Prefix) which
- contains the environment and the command tail to these subsequent
- processes. RunCmdL basically alters COMMAND$ so that you can pass a
- new command tail to a RUN program. Simply pass RunCmdL whatever new
- COMMAND$ you want the RUN program to act on, and that RUN program will
- have a new COMMAND$. The maximum length is 128 characters. DOS may
- overwrite the first few characters of cmd$ with the filename to RUN,
- so be sure to pre pad it with enough spaces to compensate. To cancel
- a Command Tail, simply pass a single space more than that filename
- length. Example:
- cmd$ = " /C /1 foobar.dat COLOR" ' note leading spaces
- CALL RunCmdL(c$)
- RUN "Foobar"
-
- Note the leading spaces enough to allow FOOBAR to be overlayed
- plus one space as a separator. RunCmdL works in the QB environment as
- well as a EXE.
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 63
-
-
-
-
-
-
-
- Name: SaveScrn/RestScrn Type: SUB
- Syntax: CALL SaveScrn(SEG arry(x))
- CALL RestScrn(SEG arry(x))
-
- The SaveScrn routine saves the current screen display to an
- integer array then via RestScrn you can restore that saved screen to
- the display. This is very handy in a routine in situations where you
- might want to pop a help window to the display. You could save the
- current screen, display a help window or screen, then upon command
- redisplay the original screen. The GLIB implementation is very
- undemanding - the array which we save to and from can be DYNAMIC or
- STATIC, the Save and Restore screen functions will work with either
- type of array, and both in EXE files and from the QB environment.
-
- Additionally, Save/Rest Scrn not only recognizes extended video
- type (like VGA, EGA and MCGA), but video modes other than 80*25 are
- supported - if your VGA is in 80 * 43 mode, Save/Rest Scrn will see
- that and save 3440 character/attribute pairs rather than 2000 (be sure
- to allow for 3440 integers rather than 2000 in this case!). Example:
-
-
- DECLARE SUB SaveScrn(SEG Array%)
- DECLARE SUB RestScrn(SEG Array)
- ..
- ..
- REDIM ScrnArry(10000) ' enough for 5 (80 x 25) screens
-
- CALL SaveScrn(ScrArry(1)) ' save current screen to pos 1
- CALL RestScrn(ScrArry(4000)) ' restore from screen pos 3
-
-
- INTEGER variables can be used to point to the screen offsets:
-
-
- Scrn1 = 1 : Scrn2 = 2001 ' simple variable
- CONST SCRN3 = 4001, SCRN4 = 6001 ' constants work too!
-
- CALL SaveScrn(ScrArry(Scrn1)) ' save display to offset 1
- GOSUB DoHELP
- CALL RestScrn(ScrArry(SCRN4)) ' restore from offset 6001
-
-
- For more information, examine the demo source code, as these 2
- routines are used quite a bit. In the demo, a deliberate delay is
- used in some cases to slow down the save and restore process to allow
- you time to perceive some processes.
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 64
-
-
-
-
-
-
-
- Name: SaveWindow Type: SUB
- RestWindow
- Syntax: CALL SaveWindow(SEG arry(x), TR, LC, BR, LC)
- CALL RestWindow(SEG arry(x), TR, LC, BR, LC)
- These may be invoked with the shorter names SvWdw and RstWdw
-
-
- Where SaveScrn and RestScrn save and restore the entire screen
- (taking 4000 bytes of memory to do so), Save / RestWindow save and
- restore only a portion of the screen as might be needed to manage the
- section of the screen that will be altered from a window display.
- Since the size of the array required varies depending on the size of
- the window, use BuffCalc to calculate the precise size needed.
-
- Example:
-
- DECLARE SUB SaveWindow(SEG arry, TR, LC, BR, RC)
- DECLARE SUB RestWindow(SEG arry, TR, LC, BR, RC)
- ..
- ..
- ..
- CASE 17 ' Help function
- size = BuffCalc(1, 40, 20, 80)
- REDIM HelpWdw(size) ' get array size
- CALL SaveWindow(HelpWdw(1), 1, 40, 20, 80)
- ' save screen under wdw
-
- CALL HELP ' do help
- CALL RestWindow(HelpWdw(1), 1, 40, 20, 80)
- ..
- ..
- See SvScrn / RstScrn for general info on screen save techniques.
-
-
-
-
-
- Name: ScrlOn / ScrlOff Type: SUB
- Syntax: CALL ScrlOn
-
- Toggles the scroll lock key on or off. If the keyboard is eq-
- uipped with LED's, they are also toggled to the appropriate state.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 65
-
-
-
-
-
-
-
- Name: ScrnDump Type: FUNCTION
- Syntax: errc = ScrnDump(fhandle)
-
- Very simply, this reads thru video memory, removes the attribute
- byte and dumps the text to disk, adding a CR/LF pair every 80th
- character except on the last line. This is very fast and works with a
- DOS file handle - either open the file with FOPEN or use BASIC's
- FILEATTR to ascertain the handle from a BASIC fileno. If you use
- BASIC's "OPEN ... FOR", ScrnDump will respect the mode (OUTPUT or
- APPEND) and it would be VERY unlikely that any error occurs because
- the legitimacy of the file name would have been check by BASIC when
- OPENed.
-
- ScrnDump will return errc as 6 if the handle is not valid - the only
- likely error short of a disk error. Example:
- ff = FREEFILE ' get handle
- OPEN "scrndump.fil" FOR APPEND AS #ff ' open file
- fh = FILEATTR(ff,2) ' fileno => fhandle
- errc = ScrnDump(fh)
-
-
-
- Name: ScrnDumpB Type: FUNCTION
- Syntax: errc = ScrnDumpB(fhandle)
-
- This works very similar to ScrnDump, except that rather than
- dumping a text file, it leaves video memory in binary format. This is
- similar to the BSAVE function in BASIC except that the signature bytes
- are omitted and you can APPEND the screen image to an existing file.
- In so doing, you can basically make a binary screen library. Add-
- itionally some periodic bugs in BSAVE with DOS 2.0 and/or QB are
- avoided.
- Example:
- ff = FREEFILE ' get handle
- OPEN "scrndump.fil" FOR APPEND AS #ff ' open file
- fh = FILEATTR(ff,2) ' fileno => fhandle
- errc = ScrnDumpB(fh)
-
-
-
- Name: ScrnWash Type: SUB
- Syntax: CALL ScrnWash
- ScrnWash may also be called as MonoScrn
-
- ScrnWash removes the color from the screen display in order to
- make it suitable for a Monochrome or Composite system. ScrnWash
- converts colors 1 to 6 to 7 (white) and converts colors 9 to 14 to 15
- (hi int white). In effect, it washes the colors out to black, white
- and hi intensity white.
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 66
-
-
-
-
-
-
-
- Name: ScrollL/ScrollR Type: SUB
- Syntax: CALL ScrollL(Tr, Lc, Br, Rc, FillAttr, NumLines)
- Syntax: CALL ScrollR(Tr, Lc, Br, Rc, FillAttr, NumLines)
- These may also be called as ScrlLeft and ScrlRght
-
- This routine scrolls the entire screen or a portion of it left
- or right the designated number of lines. The scrolled or blanked
- portion of the screen is filled in with the designated attribute if
- the attribute value is 0 to 128. If the attribute value is -1, then
- the attribute is left unchanged. Example:
- CALL ScrlLeft(1, 1, 25, 80, -1, 4) ' scroll screen left 4 cols
- CALL ScrlRight(5, 5, 18, 60, 7, 15) ' scroll a window right 15 cols
-
-
-
- Name: ScrollUp / ScrollDn Type: SUB
- Syntax: CALL ScrollUp(TRow, LCol, BRow, RCol, attr, Num)
- CALL ScrollDn(TRow, LCol, BRow, RCol, attr, Num)
-
- These 2 routines scroll a portion (or all) of the current display
- up or down a user defined number of times. SCROLL allows for you to
- set the parameters for all four boundaries: top, bottom, left and
- right. Additionally, you designate the number of lines to scroll.
- Designating 0 as the number of lines to scroll, clears the screen.
- Parameters:
- Top, left, bottom and right, relate to the bounds of the area to
- scroll, attribute is the color to use to fill the portion of the
- screen affected, and Num is the number of lines to scroll. Example:
-
- num=12 : top=1 : lft=1 : bttm=12 : rght=79
- CALL ScrollDn(top, lft, bttm, rght, 112, num)
- ' scrolls lines 1 to 12 down 12 lines - lines 13 to 25
- ' are lost
-
- CALL ScrollUp(13, 1, 25, 79, 7, 12)
- ' scrolls lines 12 to 25 up 12 lines - with 13-25
- ' becoming blank.
-
- CALL ScrollD(1, 1, 25, 79, 7, 25)
- ' Clears the screen with the display scrolling down off
- ' the screen
-
-
-
- Name: SetDrv Type: SUB
- Syntax: CALL SetDrv(drv$)
-
- Sets or resets the default drive. To set the drive, simply pass
- it the letter, upper or lower case, to log into. This removes the
- ambiguity of drive numbers (Hmm, is drive 1 A: or B: in this case...).
- SetDrv returns nothing and if passed a bad parameter, DOS simply
- rejects it leaving the default drive unchanged. Example:
- drv$="d"
- CALL setdrv(drv$)
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 67
-
-
-
-
-
-
-
- Name: SetErrLvl Type: SUB
- Syntax: CALL SetErrLvl(ERRORLEVEL)
-
- Sets return code upon program termination. These can be read
- from DOS via as "ERRORLEVELs" in batch files. This routine should be
- called near the end of a program. It WILL NOT terminate your program,
- upon execution, but will merely change the QB RTL (Run Time Library)
- default return code ("ERRORLEVEL") so that when the program is ter-
- minated with END or SYSTEM, your redefined error level is used.
-
- Since this is an interrupt service routine, ie we take over the
- DOS interrupt function to terminate, it MUST NOT be called more than
- once in a program. Further, since there is no way to uninstall it, it
- should not be called from inside the environment - you should not
- revector interrupts without installing them before dropping to QB
- editor level. (This goes for NoBoot, Clock and DrvErr too, but they
- can be uninstalled!).
- Example 1:
- CALL SetErrLvl(code) ' terminate and set "ERRORLEVEL"
-
- Example 2:
- IF ErrCode THEN
- PRINT "ABEND"
- CALL SetErrLvl(ErrCode)
- ELSE
- PRINT "Normal Termination"
- SYSTEM
- END IF
-
-
-
-
- Name: ShareInst Type: FUNCTION
- Syntax: RetCode = ShareInst
-
- Returns a non zero value if SHARE is installed. This can be
- helpful at the start of a program in determining the type of file
- access to use.
- Example:
- IF ShareInst = 0 THEN
- PRINT "Sorry, this version requires SHARE.EXE be installed!"
- END IF
-
-
-
- Name: ShiftLeftI/ShiftRightI Type: FUNCTION
- Syntax: Result = ShiftLeftI(value, ShiftCount)
- Result = ShiftRightI(value, ShiftCount)
- These can also be called by the similar assembler instruction
- names ShlI and ShrI.
-
- This returns RESULT after the integer VALUE has been shifted left
- or right the number of times indicated in ShiftCount. Besides provid-
- ing a quick multiplication and division method, it is handy for bit
- operations such as isolating the date bits in a DATE word for in-
- stance.
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 68
-
-
-
-
-
-
-
- Name: ShutDown Type: SUB
- Syntax: CALL ShutDown(graphics)
-
- This parks any fixed disks in the system, shuts down the system
- and via if the graphics switch is set (non zero), a graphic display of
- the Big Red Switch is drawn center screen. HALT provides a more
- economical version of ShutDown by skipping the parking and picture.
-
-
-
- Name: Sleeper Type: SUB
- Syntax: CALL Sleeper(x)
-
- This works identically to BASIC's intrinsic SLEEP by waiting x
- secs for a keypress or, if x is set to zero it will wait forever for
- that keypress. Using SLEEP implicitly sets up an EVENT trap. That
- is, if you link your program with the NOEVENT.OBJ stub file, some
- versions of the compiler will cause your program will lock up or bomb
- out when it reaches the SLEEP statement because it needs the EVENT
- code that you stubbed out. Sleeper allows you to still link with NO-
- EVENT.OBJ and/or produce smaller code size by omitting all the event
- trapping code.
-
-
-
- Name: SpkrOn/SpkrOff Type: SUB
- Syntax: Call SpkrOn
- Call SpkrOff
- SpkrOn may also be called as SpeakerOn and SpkrOff as SpeakerOff
-
- These enable or disable the PC speaker. With the speaker toggled
- off, BASIC's SOUND statements will execute, but no sound will be
- emitted. Allowing for total program configuration, if the end user
- does not want sound, you can kill the speaker with one line of code:
-
- CALL SpkrOff
-
- rather then the following in hundreds of places in your code:
-
- IF SoundFXON THEN
- FOR x = 1 TO 8
- SOUND f, d
- NEXT x
- END IF
- Note that good programming practices would dictate that you
- restore the speaker state (SpkrOn) before your program terminates.
-
-
-
- Name: SpkrSnd Type: SUB
- Syntax: Call SpkrSnd(BYVAL freq, BYVAL dur)
- SpkrSnd may also be called as SpeakerSnd
-
- Emits a tome on the PC speaker of the specified frequency for the
- number of clock ticks specified by duration. The advantage to this
- over SOUND is that this adds less overhead and is slightly faster.
- Example: CALL SpkrSnd(750, 5) ' Equivalent to BEEP
-
- Copyright (C) InfoSoft, 1986-1990, 1991 69
-
-
-
-
-
-
-
-
- Name: Soundex/SoundexM Type: FUNCTION
- Syntax: code$ = Soundex(text$)
-
- The Soundex process is a fabulous algorithm developed by Michael
- Baldwin of AT&T Labs. Soundex allows you to convert English text,
- words or names to a fundamental code so that 'botl', 'bottel', 'btl'
- and 'bottle' (and several more misspellings and botched abbreviations)
- would all look alike to your code. In searching a large databases for
- a name, when using Soundex, the end user really only needs to know
- 'sort of' how it SOUNDS (not spelled)!
-
- To clarify what Soundex does, note that both CATSUP and KETCHUP
- return a similar Soundex code. This Soundex code is expressed as a 4
- character code in the form '?nnn' where '?' is the first letter of the
- word/name, and each 'n' is the balance of the encoded word or name.
- If the encoding does not take up all 3 characters the balance is
- filled with zeroes (eg: L300).
-
- One drawback is that names or words with foreign origins may not
- come back with logical Soundex codes: 'lummox' (a lazy oaf) returns
- the same code as 'Lemieux'. Now, Mr. Lemieux may indeed be an oaf,
- but the words do not sound at all alike.
-
- SoundexM is a modification to the Soundex routine that follows the
- conventional algorithm, but rather than being in "?nnn" format, it
- encodes the first character too. The advantage of this is that the
- code can then be made part of a file record and it takes up only 2
- bytes (INTEGER). Additionally, when searching large databases, with
- the first letter coded or quantified, record search and retrieval
- using binary searches and other fast hashing techniques can be used
- with great effect.
-
- Examples:
-
- Word Soundex SoundexM
- ----- ------- --------
- Catsup C321 2321
- Ketchup K321 2321
- Lemieux L520 4520
- Ohlemeyer O456 0456
- AirReturnFan A636 0636
- LLoyd L300 4300 **
- Ladd L300 4300 **
- ( ** many Soundex algorithms fail on these)
-
-
- I tend to use a combination of both Soundex and SoundexM: I store
- the Soundex code in files for fast compares, but also use LEFT$(x$, 1)
- or the first letter for alphabetical reference.
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 70
-
-
-
-
-
-
-
- Name: StatLine Type: FUNCTIONs
- (PrintStatL, CLX and SetBVLine are thoroughly covered in
- MACROxx.DOC).
-
-
-
-
- Name: StrLenMax/StrLeMin Type: FUNCTION(s)
- Syntax: Min = StrLenMax(BYVAL(VARPTR(Array$(x))), Quan)
- Max = StrLenMax(BYVAL(VARPTR(Array$(x))), Quan)
-
- Passed a string array, these will scan the array up to Quan number
- of elements (the whole array or just a portion), to find either the
- longest or shortest string length. This is much faster and more
- compact than fashioning loops in BASIC. Take care that the Quan
- parameter will not tell StrLen--- to scan beyond the limits of the
- array or invalid results will be returned.
-
- DECLARE FUNCTION StrLenMax(BYVAL ptr%, Quan%)
- ..
- ..
- REDIM Array$(125)
- ..
- ' this will scan elements 10 to 30 to find the longest string.
- MaxL = StrLenMax(VARPTR(Array$(10)), 20)
-
- ' this will scan the entire array to find the shortest string
- MinL = StrLenMin(VARPTR(Array$(1)), UBOUND(Array$))
- ' same thing
- MinL = StrLenMin(VARPTR(Array$(1)), 125)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 71
-
-
-
-
-
-
- Name: SubDirCount Type: FUNCTION
- Syntax: count = SubDirCount(mask$)
-
- Count the number of subdirectories matching a given mask. This
- counts the number of files with the directory attribute in the default
- directory. Note that while it is unusual, a directory CAN have an
- extension. Example:
- DirCnt = SubDirCount("*.*")
-
-
- Name: SubDirCH Type: FUNCTION
- Name: SubDirMK Type: FUNCTION
- Name: SubDirRM Type: FUNCTION
- Syntax: errc = SubDirCH(SubDirName$)
- errc = SubDirMK(SubDirName$)
- errc = SubDirRM(SubDirName$)
-
- Changes (SubDirCH), Makes (SubDirMK) or Removes (SubDirRM) the sub
- directory specified by SubDir$. The advantage over BASIC's native
- CHDIR is that if any error is encountered, rather than an error
- condition being forced on your code, an error code is returned. The
- return code is set (non zero) if an error is encountered.
-
-
-
-
- Name: SubDirExist Type: FUNCTION
- Syntax: RetCode = SubDirExist(mask$)
-
- Returns a non zero value if a given sub directory exists, and zero
- if it does not. Example:
- IF SubDirExists("QB45") THEN
- CHDIR "QB45"
- ELSE
- PRINT "No can do"
- END IF
-
-
-
- Name: SubDirGet Type: FUNCTION
- Syntax: CurDir$ = SubDirGet$
-
- Returns a string representing the current, default directory. .
-
-
-
- Name: SubDirList Type: FUNCTION
- Syntax: ErrCode = SubDirList(mask$, VARPTR(DirNames$(x)))
-
- SubDirList works almost identically to the function Dir, except it
- fetches filenames that bear the directory attribute into the string
- array. By passing a mask, it allows you to optionally get only those
- names that your program has created or controls; ie FooBar.EXE
- creates, gets and uses \FBData, \FBPrntr and \FBReports, so the mask
- would be \FB*.*. Also note that directories can have dots in the
- name.
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 72
-
-
-
-
-
-
-
- Name: SysTicks Type: FUNCTION
- Syntax: TicksSoFar& = SysTicks&
-
- SysTicks returns the number of clock ticks that have elapsed since
- midnight. This allows for an even finer resolution of time that
- SysTime or TIMER. Note that SysTicks returns a LONG integer.
-
-
-
- Name: SysTime Type: SUB
- Syntax: CALL SysTime(hrs, mins, secs, hund)
-
- Rather than tearing apart BASIC's TIME$ with MID$ to determine
- the current hour, minute, second, SysTime allows instant access to all
- that PLUS the hundredths of a second with no string garbage generated.
- Note that earlier clone BIOSes may not return hundredths of a second,
- so it may not be accurate on all systems.
-
-
-
-
- Name: TFRMAT Type: SUB (BASIC)
- Syntax: CALL TFrmat(nutime$, mode)
-
- TFRMAT allows for Time string formatting similar to that in
- DFRMAT. There is no error checking that a valid time is passed, but
- if the mode parameter is not set right, an error message of: " Invalid
- mode specified" will be returned in T$, also m will be set to 50. The
- parameter MODE controls the optional label - 0 = OFF / none, 1 =
- "am" / "pm" whichever is appropriate
- Example: Output:
- PRINT TIME$ 13:01:01
- CALL tfrmat(nutime$,1)
- PRINT nutime$ 1:01 pm
-
-
-
- Name: TimerToggle Type: SUB
- Syntax: CALL TimerToggle(TimerNum, Toggle)
-
- TimerToggle and TimerElapsed provide for an assembler based medium
- resolution set of timers. The granularity of these timers is approx-
- imately 976 milliseconds. These Timer---- functions allow for 5 dif-
- ferent time slots so that you can track several different processes.
- When invoking TimerToggle, TimerNum should be 1 to 5 indicating the
- timer to toggle (a number less than one or more than 5 should exit
- doing nothing.) The Toggle parameter indicates whether you are
- starting or stopping that timer: 0 HALTS or stops the timer, any other
- value starts it. If a given timer has already been started, issuing
- another START command for that timer causes the previous start time to
- be overwritten - that is a timer cannot be RE-started. See also
- TimerElapsed&.
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 73
-
-
-
-
-
-
-
-
-
- Name: TimerElapsed& Type: FUNCTION
- Syntax: ProcTime& = TimerElapsed&(TimerNum)
-
- Fetches the number of elapsed clock ticks since the specified
- timer was started. If the timer was never started, garbage is ret-
- urned. TimerNum refers to an integer 1 to 5 indicating which timer
- elapsed time is to be returned. TimerElapsed& returns a LONG INTEGER,
- so be sure to use the right data type. Also TimerElapsed& does not do
- an implicit timer stop function, it merely returns the difference of
- the start and stop ticks for that timer.
-
- Example:
-
- CALL TimerToggle(1,1) ' start timer one
- ..
- CALL TimerToggle(1,0) ' stop timer one
- ProcTime& = TimerElapsed&(1) ' get elapsed timer ticks
- ' into ProcTime&
-
-
-
-
-
-
-
-
-
- Name: TimeSquare Type: FUNCTION (BASIC)
- Syntax: KeyPress = TimeSquare(Msg$(), Row, Col, Attr, Cycles)
-
- This flashy little number provides a revolving display of messages
- from the array passed simulating the marquee/reader board found in
- Times Square, NYC. TimeSquare returns after Cycles number of complete
- displays have been completed or a key is pressed. Parameters:
- Msg$() - The string array of messages to display
- Row, Col - Row and column for the message(s) display
- Attr - Attribute for the message display
- Cycles - Determine the number of complete cycles for the
- collection of messages. If set to less than
- one, the complete set of messages is displayed at
- least one time before a keypress will interrupt it.
- If Cycles is negative and no key is ready after the
- first rotation, the display continues until
- ABS(cycles) have been displayed.
-
- TimeSquare requires QPrint, KeyReady and Delay18. Use
- Save/RestWindow to restore the section of screen disturbed by
- TimeSquare.
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 74
-
-
-
-
-
-
-
- Name: Translate Type: FUNCTION
- Syntax: errc = Translate(source$, table$)
- TRANSLATE can also be called by the name XLATE
-
- This will translate or substitute all characters in SOURCE$ from
- the list of characters in TABLE$ based on their ASCII value. Note
- that since this may be as high as 255, that TABLE$ should allow for
- all possibilities and be 256 characters long. This provides for an
- easy and configurable encryption scheme.
- Example:
- FOR x = 1 to 256
- Table$ = Table$ + CHR$(256 - x)
- NEXT x
- Serial$ = "123456"
- errc = Translate(Serial$, Table$)
- The result is that '1' becomes ASCII 206 because TABLE$ is the
- ASCII table backwards. So '1' is 49 and 255 - 32 = 206.
-
-
-
-
- Name: ValidDrv Type: FUNCTION
- Syntax: result = ValidDrv(drv$)
-
- ValidDrv tests a given character passed to see if it is possibly a
- valid drive character. The return is 0 or non zero indicating if the
- drive is valid and available. The spectacular thing about this
- function is that it returns LOGICAL, not just physical drives, so that
- if the DOS version is greater than 3.0, if SUBST or networking soft-
- ware are in use, ValidDrv will return correct information - this is
- done by accessing the IOCTL functions if DOS 3.0 or greater is active.
- The only possible non true return would be drive B: in which, the
- system recognizes A: as B: when only one floppy is installed.
-
- Example:
-
- DECLARE FUNCTION ValidDrv%(a$)
- ..
- ..
- FOR x = 1 TO 26
- PRINT CHR$(x+64);
- IF ValidDrv(CHR$(x+64)) THEN
- PRINT " is a valid, active drive letter."
- ELSE
- PRINT " is not a valid drive letter."
- END IF
- NEXT x
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 75
-
-
-
-
-
-
- Name: VerifyGet Type: FUNCTION
- Syntax: vflag = VerifyGet
-
- Returns the current VERIFY setting of the system. This is NOT
- a read-after-write test as some think, but is where DOS does a CRC
- check of data just written to make sure it is the same as that of the
- original data. To CHANGE the VERIFY switch, use VerifySet (qv). This
- routine returns 0 for OFF, non zero for ON.
-
-
-
- Name: VerifySet Type: SUB
- Syntax: CALL VerifySet(vflag)
-
- Sets or resets the DOS VERIFY switch (see GetVerify for an explan-
- ation of VERIFY). Note that if you intend to alter such a system
- switch, it is good programming practice to restore it to its original
- setting when your program terminates, this switch can be determined
- via VerifyGet. In calling VerifySet, 0 turns VERIFY OFF, 1 turns it
- ON. Example:
- CALL VerifyGet(0)
- CALL VerifySet(1)
-
-
-
- Name: VFName Type: FUNCTION
- Syntax: errc = VFName(fil$, DOSCode)
- VFName may also be called as ValidFileName
-
- VFNAME checks a string you pass it to determine if the string
- indeed is capable of being a valid filename. Pre testing a string
- that you may have gotten from end user input, helps avoid runtime
- errors later on and in the case of novice end users allows consid-
- erable feedback from your program on what is wrong with a filename
- typed in.
-
- The process is twofold - it tests for characters such as ,[><
- and also attempts to open the file and returns 2 error codes. In the
- case of the character test, the FUNCTION returns 0 (in errc) if it
- finds no offending characters, or the ASCII value of any invalid
- filename character. This allows you to be able to give apparently
- intuitive feedback to users on valid filename characters.
-
- A second pass is needed to test drive and path validity. The
- colon and backslash are not tested as invalid chars since they ARE
- valid IF in the right spot. To test this, VFNAME attempts to open or
- create the file thus returning info on the path, access and if the
- file already exists. Any DOS feedback is returned as the formal
- parameter DOSCode.
- 3 - Drive or path not found
- 4 - No handle available ("Too Many Files")
- 5 - Access denied (already opened on multi system)
- 80 - file exists.
-
- NOTES:
- 1) VFNAME does NOT actually create or open the file! It just
- pre-tests for any possible runtime error in trying to do so.
- 2) VFNAME requires DOS 3.x
-
- Copyright (C) InfoSoft, 1986-1990, 1991 76
-
-
-
-
-
-
-
-
-
- Name: VidInfo Type: SUB
- Syntax: CALL VidInfo(NumRows, NumCols, Mode, Page, PgSize)
-
- With the advent of the more advanced video subsystems, the pro-
- grammer can no longer make certain assumptions such as number of rows
- or columns. VidInfo attempts to return much of the information
- available on the current settings:
- NumRows - The number of rows in the current mode.
- NumCols - The number of video columns.
- Mode - The Video mode. This has little to do with the
- BASIC SCREEN statement - it is the DOS video mode.
- Page - The current active page.
- PgSize - The size in bytes of the active page.
- See also VidType, VTypeSet and VTypeClr
-
-
-
-
-
- Name: VidOff/VidOn Type: SUB
- Syntax: CALL VidOn
-
- Similar to a screen saver program, this routine will turn off
- any monitor (tested on CGA, EGA, MDA and VGA). If a timing loop in
- your long running program senses no activity for x minutes, a call to
- VIDOFF will turn off the display, then once you sense activity again,
- VIDON restores the display.
-
- Note: VidOn / VidOff will only toggle the video output on a VGA
- system equipped with both a VGA adapter AND a VGA monitor. Some
- 'super' VGA cards that can drive any monitor may not respond to this
- depending on what mode or type of emulation they are performing.
-
-
-
-
- Name: VidType Type: FUNCTION
- Syntax: crt = VidType
-
- No routine can tell you the type of display attcahed to a com-
- puter, but routines such as VidType CAN tell you the type of video
- display card installed. As such, VidType returns an integer code to
- identify the active video card and/or mode:
-
- 0 = MONO 4 = EGA Mono 8 = VGA Mono
- 1 = Herc, Herc Plus 5 = EGA Color 9 = VGA Color
- 2 = Herc Incolor 6 = MCGA Mono
- 3 = CGA 7 = MCGA Color
-
- Note that on multiple display systems, the active display is
- identified on EGA/VGA systems, while the primary one is identified on
- CGA/Mono multiple display systems. Also, some "Super VGA" cards
- connected to Multi Synch monitors, may identify the Multi Sych system
- as an EGA. This is dependant on the BIOS compatibility of the card.
- See also VTypeSet and VTypeClr
-
- Copyright (C) InfoSoft, 1986-1990, 1991 77
-
-
-
-
-
-
-
-
-
- Name: VidPageCsr Type: SUB
- Syntax: CALL VidPageCsr(page, row, col)
-
- This fetches the correct row, column coordinates for a requested
- video page. No error checking is done for a VALID page, but when
- called from a loop, it can quickly fetch the cursor location for any
- and all pages. Example: Get Cursor locations into array
- FOR x = 1 to MaxPages
- CALL VidPageCsr(x, Csr(x,1), Csr(x,2) )
- NEXT x
-
-
-
- Name: VLabelGet/VLabelSet Type: FUNCTION
- Syntax: MyLabel$ = VLabelGet$
- errc = VLabelSet(NewVLabel$)
-
- Allows you to get or set the disk volume label. The maximum size
- allowed for a label is 11 characters. VLabelSet will only use the
- first 11 of whatever you pass (pass SPACE$(11) to clear the name). A
- return code of -1 indicates and error.
-
-
-
-
- Name: VTypeSet/VTypeClr Type: FUNCTION and SUB
- Syntax: errc = VTypeSet(ColorType, TraceFlag) (Function)
- CALL VTypeClr (SUB)
-
- These sub programs allow you to override or tailor the video sub
- system detection code used internally by virtually all of the GLib
- video routines (Painter, Windows, Boxes, QPrint etc). At times it may
- be desirable override the default systems detected. For example a
- very high quality CGA may not need video retrace performed (ie 'snow
- removal'), VTypeSet would allow you to instruct most all video sub
- programs to skip such retrace checking. Of course, in this case,
- there is no way for your code to tell if the snow removal is needed
- without asking the end user.
- Another example is in odd video cards such as a "CGA Emulator":
- in using VTypeSet, you can force output to the MONO or COLOR video
- segments as need by these. Finally, the very high-res EGA cards used
- on early Model 80's for ACAD and such _are_ color systems, yet they
- return a code indicating a MONO sub system (on purpose I am told).
- Using VTypeSet allows you to force output to the color segment.
-
- Parameters:
-
- ColorType: 0 causes output to the Mono video segment;
- 1 forces output to the color segment
- Any other value causes an error to be returned.
- TraceFlag: 0 eliminates video retrace checking ("snow removal")
- 1 forces it to be used regardless of the video sub system
-
- See Note below
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 78
-
-
-
-
-
-
-
- VTypeClr clears the overrides that you set with VTypeSet and
- instructs GLib video sub programs to act based on the video sub system
- detected by it's internal detection routines.
-
- Notes:
- 1.) Since VTypeSet overrides the defaults, no error or integrity
- checking performed. Setting the TraceFlag (1) and the ColorType
- to MONO (0) may hang the system for a variety of reasons. The
- TraceFlag should only be set when the ColorType is set to Color
- (1) _AND_ there is indeed a color subsystem installed and
- active. Setting the TraceFlag with a EGA or VGA system will
- cause it to hang as there is never a high or low return from the
- retrace port - it is non-existant!
-
-
- 2.) Wise use of this can also be used to slow down the grow effect
- of WINDOWS and possibly provide a method of adjusting the GROW
- factor. By setting the TraceFlag to 1 (on CGA systems) and
- forcing video retrace, just the right amount of delay may be
- added to the growing of the WINDOWS.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 79
-
-
-
-
-
-
-
- Name: Windows Type: SUB
- Syntax: CALL Windows(TR, LC, BR, RC, SFX, Grow, Frame, Attr,_
- label$)
-
- An extensive windowing routine, allows you to fully control
- frames, sound, color and grow effect. The routine requires numerous
- arguments passed. Be warned that NO error checking takes place as to
- accurate or misplaced coordinates - really far out coordinates can
- lock up the machine (such as locating the bottom of the window ABOVE
- the top etc...).
- Frames: WINDOWS comes with virtually an unlimited number of frame
- styles with the five most common 'built in':
- 0 - Spaces used / no frame
- 1 - Double Lines Horizontal / Double Lines Vertical
- 2 - Double Lines Horizontal / Single Lines Vertical
- 3 - Single Lines Horizontal / Single Lines Vertical
- 4 - Single Lines Horizontal / Double Lines Vertical
-
- Invoking WINDOWS with the frame style set to 5 tells WINDOWS
- to use the user defined character set for the frame as defined
- by the WSetUDef sub program (qv). An unrecognized frame style
- code such as anything over 5 or 5 if there is no user defined
- frame style defined, will default to type 0 - spaces/no frame.
-
- Grow: By setting the GROW parameter to ZERO, the window simply
- appears on the screen. Non Zero indicates you want a growing
- effect and controls the grow speed: the larger the number, the
- slower the growing. Other grow effect factors:
- o Video Sub system: This is more a factor than the CPU
- type or speed: A 25 MHz 386 with a CGA will need about
- the same grow factor as a 6 Mhz 286 and a 8088 PC also
- with a CGA will require a similar GROW factor, more so
- than if it has a VGA.
- o WINDOW Size and Shape. A tall, but narrow window
- may need a different delay value than a very wide but
- short one.
- o Each increment of one invokes a delay of 1 clock tick.
- This may not sound like much, and indeed in the grand
- scheme of things it is not, but in the context of 18 to
- 24 redrawings of a window it can be a lot. Our testing
- on VGA and fast 286 systems showed that GROW factor
- values of 1, 2 and 3 were plenty to slow down the delay
- a speed at which it can be perceived. Too long of a
- delay makes the CHIRP sound incongruent and the growing
- look 'funny'.
-
- Other Parameters:
- TR - Top row of window to be displayed.
- LC - Left border of window to be displayed.
- BR - Bottom row of window to be displayed.
- RC - Right border of window.
- SFX - Sound effects toggle, 0=OFF 1=ON
- Grow - Grow switch, 0 = No grow, Non Zero = Grow Speed
- Frame - Style of frame to use for the window
- Attr - Attribute of window (See also MakeAttr)
- Label$- Label to center across the top of the window, for no label
- use ""
-
- Copyright (C) InfoSoft, 1986-1990, 1991 80
-
-
-
-
-
-
-
- Example:
- tr=2 : lc=2
- br=5 : rc=79
- sfx=1 : gro=1 : frame=1
- attr=78
- label$=" A long window across the top of the screen "
-
- CALL Windows(tr, lc, br, rc, sfx, gro, frame, attr, l$)
- or
- CALL windows(2, 2, 5, 45, 0, 1, 4, 64, "")
- Puts a window to the screen from 2,2 to 5,79, with a chirp sound
- effect, with a double / double line frame with a yellow foreground on
- a red background.
-
- Other sub programs that control or add to WINDOWS or can be used
- with it include: WShadow, MakeAttr, Chirp, BufCalc, VTypeSet and
- SaveScrn
-
-
-
-
- Name: WSetUDef Type: SUB
- Syntax: CALL WSetUdef(TL, TR, BL, BR, VChar, HChar)
-
- WINDOWS has 5 built in, or default frame styles, however in cer-
- tain situations, you may want to define your own via WSetUDef. Once
- defined they may be used over and over; that is, you need not call
- WSetUDef over and over to set the same User Defined frame style for
- each call to WINDOWS. The User Defined type can be changed later with
- another call to WSetUDef. The parameters sent to WSetUDef are in-
- tegers representing the ASCII value of the character to use for the
- Top Left corner, Top Right corner, Bottom Left corner, Bottom Right
- corner, Vertical character and Horizontal character respectively.
-
- Example:
- ' Set Window frames to "?"
- CALL WSetUDef(63, 63, 63, 63, 63, 63)
- ..
- ..
- ' make growing window, with no sound with "?????" frame style
- CALL Windows(5, 5, 18, 45, 0, 1, 5, 78, " Test ")
-
-
- ' change user defined box characters to 'test' on frame style
- ' (+-|):
- CALL WsetUDef(43, 43, 43, 43, 124, 45)
- ..
- ..
- CALL Windows(5, 5, 18, 45, 0, 1, 5, 78, "Text")
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 81
-
-
-
-
-
-
-
- Name: WShadow Type: SUB
- Syntax: CALL WShadow(Flag)
-
- This sets a global flag to indicate to the Windows routine whether
- or not it is to draw the window with a shadow or '3-D' effect around
- it. By 'global', we mean all future calls to Windows, whether from
- your main code module or from inside a sub, will respect the setting
- of the flag.
-
- By making this shadowing effect a separate call, we avoid adding a
- parameter to the Window call that invalidates thousands of lines of
- code that are already written as documented above. Shadow Parameter:
- 0 = Off - no shadowing
- 1 = Shadowing ON - Place shadow on bottom and right side
- of window.
- -1 = Shadowing ON - Place shadow on bottom and left side of
- window.
-
- This shadow effect basically washes out the underlying colors - not a
- simple string of spaces in color 0 that others will try to tell you is
- a shadow. If you hold a paper half-in and half-out of a shadow, you
- can still see the portion in the shade - just the tones and hues
- change!
-
- The size of the window frame is unaffected by WShadow, but one
- more screen row and one more column is altered, and should be taken
- into consideration when saving a portion of the screen (ie:
- SaveWindow).
-
- Once set, the shadow is automatically displayed with every sub-
- sequent call to Windows. If you always use a shadow and want it on
- the right, 'CALL WShadow(1)' is all you need to add to your code - all
- Window calls after that will have a shadow on the right.
-
- Thru the course of your program, WShadow can be changed to move
- the shadow to the other side or halt it and reactivate it, but only
- future calls to Windows are affected.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 82
-
-
-
-
-
-
-
- Acknowledgements
-
- Advanced MS DOS Programming, MS-DOS Functions and IBM ROM BIOS
- all by Ray Duncan
-
- Norton Guides For Assembler
-
- Programmers Guide to PC and PS/2 Video Systems by Richard Wilton
-
- Programming Problem Solver Handbook by Robert Jordain
-
- Assembly Language Subroutines by Leo J Scanlon
-
- Interrupt List - A file of undocumented or poorly documented
- interrupts found on BBSes everywhere.
-
- MS-DOS Encyclopedia published by Microsoft Press, edited by
- Ray Duncan
-
- System BIOS for IBM PC/XT/AT computers and compatibles
- by Phoenix Technologies
-
-
- The basic timekeeping function and framework of CLOCK is based on
- CLOCK.ASM PC Magazine Vol 6 No 17. Our enhancements include the 12
- hour display format, label, secondary timing loop to adjust the
- accuracy and the tone that sounds on the hour and half hour.
-
- QCALC is based on a Floating Point Calculator in 'C' (author
- unknown) and CALC.COM (A TSR pop up calculator) from Vol 7 No 6 of PC
- Magazine. Our modifications include making it locatable, the display
- appearance, the blinking buttons and speed parameter, and making it
- callable from "C" or "QB" and returning a long
- integer to either.
-
- Finally, if you are interested in ASM level programming or just
- plain tinkering, the Microsoft KnowledgeBase is invaluable. When many
- of the normal interface items changed in QB4, they are not completely
- covered in the Mixed Language Programming Guide, but many extended
- explanations and examples are in the KnowledgeBase. Information for
- passing Fixed Length String arrays as well as string arrays to ASM
- routines that is radically different in QB4 and QBX (BASIC PDS), for
- instance, that made DirA and DIRF possible came from there.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Copyright (C) InfoSoft, 1986-1990, 1991 83
-
-
-