INTRODUCTION

Btv.pas is a fully object oriented Turbo Pascal 6.0,7.0 programming interface
for Novell's Btrieve database manager. Through OOP techniques Btv.pas greatly
simplifies the interface to Btrieve for Turbo Pascal programs. Included in
this package are full working examples that demonstrate the ease and power of
the BTV interface. Also included is a complete application for recovering
damaged files.

Just a few of the features are :

 * Over 40 functions for Btrieve
 * Create, easy file definition and creation
 * Clone, create an empty copy of a file
 * Recover, recover records from a damaged file
 * Save, save all records to a DOS file compatible with BUTIL
 * Load, read records from a file created by Save or BUTIL
 * Create Supplemental Indexes
 * Supports multiple and segmented keys
 * Supports alternate collating sequences
 * Supports variable length records
 * Automatic padding and justification of string keys
 * Supports full transaction processing
 * Supports full network record and file locking
 * Automatic integrated error handling
 * Supports DOS, Windows, and Protected Mode programs
 * Encapsulates extended operations


In writing this documentation I have assumed the reader is knowledgeable
about the workings of Btrieve and the basics of object oriented programming
in Turbo Pascal. This document is not meant to explain or serve as a tutorial
on either of these subjects. I think you will find the source code itself
fairly well documented. I strongly recommend that you look it over. If you
have any questions, suggestions for improvement, or problems, please do not
hesitate to contact me.

Richard Hansen
PO Box 18571
Saint Paul, MN  55118-0571  USA

CompuServe  : 70242,3367
Internet    : 70242.3367@compuserve.com
Fido Net    : 1:282/115

If you need more information on Btrieve, you may want to get a copy of the
following book:

  "The Ilustrated Guide to Btrieve"

  ISBN 0-9623397-7-6
  MIDI America
  2103 N. Decatur Rd., Suite 160
  Decatur, GA  30033  USA
  (404) 634-3334


Btv.pas Copyright 1992  Richard W. Hansen, all rights reserved.
Btrieve Copyright Novell, Inc.
Butil Copyright Novell, Inc.


DEFINITION OF SHAREWARE

Shareware distribution gives users a chance to try software before buying it.
If you try a Shareware program and continue using it, you are expected to
register. Individual programs differ on details -- some request registration
while others require it, some specify a maximum trial period. With
registration, you get anything from the simple right to continue using the
software to an updated program with printed manual.

Copyright laws apply to both Shareware and commercial software, and the
copyright holder retains all rights, with a few specific exceptions as stated
below. Shareware authors are accomplished programmers, just like commercial
authors, and the programs are of comparable quality. (In both cases, there
are good programs and bad ones!) The main difference is in the method of
distribution. The author specifically grants the right to copy and distribute
the software, either to all and sundry or to a specific group. For example,
some authors require written permission before a commercial disk vendor may
copy their Shareware.

Shareware is a distribution method, not a type of software. You should find
software that suits your needs and pocketbook, whether it's commercial or
Shareware. The Shareware system makes fitting your needs easier, because you
can try before you buy. And because the overhead is low, prices are low also.
Shareware has the ultimate money-back guarantee -- if you don't use the
product, you don't pay for it.


DISCLAIMER - AGREEMENT

Users of Btv.pas must accept this disclaimer of warranty:  "Btv.pas is
supplied as is. The author disclaims all warranties, expressed or implied,
including, without limitation, the warranties of merchantability and of
fitness for any purpose. The author assumes no liability for damages, direct
or consequential, which may result from the use of Btv.pas."

Btv.pas is "shareware" and is provided at no charge to the user for
evaluation. Feel free to share it with your friends, but do not give it away
altered or as part of any other source code package. If you find this source
code useful and continue to use Btv.pas after a reasonable trial period, you
must register it. The registration fee will license one copy for use on any
one computer at any one time. You must treat this software just like a book.
An example is that this software may be used by any number of people and may
be freely moved from one computer location to another, so long as there is no
possibility of it being used at one location while it's being used at
another. Just as a book cannot be read by two different persons at the same
time.

Commercial users of Btv.pas must register and pay for their copies of Btv.pas
within 30 days of first use or their license is withdrawn. You may use
Btv.pas in your software projects, but you may only distribute it in
executable form. No royalties are required for programs you develop using
licensed copies of Btv.pas.

Anyone distributing Btv.pas for any kind of remuneration must first contact
Richard Hansen for authorization. This authorization will be automatically
granted to distributors recognized by the ASP as adhering to its guidelines
for shareware distributors, and such distributors may begin offering Btv.pas
immediately (However Richard Hansen must still be advised so that the
distributor can be kept up-to-date with the latest version of Btv.pas.).


REGISTRATION

You may register by check, money order, credit card, or online on the
CompuServe information service. All registrations are $50.00 plus $5.00
shipping and handling. Registered users get the latest version, printed
documentation, full source for all BTV.PAS units, and the full version of 
the Btrieve message file "BTRIEVE.MSG" that contains all Btrieve error
and operation code messages.

Checks or money orders are prefered. If paying in U.S. dollars, the check
must be drawn on a drawn on a U.S. bank.

You can also register online on CompuServe. Type GO SWREG, and follow the
prompts. The Registration Id for CompuServe is 759. All Compuserve
registrations are $55.00, including shipping and handling.

You may place an order by Master Card, VISA, American Express, or Discover by
contacting Public Software Library at (800) 242-4PSL (from overseas
(713) 524-6394), by FAX at (713) 524-6398, or on CompuServe at 71355,470.
These numbers are for credit card orders only! Please, do not call these
numbers for any type of technical assistance. The Registration Id for PSL is
10905. All PSL registrations are $55.00, including shipping and handling.

Site licenses and multiple copy discounts are available. Remember a
registered copy is required for each programmer using BTV.PAS.

Please contact me with any comments, suggestions, problems, bugs, or
questions.

Richard Hansen
PO Box 18571
Saint Paul, MN  55118-0571  USA

CompuServe : 70242,3367
InterNet   : 70242.3367@compuserve.com
FidoNet    : 1:282/115


OVERVIEW

There are three objects that make up the BTV OOP interface to Btrieve. The
most important of these is the BtrieveFile object. BtrieveFile contains all
the routines for opening and creating files, reading, writing and deleting
records, etc. BtrieveFile contains a pointer to a data buffer that can be
automatically allocated and deallocated by the object if you desire.

Next, is the ErrorHandler object, this object controls error handling for the
file. Most  Btrieve error may be turned on or off for trapping by the error
handler object (Note: With the release of the Windows version of Btrieve, all
errors will longer fit in a set of 0..255). This frees you from the need to
check for errors after each operation, but still allows for full error
processing. Each file object has a pointer to an error handler, this error
handler can be the same or different for each file you open. If an error is
turned on the error handler will call an error display routine, and based on
a return code from it, will continue, abort, or retry an operation.

Last, there is the DisplayObject. This object handles the display of any
errors encountered. It is called by the error handler, and returns an action
code, possibly based on some user response, to the error handler. This action
code will cause the error handler to either abort the program, retry the
operation, or continue processing.

Target Platform

IMPORTANT PLEASE NOTE!!!!!

BTV.PAS is compatible with DOS, Windows, and protected mode programs. Your
code should compile without changes, at least for Btrieve access, for any of
the three targets. All necessary compilation changes are handled by IFDEF
conditional compilation directives in the source code. The IFDEFs work in
conjunction with the standard Borland Pascal conditional symbols of VER70,
MSDOS, WINDOWS, and DPMI. You do not need to define any of these symbols.

With Borland Pascal 7.0, for future compatibility, you may want to replace
the DOS unit with the WINDOS unit.

There is a small problem with the protected mode version. BTV.PAS compiles
but does not run correctly under the 7.0 release, dated 10/27/92. BTV.PAS
does, however, compile and run fine under the 7.01 maintenance release, dated
03/09/93. The 7.01 update is available from Borland International for $10.00.
Please contact Borland International for more details.

Declarations

const
  bOpen = 0;

  bGetKey = 50;

These constants define all the available Btrieve operations.

  bOkay = 0;
  ...
  bLastError = bInternalTTSerr;

These define all the status codes returned by Btrieve. In addition there are
constants for file open modes, locking, key types, file flags, etc.

  MaxSegments = 24;

Defines the maximum total number of key segments allowed for file. If none of
your files will ever have this many segments then redefine it to some smaller
size and save a few bytes of memory.

  MaxBuffSize   : Word = 16 * 1024;

This initialized variable defines the maximum size that will be automatically
allocated for a file data buffer. There is no need to redefine this if you
are using fixed length records, since only as much memory as needed will
actually be allocated. If you are using variable length records and are sure
they will be smaller than 16K bytes, then you can redefine this as needed
before opening the file.

{.$DEFINE BCHECK}

If this compiler directive is defined, a check for Btrieve will be made
during program initialization. If the record manager is not present the
program will be halted.

{.$DEFINE BTRIEVE50}

Define this to make all opcodes new to Btrieve version 5.0 available.

type
  PProgress = ^TProgress;
  TProgress = Object
    Constructor Init;
    Procedure Display(Count : LongInt); Virtual;
  end;

Defines an object with a method to display the progress of Recover, Load and
Save operations.  Count is the current record count, the display routine will
be called every ten records.

  AllErrors = bInvalidOp..bLastError;
  ErrorSet = Set of AllErrors;

These two define a set of most possible Btrieve errors. Note: With the
introduction of Btrieve for Windows, some status codes are greater than 255,
and will not fit in the normal error set.

  ErrorAction = (erAbort, erDone, erRetry);

Enumerates the possible responses to a Btrieve error. One of these three
actions must be returned by your error display routine. If erAbort is
returned the program will be halted, if erDone is returned the program will
continue, if erRetry is returned the Btrieve operation that generated the
error will be executed again.

  PErrorDisplay = ^ErrorDisplay;
  ErrorDisplay  = Object
    Constructor Init;
    Destructor Done; Virtual;
    Function Display(Error : Integer; ErrorMsg : String; OpCode : Integer;
                  OpCodeMsg : String; FileName  : PathStr ): ErrorAction;
                  Virtual;
  end;

ErrorDisplay is the object that will display errors to the user. This is an
ABSTRACT object and can never be used as is, you must define a descendant
object that does what you want in each program. The error handler will pass
an error number, error description, operation, operation description, and the
full file path to your object. Your object should display the error and
return an action code. This action code can be based on user input, or the
type of error and operation.

  PErrorHandler = ^ErrorHandler;
  ErrorHandler  = Object
    RetryCount : Word;
    MaxRetry : Word;
    RetryDelay : Word;
    TrappedErrors : ErrorSet;
    ErrDisplay : PErrorDisplay;
    ErrorsON : Boolean;

    Constructor Init(DisplayObject : PErrorDisplay);
    Destructor Done; Virtual;
    Procedure AddErrors(ErrorCodes : ErrorSet);
    Procedure ClearRetry;
    Function ErrorDispacther(ErrorCode : Integer; OpCode : Integer;
                        FileName : PathStr): ErrorAction; Virtual;
    Function Error(Status : Integer; OpCode : Byte;
                  FileName : PathStr): Boolean; Virtual;
    Function ErrorMsg(ErrorCode : Integer): String; Virtual;
    Procedure ErrorsOnOff(State : Boolean);
    Function GetDelay: Word;
    Procedure GetErrors(var ErrorCodes : ErrorSet);
    Function GetMaxRetry: Word;
    Function OpMsg(OpCode : Integer): String; Virtual;
    Procedure RemoveErrors(ErrorCodes : ErrorSet);
    Procedure SetDelay(Seconds : Word);
    Procedure SetErrors(ErrorCodes : ErrorSet);
    Procedure SetMaxRetry(Retry : Word);
  end;

This is the error handler object used to trap Btrieve errors. It can be used
as defined, but returns minimal error messages. Most errors can be set to be
trapped or not by the error handler. By default all errors except end of file
are trapped. All trapped errors will be routed through the error display
object assigned to the handler when it is initialized. Untrapped errors must
be handled directly in your program code.

NOTE: With the introduction of Btrieve for Windows, some status codes are
greater than 255, and will not fit in the error set. Since they cannot be
toggled singly, you should call ErrorsOnOff to remove error trapping for
those errors greater than 255.

ErrorHandler is the parent object for the DefErrorHandler and
DiskErrorHandler objects.  DefErrorHandler holds all error messages in
memory, while DiskErrorHandler keeps them in a Btrieve file. Normally, you
would want to use either a DefErrorHandler or DiskErrorHandler to have
descriptive error messages.

Locking errors (record in use, file in use) are a special case. These errors,
which happen only on networked systems, automatically cause the operation to
be retried a preset number of times. No error will be generated until the
maximum number of retries, set by you, have been attempted. This feature can
save some programming work on your part if you are writing an application
that uses the networked version of Btrieve.

If this all sounds complicated, don't worry, it really isn't that bad. Please
take a look at the example code to see how easy it is to setup the error
handling. My feelings on error checking are that the more automatic it is the
better. In Btv.pas a little work up front leads to considerably less coding
later. You only need to do this stuff once, no matter how many files you
open. Once you get the error handling setup, you can pretty much forget about
it in the rest of your program. It gets even easier if you create a standard
error handling Unit and reuse it in all your programs.

  PBtrieveFile = ^BtrieveFile;

The BtrieveFile object is the heart of Btv.pas. It contains all the routines
for manipulating Btrieve files. It is a fairly complex object; but, it
greatly simplifies your interaction with Btrieve files.

You will create one of these objects for each file you want to access in a
program. To open a file, you execute two object methods. First, you init the
object passing a file path, an error handler (can be nil), and a pointer to a
data buffer and the data buffer size. Any number of files can share a single
error handler. If you pass a nil pointer for the data buffer, a buffer will
be allocated for you. Next, you call Open with an open mode (Read Only,
Exclusive, or Accelerated ) and file owner name.

Creating a file is almost as easy. Init is called the same as for Open. Next,
for each key segment needed, you execute the AddKeySegment method passing the
key position, size, key type, etc. This will define each key segment you need
for the file.

After all keys are defined make a call to Create. This method takes the file
flags, record size, page size, etc. as parameters and Creates a new file.
Create does not open the file, so finish off with a call to the Open method.

Reading and writing records is just as simple. For a read by key you must
first make a call to MakeKey, to build the key buffer. Then call Get,
supplying the opcode for the type of read you want and the locking state. The
data will be passed back in the file buffer setup on initialization.  For the
step operation you just call Get passing the correct opcode.

If you want to maintain your own key buffer, you can do that too. After
initializing the file, but before opening it, add your external key buffer by
calling AddKeyBuffer. Once you call AddKeyBuffer, no calls to MakeKey are
needed and none should be made. Before a key read, you just fill your key
buffer as needed and call Get.

To write a new record, fill the buffer you setup and execute the Insert
method. To change a record, first read it with a call to Get. Make any
changes to the buffer and call Update.

  Procedure CheckForBtrieve;

This global system level procedure can be called to check for the presence of
Btrieve. It halts the program if Btrieve is not loaded. This is the same
routine called during program initialization, if that feature is enabled (if
BCHECK is defined).

  GetBtrieveVersion(..);

Is a global system level procedure for determining the Btrieve version number.

  UnloadBtrieve;

This is another global system level procedure. It can be called to unload the
Btrieve Record Manager. Like the other global procedures, it can be called
without creating a BtrieveFileObject.


BtrieveFile OBJECT
==============================================================================
This is the main object in BTV.PAS. It is a fully fuctional Btrieve file
object. BtrieveFile is the parent object for XBtrieveFile, which handles
Btrieve extended IO operations.


Fields
------------------------------------------------------------------------------
AllocateData      AllocateData : Boolean;

This field is set by Init and used by Open and Done. If the data buffer
pointer passed to Init is nil, AllocateData is set to TRUE and file buffer
memory will be automatically allocated and deallocated.

AllocateKey     AllocateKey : Boolean;

This field is set to TRUE by Init and used by Open and Done. If the
AddKeyBuffer method is called AllocateKey is set to FALSE and key buffer
memory will not be automatically allocated and deallocated.

AltPath         AltPath : PathStr;

Holds the name and path of an alternate collating sequence for the file.

BytesRead       BytesRead : Word;

Is the number of bytes input from the file on the last read operation.

BytesToWrite      BytesToWrite: Word;

Holds the number of bytes in the buffer that will be output to the file on
the next write operation. For fixed length records it defaults to the size of
the file record and should not be changed. For variable length records it
should be set before each record is written. You set the BytesToWrite by
calling SetOutputSize.

CurIndex          Index : Word;

CurIndex is the current Key number (access path) used for the reads and
writes.

CurrentKeySize    CurrentKeySize : Byte;

Used internally to find the largest key.

Data              Data : Pointer;

Points to the file buffer.

DataSize          DataSize : Word;

DataSize is the size of the file buffer pointed to by Data.

ErrHandler        ErrHandler : PErrorHandler;

A pointer to the ErrorHandler object that will control all error checking.
If ErrHandler is nil no error checking is done.

FileOpen          FileOpen : Boolean;

Will be set to TRUE if the file is opened successfully.

FillValue   FillValue   : Byte;

FillValue is the value used to fill the data and key buffers in the
ClearBuffer and ClearKey methods.

IndexCount        IndexCnt : Byte;

Number of keys in the file.

Key             Key : Pointer;

Points to the file key buffer.

KeyList         KeyList : KeyDefArray;

Holds a definition record for each key segment in the file.

KeySize         KeySize : Byte;

Size of the key buffer pointed to by KeySize.

KeyStart          KeyStart : Array[0..MaxSegments - 1] of Byte;

Holds a list of the offsets of the first segment of each key.

Path              Path : PathStr;

Path contains the name and path of the file.

PosBlock          PosBlock : Array[1..PosBlockSize] of Byte;

The Btrieve position block.

ReadKeyDefs     ReadKeyDefs : Boolean;

Indicates whether the key definitions have been setup manually or should be
read from the file.

SegmentCnt      SegmentCnt : Byte;

The total number of segments in all keys.

Status            Status : Integer;

The status of the last Btrieve operation.

VariableLen       VariableLen : Boolean;

Set to TRUE if the file holds variable length records.

SISegments      SISegments : Byte;

Used in setting up a supplemental index.


Methods
------------------------------------------------------------------------------
Init              Constructor Init(FilePath : PathStr;
                                   var ErrorObject : PErrorHandler;
                                   DataBuf : Pointer; DataBufSize : Word);

Initializes the file name and path, sets the pointer to the error handler
object. If ErrorObject is nil no error checking is done, it is all up to the
programmer in this case.

If DataBuf is nil, then AllocateData is set to TRUE and memory for the file
buffer will be allocated and deallocated automatically. The size of the data
buffer allocated, depends on whether or not the file has variable length
records. If the file has fixed length records, the data buffer is allocated
to the exact size of the records in the file.  If the file has variable
length records, the data buffer is allocated to the value of the MaxBuffSize
variable stored in the file BTVCONST.PAS.

If DataBuf is not nil, then DataBufSize must be the size of the buffer
pointed to by DataBuf. DataBuffSize must also be large enough to hold the
largest record in the file, whether the file has fixed or variable length
records.

See Open, Create, Done, ErrorHandler object.

Done            Destructor Done; Virtual;

If AllocateKey is TRUE, disposes of key buffer memory. If AllocateData is
TRUE, disposes of the data buffer memory.

See Init

AbortTransaction    Procedure AbortTransaction;

Aborts the current Btrieve transaction.

See EndTransaction, StartTransaction

AddAltSequence    Procedure AddAltSequence(AltSeqPath : PathStr);

Defines an alternate collating sequence file that will be loaded and passed
to Btrieve on during file creation. This method only needs to be called once,
before Create if an alternate collating sequence is desired.

AddAltSequence can also be call before adding a supplemental index. However;
it should not be called before adding a supplemental index, if an alternate
collating sequence was added when the file was created.

See Create

AddErrors       Procedure AddErrors(ErrorCodes : ErrorSet);

Call AddErrors to add a set of error codes to those handled by the file's
error handler. Use it in  conjunction with RemoveErrors to turn an error/on
and off for automatic trapping. AddErrors just makes a call to the error 
handler AddErrors method, so it is here mostly for convenience. You could 
just as well add errors by dereferencing the ErrHandler pointer. But this is 
one of the most often made calls to the error handler.

See RemoveErrors, ErrHandler, ErrorsOnOff, GetErrors, SetErrors, ErrorHandler

AddKeyBuffer      Procedure   AddKeyBuffer(KeyBuf : Pointer; 
                                           KeyBufSize : Byte);

If you do not want to use MakeKey to setup your keys for file reads, you can 
use AddKeyBuffer to set up an external programmer defined key buffer. This 
external key buffer will generally be a record defined to match a key in the 
file. This external key buffer will be passed to Btrieve on all key reads.

AddKeyBuffer must be called after Init, but before Open. After a key buffer 
is added it is the programmer's responsibility to make sure the key is setup 
properly before each file read. Once, you have called AddKeyBuffer, you 
CANNOT call MakeKey.  The key buffer may be changed as needed by multiple 
calls to AddKeyBuffer.

AddKeySegment   Procedure AddKeySegment(Position : Word; Size : Word;
                                        Flags : Word; KeyType : Byte;
                                        NullValue : Byte; Justify : Byte);

AddKeySegment is used to manually define keys for the file. When creating a 
file the keys must be setup by calls to AddKeySegment. Keys do not have to be 
defined before opening a file. On an Open if no calls to AddKeySegment have 
been made, then the key information will be read from the file itself.

Except for Justify, the parameters are the same as defined by Btrieve. 
Position is the position of the segment in the file. It is the same as 
Btrieve expects, remember they start at one not zero. Size is the  number of 
bytes in the key segment you are defining. Flags are the usual flags such as 
modifiable,  duplicate, etc. KeyType can be any valid type understood by 
Btrieve. NullValue will normally be set to zero.  Please check your Btrieve 
manual for more information on defining keys.

Justify is a special parameter that makes the use of key strings simpler. Any
string  key segment can be automatically padded to the left or right with to 
its defined size. If Justify is set to bLJustify a string will be padded 
to it's full length with spaces. If Justify is bRJustify then a string key 
will be left padded to its defined size with spaces. Set Justify to bNormal 
to leave your key strings as passed.

While this padding is not absolutely necessary, it does make strings easier 
to use. Since the same padding is done to the keys used to read from or write 
to the file, you will never need to worry about trailing or leading spaces on
your string keys. 

A note about the Btrieve String type and justification. When justifying 
String keys, as opposed to LStrings or ZStrings, make sure to clear your key 
or data buffer to zeros. When you call MakeKey be sure to pass your key data 
in a zero filled buffer. This is especially important for right justified 
strings, so the end of the actual valid data can be found. The end of the 
string is considered any data byte that has a value less than 32.

To define the keys for a file, just make repeated calls to AddKeySegment.  
Make one call for each segment needed. You must make these calls in order, 
just as if you were building the key data buffer directly. Add the segments 
that make up key one first, then the segments for key two, then the segments 
for key three, etc. The segments for each key must also be added in order, 
segment one, segment two, etc.  The data will be stored in KeyList and passed 
to Btrieve on a Create.

A typical call would look like  :

          F.AddKeySegment(1,10, bModifiable + bExtended, bLstring, 0, False);

This key starts at position 1 in the file, is modifiable, is a lstring and is 
the last segment in its key path, it has a null value of zero, and  is not 
right justified.

See bXXXXX constants, Create

AddSupplKeySegment    Procedure AddSupplKeySegment(Position : Word; 
                                                  Size : Word;
                                                  Flags : Word; 
                                                  KeyType : Byte; 
                                                  NullValue : Byte; 
                                                  Justify: Byte);

This functions the same as AddKeySegment but is used to define a supplemental
index. You can only define one key at a time.

See bXXXXX constants, CreateIndex, AddKeySegment

bResult         Function bResult: Integer;

This function returns the last error status from Btrieve. Unlike the Turbo 
Pascal IoResult function; a call to bResult does not reset the status, so 
multiple calls can be made to this function.

ChangeBufferSize    Procedure ChangeBufferSize(Size : Word);

This method should only be used for files with variable length records where 
the file buffer is allocated by the automatically by the BtrieveFile object. 
Use it in that rare instance when you need to change the size of the file 
buffer.

See Data, Init

ClearBuffer       Procedure ClearBuffer;

Clears the data buffer (the memory pointed to by the Data field). Uses 
FillValue to fill the buffer to its defined size.

See ClearKey, SetFillValue

ClearKey          Procedure ClearKey;

Clears the key buffer, (the memory pointed to by the Key field). Uses 
FillValue to fill the buffer to its defined size.

See ClearBuffer, SetFillValue

ClearOwner        Procedure ClearOwner;

If an owner has been assigned to a file, this method will clear it. The file 
must be opened before invoking this method.

See SetOwner

Clone           Procedure Clone(NewFilePath : PathStr; Mode : Integer);

Clone will create an empty copy of the file on the specified file path. Mode 
indicates whether the file should be over written if it already exists.

See bXXXXX constants

Close           Procedure Close;

Closes an open file.

See Done

Copy            Function Copy(OutFile: PBtrieveFile; 
                              DisplayObj: PProgress): Integer; 

Copy all records to a new Btrieve file. OutFile is a pointer to the Btrieve 
output file. OutFile must be inited, but does not need to be opened. 
DisplayObj is a pointer to a method that can be called to display the 
progress of Copy. DisplayObj can be nil, in that case no calls will be made. 
If the input file is damaged, you should use Recover, not Copy to copy 
records.

See Load, Recover, Save

Create            Procedure Create(Flags : Word; RecordSize : Word; 
                                   PageSize : Word;
                                   Pages  : Word; Mode : Integer);

Create a new file. Flags are the normal Btrieve file flags such as truncate, 
variable length, or key only. RecordSize is the record size, or the size of 
the fixed length portion of a variable length record. PageSize is the page 
size you want for the file; as usual, it must be a multiple of 512 bytes, up 
to 4096 bytes. Pages is the number of pages  Btrieve should preallocate to 
the file. Mode indicates whether the file should be over written if it 
already exists. A typical call could be :

          F.Create(bNormal, 100, 512, 0, bNoOverWrite);

This file would have no special features like variable length records, is 100 
bytes long, has a 512 byte page size, has no preallocated pages, and will not 
over write an existing file on the same path.

NOTE:  Before calling Create you must define ALL the keys by calling
AddKeySegment.

See bXXXXX constants, AddKeySegment, Init

CreateIndex     Procedure CreateIndex;

Adds a new supplemental index to the file. First, you must set up the new 
index by calling  AddSupplKeySegment. If you are adding more than one new 
index, create each one separately.

See AddSupplKeySegment

Delete            Procedure Delete;

Deletes the current record from the file. You must have previously read a 
record to set the current positioning.

See Get, GetDirect

DropIndex       Procedure DropIndex(Index : Integer);

Removes the supplemental index specified by the Index parameter from the file.

EndTransaction    Procedure EndTransaction;

Ends the current Btrieve transaction.

See AbortTransaction, StartTransaction

Error           Function Error(ErrStatus: Integer; OpCode : Byte;
                               FileName : PathStr): Boolean;

This method is intended mainly for internal use. If the error handler is not 
nil, Error just makes a call to its error handler's Error procedure.

ErrorsOnOff Procedure   ErrorsOnOff(State : Boolean);

Toggles all error trapping on or off for the object. Calls 
ErrHandler^.ErrorsOnOff to set the current error trapping state. When error 
trapping is off, all error must be handled by the programmer.

Note: With the introduction of Btrieve for Windows, some status codes are 
greater than 255, and will not fit in the error set. Since they cannot be 
toggled singly, you should call ErrorsOnOff to remove error trapping for 
these errors.

See AddErrors, GetErrors, RemoveErrors, SetErrors

FillKeyBuffer     Procedure FillKeyBuffer(var Buff; Size : Byte);

This method copies data directly into the key buffer. Buff points to a block 
of memroy to copy, Size is the number of bytes to copy to the key buffer. You 
may call this method instead of MakeKey.

FixKeyStrings     Procedure FixKeyStrings;

Justifies all key strings when writing a record. Intended for BtrieveFile 
internal use only.

Get             Procedure Get(Op : Word; Lock : Word);

Reads a record from the file. This procedure will execute get or step reads. 
Op is the type of read to attempt, such as equal to the key, greater than the 
key, less than the key, step first, step last, next record, or previous 
record. Lock is a standard Btrieve locking type. Please see your Btrieve 
manual for more information on record locking.

If you are reading by key value, before calling Get, you must set up the key 
buffer.  This can be accomplished by calling MakeKey or FillKeyBuffer, or 
through an external programmer defined key buffer.

See bXXXXX constants, MakeKey, SetKeyPath, FillKeyBuffer, AddKeyBuffer

GetDirect         Procedure GetDirect(Lock : Word; Position : LongInt);

Read a record from the file using a physical record position. Lock is a 
standard Btrieve locking type. Position is the position of the desired 
record, you should must get Position by a previous call to GetPosition. You 
may call SetKeyPath to establish the index that will be active after the 
read. Please see your Btrieve manual for more information on record locking.

See bXXXXX constants, GetPosition, SetKeyPath

GetErrors       Procedure GetErrors(var ErrorCodes : ErrorSet);

Returns the set of trapped error codes currently used by the error handler.

See AddErrors, GetErrors, ErrorsOnOff, RemoveErrors, SetErrors, bXXXXX
constants

GetFillValue      Function GetFillValue: Byte;

Returns the current value used to clear the data and key buffers.

GetPosition       Function GetPosition: LongInt;

Returns the position of the current record in the file. You must have 
previously read a record to establish positioning. Use the value returned as 
the Position parameter on a call to GetDirect.

See Get, GetDirect

Insert            Procedure Insert;

Adds a new record to the file. You must fill the file buffer and call this 
method. When writing variable length records be sure to set the actual number 
of bytes of data by a call to SetOutputSize.

See SetOutputSize, Update

IsOpen            Function IsOpen: Boolean;

Returns TRUE if the file is open.

Load            Function Load(InputFilePath : PathStr; 
                              DisplayObj : PProgress): Integer;

Reads records from a DOS file and inserts them into the file. This operates 
the same as Butil with the -Load option. The file being read must be in the 
same format as Butil generates with the -Recover option. Load will read the 
files generated by the Save method.

InputFilePath is the name of the DOS file to read from. DisplayObj is a 
pointer to a method that can be called to display the progress of Load. 
Recover. DisplayObj can be nil.

Load will return a non-zero value if any errors occur. If there is an error, 
you can check the value of bResult to tell which file had a problem. If 
bResult returns zero, then the DOS file had an error. If the   error returned 
is bLoadInputErr, then the DOS file is not in the correct  format.

See Save

MakeKey         Procedure MakeKey(V1 : Pointer; V2 : Pointer; 
                                  V3 : Pointer; V4 : Pointer;
                                  V5 : Pointer; V6 : Pointer); Virtual;

Use this method to build a key before reading a record. The V1..V6  
parameters are the addresses of the data values that will make up the key. 
These parameters must be specified in the same order as in the current index. 
Six key parameters should be enough for most situations, but you can easily 
override MakeKey to provide for more or less. Any unused parameters should be 
passed with a value of nil. A typical call might be :

          F.MakeKey(@State, @City, nil, nil, nil, nil);

This call sets up a key made of two segments. It passes nil pointers for the 
four unused segment parameters.

You may need to call SetKeyPath to establish the index that you want to use.

See AddKeyBuffer, SetKeyPath, bXXXXX constants

NumberOfRecords   Function NumberOfRecords: LongInt;

Returns the NumberOfRecords, actually depending on version, this may really be
the largest number of records ever in the file.

Open            Procedure Open(Mode : Integer; Owner : String);

Opens the file. Mode is the file access mode such as accelerated, exclusive, 
read only or verify. It will normally be set to zero. Owner is the eight 
character file owner name (password). Unless you have set an owner name with 
a call to SetOwner, this should be a null string.

See bXXXXX constants, SetOwner, Init

Recover         Function Recover(NewFilePath: PathStr; 
                                 DisplayObj: PProgress): Integer;

Recover writes the contents of the file to a DOS file. For optimum results 
the file should be opened in Read Only mode. NewFilePath is the name of the 
DOS file to create. DisplayObj is a pointer to a method that can be called to 
display the progress of Recover. DisplayObj can be nil, in that case no calls
will be made.

This method operates the same as Butil with the -Recover option. The file
being written is in the same format as Butil needs for its -Load option.

Recover will return a non-zero value if any errors occur. If there is an 
error, you can check the value of bResult to tell which file had a problem. 
If bResult returns zero, then the DOS file had an error.

See Copy, Load, Save

RemoveErrors      Procedure RemoveErrors(ErrorCodes : ErrorSet);

Use RemoveErrors to remove a set of error codes from those handled by the 
file's error handler. Use it in conjunction with AddErrors to turn an error 
on and off for automatic trapping. RemoveErrors just makes a call to the 
error handler RemoveErrors method, so it is here mostly for convenience. You 
could just as well remove errors by dereferencing the ErrHandler pointer. But 
this is one of the most often used calls for the error handler.

See AddErrors, ErrorsOnOff, ErrHandler, SetErrors, ErrorHandler, bXXXXX
constants

Reset           Procedure Reset;

Resets all resources held by a workstation.

ResetStation    Procedure ResetStation(Connection : Word);

Resets all resources held by a workstation. Connection is the Netware 
connection number for the desired station.

Save            Function Save(NewFilePath : PathStr; 
                              DisplayObj : PProgress): Integer;

Writes all the records that can be read to a DOS file. The file should be 
opened in Read Only mode. This method operates the same as Butil with the 
-Recover option.  The file being written is in the same format as Butil needs 
for its -Load option. Save generates a file that can be read by the Load 
method.

NewFilePath is the name of the DOS file to create. DisplayObj is a pointer to 
a method that can be called to display the progress of Save. DisplayObj can 
be nil, in that case no call will be made.

Save will return a non-zero value if any errors occur. If there is an error, 
you can check the value of bResult to tell which file had a problem. If 
bResult returns zero, then the DOS file had an error.

See Copy, Load, Recover

SetErrors       Procedure SetErrors(ErrorCodes : ErrorSet);

Set the trapped errors currently used by the error handler.

See AddErrors, ErrorsOnOff, GetErrors, RemoveErrors, SetErrors, bXXXXX
constants

SetFillValue        Procedure SetFillValue(Value : Byte);

Sets current value used to clear the data and key buffers.

SetKeyPath        Procedure SetKeyPath(Number : Word);

Sets the key number (access path) that will be used for all reads and writes.

SetOutputSize   Procedure SetOutputSize(Size : Word);

SetOutputSize sets the length of the data buffer before writing a record to 
the file. The data buffer size defaults to the size of the record defined in 
the file. It is only necessary to call SetOutputSize for variable length 
records.

SetOwner        Procedure SetOwner(Owner : String; Mode : Integer);

Owner is the eight character file owner name. Mode is the security 
restrictions desired on future access to the file. Please consult your 
Btrieve manual for  more information on these restrictions.

See bXXXXX constants, ClearOwner

StartTransaction    Procedure StartTransaction(Lock : Word);

Start a Btrieve transaction.

See AbortTransaction, EndTransaction

Stat              Procedure Stat(var FData : FileSpec);

Returns the file statistics.

Unload            Procedure Unload;

Unloads Btrieve from memory.

UnlockAll         Procedure UnlockAll(Lock : Word);

Unlocks all locked records in the file. Lock identifies the type of locks 
that are active.  Less than or equal to 200 indicates single locks, greater 
than 200 indicates multiple record locks. Please see your Btrieve manual for 
more information on record locking.

See bXXXXX constants

Update            Procedure Update;

Updates an existing record in the file. When writing variable length records 
be sure to set the actual number of bytes of data by a calling SetOutputSize 
first.

See SetOutputSize, Insert

Version         Procedure Version(var Ver : Word; var Rev : Word; 
                                  var OSFlag : Char);

Returns the Btrieve version number that is running. Ver is the full version 
number, Rev is the revision number, OSFlag indicates the operating system.


XBtrieveFile OBJECT
==============================================================================
XBtrieveFile is a direct descendant of the BtrieveFile object. XBtrieveFile 
implements functionality for the Extended Get, Step, and Insert operations. 
These extended operation are only available with Btrieve version 5.10 and 
greater. Extended Gets and Steps can be complicated to setup. For best 
results, you should read the Btrieve documentation. After that, experiment a 
little to see how Extended Gets work.

A couple things to remember, field offsets for extended gets are always zero 
based and you must always have valid file positioning established before you 
execute an XGet. This means that some type of read operation must have been 
performed prior to calling XGet. At the minimum, a Get First, Step First, Get 
Last, or Step Last should have been done. You may want to do a read that will 
set positioning to the record just before/after the first record you desire.  
This will help to keep you from exceeding your maximum reject count.

The "and" and "or" operators used in a filter with the Btrieve
extended get and step operations are interpreted in strict left to right
order.  Take, for example, the following file which contains records of
first and last names that will return a different set of records with an
extended get depending on the order of the operators:

                                RECORDS:
                                Sally Fields
                                Fred Fields
                                Fred Smith
                                Sally Jones
                                Sally Smith
                                Fred Jones

            FILTER AND RECORDS RETURNED (with key path = FN):

 FN=Fred and LN=Smith or FN=Sally          FN=Sally or FN=Fred and LN=Smith
 returns:                                  returns:
 Fred Smith                                Fred Smith
                                           Sally Fields
                                           Sally Jones
                                           Sally Smith

Btrieve evalutates an expression in the filter.  If the expression when
applied to the current record is true and the next operator is an  'or',
this record is accepted as meeting the filter condition.  If the
expression is true and the next operator is an 'and', Btrieve will continue
to evaluate each expression until an 'or' is reached, or one of the
expressions evaluates to false, or the end of the filter. If an expression
is false and the next operator is an 'and', the record is rejected.  If the
expression is false and the next operator is 'or' Btrieve will continue and
evaluate with the next expression in the filter.

    Current Expression     Next Operator    Action
    ------------------     -------------    ------
    True                       or           Accept
    False                      or           Continue
    True                       and          Continue
    False                      and          Reject
    True                      (end)         Accept
    False                     (end)         Reject

The general calling sequence for an extended Get/Step is :

  XInit()             - setup the data buffer and size
  SetRejectCount()    - set the maximum records to extract from the file
  SetExtractCount()   - set the maximum number of records to reject
  AddFilterCondition()- add filtering conditions
  AddFieldToExtract() - add fields to extract from each file record
  XGet()              - execute the Get/Step operation
  Extract each record from the data buffer
  XDone / XReset      - free resources or reset for next Get/Step operation

The general calling sequence for an extended Insert is :
  XInit()     - setup the data buffer and size
  Add each record to the data buffer
  XInsert()   - execute the Insert
  XDone       - free resources

Suppose we have records in a Btrieve file defined as :

  MyRec = record
    LastName : String[15];
    FirstName : String[15];
    ID : String[5];
    ....
  end;

Asume that LastName/FirstName and ID have been defined as key 0 and key 1 
respectively.  Retrieving full records with last names in the range "JOHNSON" 
through "JONES" would be something like :

  var
    Buffer : Array[1..30] of MyRec;
    Name : String[15];

  begin
    XInit(@Buffer, SizeOf(Buffer));
    SetRejectCount(1000);
    { leave room for the extra bytes Btrieve returns }
    SetExtractCount(25);
    Name := 'JOHNSON';
    AddFilterCondition(bLstring, 16, 0, bXGetGreatEqual+bXNoCaseCompare,
                       bXLogicAND, @Name);
    Name := 'JONES';
    AddFilterCondition(bLstring, 16, 0, bXGetLessEqual+bXNoCaseCompare,
                       bXDone, @Name);
    { set file postioning if needed }
    ....
    XGet(bXGetNext);
    { process the data }
    ....
    XDone;
  end;

Retrieving just the first and last name fields from records with last names 
greater than "SMITH" would be something like :

  type
    BufferRec = record
      LastName : String[15];
      FirstName : String[15];
    end;

  var
    Buffer : Array[1..30] of BufferRec;
    Name : String[15];

  begin
    XInit(@Buffer, SizeOf(Buffer));
    SetRejectCount(1000);
    { leave room for the extra bytes Btrieve returns }
    SetExtractCount(25);
    Name := 'SMITH';
    AddFilterCondition(bLstring, 16, 0, bXGetGreat+bXNoCaseCompare,  
                       bXDone, @Name);
    AddFieldToExtract(16, 0);
    AddFieldToExtract(16, 16);
    { set file postioning if needed }
    ....
    XGet(bXGetNext);
    { process the data }
    ....
    XDone;
  end;


Fields
------------------------------------------------------------------------------ 
Filters           Filters : PCollection;

A collection of the filtering conditions used in the next extended get or step
operation.

Extractors        Extractors : PCollection;

A collection of the fields to extract and return from records on the next get 
or step.

MaxSkip         MaxSkip : Word;

Maximum number of records that can be skipped on a get or step.

MaxExtract        MaxExtract : Word;

Maximum number of records that should be returned on an extended get or step.

XData           XData : PBytes;

Pointer to the data buffer used with get, step, and insert. XData is set by a 
call to XInit.

XDataSize       XDataSize : Word;

Size of the data buffer pointed to by XData. XDataSize is set by a call to
XInit.

XOffset         XOffset : Word;

Current position in the XData buffer. XOffset is used by ExtractNextRec to 
return the next record from the data buffer.

XCount          XCount : Word;

The number of records returned so far by calls to ExtractNextRec.

XRecCount       XRecCount : Word;

Number of records read by extended get or step.


Methods
------------------------------------------------------------------------------
Init              Constructor Init(FilePath: PathStr; 
                                   ErrorObject: PErrorHandler;
                                   DataBuf: Pointer; DataBufSize: Word);

Initialize the Btrieve file object. Calls BtrieveFile.Init to initialize the 
parent objects data.

See BtrieveFile.Init

Done    Destructor Done; Virtual;

Calls XDone to make sure all memory used by the extended operations is freed, 
then calls BtrieveFile.Done.

See BtrieveFile.Done

AddFieldToExtract   Procedure AddFieldToExtract(FieldSize: Word; 
                                                FieldOffset : Word);

Adds a field to be extracted from a record to the extract list. FieldSize is 
the size of the field in bytes and FieldOffset is the offset of the field in 
the record. Remember, field offsets for extended gets are always zero based. 
If you don't make any calls to AddFieldToExtract, XGet will return the entire 
record.

See XGet

AddFilterCondition    Procedure AddFilterCondition(FieldType: Byte; 
                                                   FieldSize: Word;
                                                   FieldOffset: Word;
                                                   ComparisonType: Byte;
                                                   LogicType: Byte;
                                                   var ComparisonValue);

Adds a filtering condition used by XGet to the filter list. Multiple 
filtering conditions can be setup. You do not need to call 
AddFilterCondition, if no filtering is desired.

FieldType may be any valid Btrieve data type. FieldSize is the size of the 
field in bytes. FieldOffset is the offset of the field in the file record. 
Remember, field offsets for extended gets are zero based.

ComparisonType specifies the comparison expression type. It can specify a
comparison for equality, greater than, less than, not equal, greater than or 
equal, or less than or equal. The numeric values are 1,2,3,4,5, and 6 
respectively. If strings are being compared, add 32 to ComparisonType to 
compare using the file's alternate collating sequence, or add 128 to compare 
without case sensitivity. Add 64 if the second operand is another field in 
the record.

LogicType specifies the AND/OR logic for this condition and the next one 
added.  Set it to zero for the last term in the filtering conditio list. A 
value of one indicates AND and a value of two indicates OR.

ComparisonValue is a pointer to some data to be used in the comparison. If
comparing to another field in the record it should be set to nil. If it is 
not nil, it must point to data of the same type and size as specified by the 
FieldType and FieldSize parameters. The data pointed to by ComparisonValue 
must be valid at the time of the call to AddFilterCondition, since it will be 
copied by AddFilterCondition.

See XGet, bXXXXX constants

ExtractNextRec    Function ExtractNextRec(var DataBuf; 
                                          DataOnly: Boolean): Boolean;

After XGet, ExtractNextRec extracts each record in order from the buffer and 
copies it to the memory pointed to by the DataBuff parameter. Btrieve 
normally returns an unformatted buffer with multiple records after an 
extended get or step operation.  ExtractNextRec is an easy way to get each 
record out of that buffer.

ExtractNextRec returns True if there was a record to extract and False if all 
records have been processed. The raw data returned by Btrieve includes the 
length of each record extracted from the file. If you do not want the length 
set DataOnly to True. If you want the length, make sure to include an integer 
or word as the first field in your record pointed to by DataBuff and pass 
False in DataOnly.

See XGet

SetExtractCount   Procedure SetExtractCount(ExtractCount: Word);

Sets the maximum number of records to read from the file. The extract count
defaults to one.

See XGet

 SetRejectCount   Procedure SetRejectCount(RejectCount: Word);

Sets the maximum number of records to skip on each get or step when trying to
satisfy the filtering conditions. The reject count defaults to one.

See XGet

XDone           Procedure XDone;

Cleanups and frees memory used by XGet. It is very important that you call 
this routine, it is the only way to free resources used by the extended 
operations, short of calling the Done destructor.

XInit             Procedure XInit(XDataBuf: Pointer; XDataBufSize : Word);

Does setup before an XGet or XInsert. Call XInit before each new XGet or 
XInsert, prior to adding filtering conditions and/or extract fields. If you 
do repeated XGets, because there are more records to return than will fit in 
the data buffer, you should call XInit only once before the first of the 
repeated XGet operations.

XGet            Procedure XGet(Op : Word);

Execute an extended Get or Step oeration. Uses the Data buffer set by calling 
XInit, the filtering conditions set by calling AddFilterCondition, and the 
extract fields set by calling AddFieldToExtract. Op can be either 36, 37, 38, 
or 39.

See AddFieldToExtract, AddFilterCondition, SetExtractCount, SetRejectCount, 
XInit, bXXXXX constants

XInsert           Function  XInsert: Word;

Adds the records stored in the data buffer to the file.

XReset            Procedure XReset;

Resets extractor and filter data between unique XGet operations. If you are 
doing a set of XGets with differing filter or extract conditions you must 
call XReset between XGet calls prior to setting the new filter and extract 
conditions.


ErrorHandler OBJECT
==============================================================================
This is the parent obejct for DefErrorHandler and DiskErrorHandler. 
ErrorHandler returns minimal message strings. While DefErrorHandler and 
DiskErrorHandler return full descriptive message strings.


Fields
------------------------------------------------------------------------------
ErrorDisplay      ErrorDisplay : PErrorDisplay;

Pointer to the object that will be called to display errors. If ErrorDisplay 
is nil, no errors will be displayed.

ErrorsON    ErrorsON : Boolean;

RetryCount        RetryCount : Word;

The number of times an operation has been attempted so far. RetryCount is only
used on lock errors.

MaxRetry        MaxRetry : Word;

The maximum number of retries allowed.

RetryDelay        RetryDelay : Word;

Delay between retries on error.

TrappedErrors   TrappedErrors : ErrorSet;

Set of all trapped errors. Any error in this set will be checked for by 
ErrorHandler and passed to an error display routine. This set defaults to all 
errors except End Of File.

NOTE: With the introduction of Btrieve for Windows, some status codes are 
greater than 255, and will not fit in the error set. Since they cannot be 
toggled singly, you should call ErrorsOnOff to remove error trapping for 
those errors greater than 255.

Methods
------------------------------------------------------------------------------
Init              Constructor Init(var DisplayObject: PErrorDisplay);

Initialize the error handler. DisplayObject is the object that will be called 
to display errors. If DisplayObject is nil, no errors will be displayed.

See Done, ErrorDisplay object

Done            Destructor Done; Virtual;

Destroys the object.

See Init

AddErrors       Procedure AddErrors(ErrorCodes : ErrorSet);

Add the errors in the set ErrorCodes to the set of trapped errors.

See ErrorSet, TrappedErrors, SetErrors, GetErrors, RemoveErrors, bXXXXX
constants

ClearRetry        Procedure ClearRetry;

Clears the current number of retries.

See SetDelay, GetDelay, RetryCount, ClearRetry, MaxRetry, GetMaxRetry

ErrorDispatcher   Function ErrorDispacther(ErrorCode : Integer; OpCode : Byte;
                                    FileName : PathStr): ErrorAction; Virtual;

ErrorDispatcher is called by the Error method. The error code, error 
description, operation code, operation description, and file path name will 
be passed to the error display object.

The error display object will return an action code, erAbort, erDone, or 
erRetry. On erAbort the program will be immediately halted. erDone will cause 
the error state to be cleared, so the operation will return to your program 
code. erRetry will leave the error state to TRUE, so the operation can be 
retried.

See Error, ErrorDisplay object, ErrorAction, bXXXXX constants

Error             Function Error(Status : Integer; OpCode : Byte;
                                FileName : PathStr): Boolean; Virtual;

If Status is in the set of trapped errors (zero cannot be added to the set) 
or is greater than bLastError, Error calls the ErrorDispatcher method. The 
status will be passed to the ErrorDisplay object through the ErrorDispatcher 
routine. In the case of file or record lock errors (84, 85), no error will be 
generated until the operation has been tried the number of times stored in 
RetryCount.

If the action code returned by the error dispatcher is erDone, Error will 
return FALSE to the calling routine, indicating no more errors. If the action 
code is erRetry then, TRUE is returned, so the calling routine will execute 
the operation again.

If a Status is not in the set of trapped errors, unless it is greater than 
bLastError, FALSE is always  returned. In this case the program must check 
the file status function bResult for errors.

See ErrorDispatcher, ErrorDisplay object, ErrorAction, bXXXXX constants

ErrorMsg          Function ErrorMsg(ErrorCode : Integer): String; Virtual;

Returns a string describing the error associated with ErrorCode.

See bXXXXX constants

ErrorsOnOff     Procedure   ErrorsOnOff(State : Boolean);

Toggles all error trapping on or off. When error trapping is off all errors 
must be handled by the programmer. This is an easy way to turn of error 
handling for a few Btrieve IO operations.

GetDelay          Function GetDelay: Word;

Returns the current seconds delay between retries.

See GetDelay, RetryCount

GetErrors         Procedure GetErrors(var ErrorCodes : ErrorSet);

Returns the full set of trapped error codes.

See TrappedErrors, SetErrors, AddErrors, RemoveErrors, ErrorSet, bXXXXX
constants

GetMaxRetry     Function GetMaxRetry: Word;

Return the maximum number of retries.

See RetryCount, ClearRetry, MaxRetry, SetMaxRetry

OpMsg         Function OpMsg(OpCode : Integer): String; Virtual;

Returns a string describing the operation associated with OpCode.

See bXXXXX constants

RemoveErrors      Procedure RemoveErrors(ErrorCodes : ErrorSet);

Remove the errors in the set ErrorCodes from the set of trapped errors.

See TrappedErrors, SetErrors, GetErrors, AddErrors, ErrorSet, bXXXXX constants.

SetDelay          Procedure SetDelay(Seconds : Word);

Set the seconds of delay between retries. This delay is only used for lock 
errors.

See GetDelay, RetryCount

SetErrors         Procedure SetErrors(ErrorCodes : ErrorSet);

Setup the full set of trapped errors.

See SetErrors, GetErrors, AddErrors, RemoveErrors, ErrorSet, bXXXXX constants

SetMaxRetry       Procedure SetMaxRetry(Retry : Word);

Set the maximum number of retries.

See RetryCount, ClearRetry, MaxRetry, GetMaxRetry


DefErrorHandler OBJECT
==============================================================================
DefErrorHandler descends from the ErrorHandler object. It holds all message 
strings in memory. ErrorMsg and OpMsg return descriptive message strings.

Methods
------------------------------------------------------------------------------
ErrorMsg          Function ErrorMsg(ErrorCode : Integer): String; Virtual;

Returns a string describing the error associated with ErrorCode.

See bXXXXX constants

OpMsg         Function OpMsg(OpCode : Integer): String; Virtual;

Returns a string describing the operation associated with OpCode.

See bXXXXX constants


DiskErrorHandler OBJECT
==============================================================================
DiskErrorHandler descends from the ErrorHandler object. It holds all message 
strings in a Btrieve file. ErrorMsg and OpMsg return descriptive message 
strings. There is a Btrieve file, "BTRIEVE.MSG", (supplied with the 
registered version BTV) that contains messages for all the status and op 
codes in Btrieve up to version 5.15. The record layout of "BTRIEVE.MSG" is as 
follows:

BtrieveMsgRec = record
  ID : Integer;
  Name : String[80];
  MsgText : Array[0..900] of Char;
end;

ID is the status or op code. The status code records are numbered from zero 
in the file. To fit all messages into one file, the op code record IDs are 
offset by 4000. So, op code zero is stored as opcode 4000 in the file.

Name is a short description of the status or op code. MsgText is a longer 
description, and may contain further explanation and, for status codes, some 
possible corrective actions. Both ErrorMsg and OpMsg return the Name field as 
the message string. You will find that Name and MsgText follow the Btrieve 
SDK manual very closely.

You may use the supplied message file or one of your own creation. If you 
create your own file, make sure it has the same layout as "BTRIEVE.MSG". 
There is a Windows program included, "BTVERR.EXE", for editing message files.


Methods
------------------------------------------------------------------------------
Init    Constructor Init(DisplayObject : PErrorDisplay; ErrorPath : PathStr);

Calls ErrorHandler.Init then opens the Btrieve message file specified by the
ErrorPath parameter.

Done    Destructor  Done; Virtual;

Calls ErrorHandler.Done then closes the message file.

ErrorMsg          Function ErrorMsg(ErrorCode : Integer): String; Virtual;

Returns a string describing the error associated with ErrorCode. If the 
message file is not open, or any errors occur, the message generated by the 
ancestor ErrorHandler is returned.

See bXXXXX constants

OpMsg         Function OpMsg(OpCode : Integer): String; Virtual;

Returns a string describing the operation associated with OpCode. If the 
message file is not open, or any errors occur, the message generated by the 
ancestor ErrorHandler is returned.

See bXXXXX constants


ErrorDisplay OBJECT
==============================================================================
ErrorDisplay displays error messages for errors handled by the ErrorHandler 
object or its descendants.


Methods
------------------------------------------------------------------------------
Init              Constructor Init;

Initialize the object.

See Done

Done            Destructor Done; Virtual;

Destroys the object.

See Init

Display         Function Display(Error : Integer; ErrorMsg : String;
                              OpCode : Byte; OpCodeMsg : String;
                              FileName : PathStr): ErrorAction; Virtual;

This routine is called by the error handler, for any errors that are in the 
set of trapped errors or greater than bLastError. Error is the Btrieve status 
code, ErrorMsg a description of the error code. OpCode is the operation that 
generated the error.  OpCodeMsg is a description of the operation. FileName 
is the full path name for the file. This routine must return an action code 
that will tell the error handler what to do next.

Here is an example of a what typical error display method might look like :

          Function TheErrorDisplay.Display(Error : Integer; ErrorMsg : String
                                           OpCode : Byte; OpCodeMsg : String;
                                           FileName : PathStr): ErrorAction;
            var
              Ch : Char;
            begin
              GotoXY(1,1);   { show what happened }
              Writeln('<BTRIEVE IO ERROR>');  Writeln(FileName);
              Writeln(ErrorMsg);  Writeln(OpCodeMsg);

              Case Error of   { a couple errors to abort on }
                bFileNotOpen, bFileNotFound, bNotLoaded :
                begin
                  Writeln('Press a key ...');
                  Ch := ReadKey;
                  Display := erAbort;
                end;
                else  { we will let user decide what to do here }
                begin
                  Writeln('Do you wish to try again (Y/N)?');
                  Ch := UpCase(ReadKey);

                  if (Ch = 'Y') then Display := erRetry
                  else Display := erDone;
                end;
              end;
            end;

As you can see, you have full control of what happens after an error. You can 
use the opcode and error to classify errors and control the error handler 
actions. Pass back erAbort to halt the program, erRetry to make another 
attempt, or erDone to continue and return the error to your program.


TProgress OBJECT
==============================================================================

Methods
------------------------------------------------------------------------------
Init              Constructor Init;

Display         Procedure Display(Count : LongInt);

This method is called by Recover, Save, and Load to display the progress of the
operation. You must define a new descendant object with a working Display method.
Before calling Recover, Save, or Load, initialize an object of your new type. Then
pass a pointer to your object. Your Display method will be called every ten records
plus one final time when the operation is complete.
