home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-02-08 | 70.3 KB | 2,079 lines |
-
-
-
-
-
-
-
-
-
-
-
-
- ISAM Manager
-
- B+Tree/ISAM System For C++
-
- Copyright 1993 Nildram Software
-
- All Rights Reserved
-
-
- ISAM Manager was written by Adrian Mardlin
-
-
-
- Address: Nildram Software
- 82 Akeman Street
- Tring
- Herts HP23 6AF
- United Kingdom
-
- Telephone: +44 (0)442 891331
-
- Fax: +44 (0)442 890303
-
- Internet: sales@nildram.com
- support@nildram.com
- info@nildram.com
-
- CIS: GO UKSHARE, Section 10 or email 76004,3436
-
- FidoNet: 2:257/112 (Address messages to ADRIAN MARDLIN)
- Or leave messages in C_PLUSPLUS or SHAREWARE echoes
-
- ILink: Leave messages to ADRIAN MARDLIN in SHAREWARE echo.
-
- TheNet: Leave messages to ADRIAN MARDLIN in C Programming echo.
-
- BBS: +44 (0)442 891109
-
- ISAM Manager is a trademark of Nildram Software.
-
- All trademarks and registered trademarks mentioned in this
- document are acknowledged.
-
- INTRODUCTION
-
- Overview
-
- ISAM Manager is a database management library for C++
- programmers. It is a full B+Tree/ISAM system, which is extremely
- fast and provides a very straightforward interface to the
- developer. Features include:
-
- Full relational capabilities.
-
- Up to 2 billion records per data file with FAST access.
-
- Multiple Indexes. up to 10 different indexes, each containing up
- to 10 data fields are allowed for each data file.
-
- Fast! In a database with 4 million records, ISAM Manager can
- locate a specific record with as little as 4 disk accesses! It's
- made even quicker by its in-built index caching system which can
- reduce the number of accesses required even further.
-
- 4GL Features. ISAM Manager can automatically generate a data
- entry program from just a database description file, giving you
- a framework on which you can build a more powerful application,
- or just a quick and easy data entry screen. Just like a 4th
- Generation Language (4GL)!
-
- Portable. ISAM Manager is provided for both DOS and Windows, and
- is easily ported to other operating systems also.
-
- ISAM Manager is currently a single-user system. That is, only
- one user may access a database at any one time. A multi-user
- version is planned, and will have full record-locking
- capabilities for fast, multi-user access.
-
-
- System Requirements
-
- ISAM Manager ships with libraries for the following compilers:
-
- Borland C++ v 4.0 or later
- Symantec C++ v 6.0 or later
- Microsoft Visual C++ v 1.0 or later
- Borland C++ for OS/2 v 1.0 or later
-
- Other compilers should work fine, as should earlier versions of
- the above compilers, but are untested, and will require you to
- compile your own libraries. Both DOS and Windows versions of the
- libraries are provided, in the large memory model. Source code
- is provided to allow you to modify or port it to other
- platforms. Approx 500k of disk space is required to install ISAM
- Manager.
-
-
- Support
-
- Full lifetime support is provided to all registered users of
- ISAM Manager direct from Nildram Software. Check the front of
- this manual for contact details. You will also be notified of
- all major upgrades, and offered them at a special reduced price.
- Make sure you return your registration card if you didn't
- purchase ISAM Manager direct from Nildram Software, or you won't
- be eligible for support, and we won't be able to tell you about
- any upgrades.
-
- In addition to the normal support, we provide a service
- available to anyone who has an Internet address, called the ISAM
- Manager Information Service. Simply send an email message to
- imis@nildram.com, and we will add you to our mailing list and
- email you details of bugs and how to fix them, new releases etc.
-
-
- What Is Shareware?
-
- Shareware is a distribution method (not a type of software) which lets
- users evaluate software before buying. If you try a shareware program
- and continue using it, you must register and pay for it. (If you paid
- a small duplication and handling fee to receive a trial copy of a
- shareware product from a vendor, you have not paid for the product
- itself or the right to continue using it after a reasonable trial
- period. A separate fee to the program's owner and developer is
- required to continue to use the product after evaluation.) Copyright
- laws apply to both shareware and commercial software.
-
- Shareware authors are accomplished programmers just like commercial
- authors and the programs are of comparable quality. In both cases,
- there are good and bad programs. The main difference is in the method
- of distribution.
-
- The shareware system makes fitting your needs easier because you can
- try before you buy. Because overheads are 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.
-
-
- Terms And Conditions
-
- ISAM Manager is shareware program and is provided by Nildram Software
- at no charge for evaluation. Feel free to share it with friends and
- colleagues for evaluation, but please do not give it away altered or
- as part of another system. The essence of user-supported software is
- to provide personal computer users with quality software without high
- prices, yet to provide incentive for programmers to continue to
- develop new products.
-
- Please encourage others to register their copies if they find it
- useful. All registered users receive a copy of the latest version of
- the ISAM Manager system.
-
- If you continue to use ISAM Manager after a reasonable trial period,
- you must make a registration payment of #39.00+VAT to Nildram Software.
- This registration fee licenses one copy for use on any one computer at
- any one time. You must treat this software just like a book. This
- software may be used by any number of people and may be freely moved
- from one computer location to another provided there is no possibility
- of it being used at one location while being used at another, just as
- a book cannot be read by two different persons at the same time.
-
- Commercial users of ISAM Manager must register and pay for their
- copies of ISAM Manager within 30 days of first use or their license
- is withdrawn. Site License arrangements may be made by contacting
- Nildram Software.
-
-
- Registration
-
- If you continue using ISAM Manager, you must register. To do this,
- either print and fill in the registration form provided (type "COPY
- REGISTER.DOC PRN" at the DOS prompt), or send a cheque for #39.00
- (thirty-nine pounds) + VAT (currently 17.5%, so #45.83 total) or
- your credit card details to the following address:
-
- Nildram Software
- 82 Akeman Street
- Tring
- Herts
- HP23 6AF
- UK
-
- Tel: +44 (0)442 891331
- Fax: +44 (0)442 890303
- Compuserve: 76004,3436
- Internet: sales@nildram.com
-
- Further registration details for overseas customers are contained
- in the REGISTER.DOC file. You will receive the latest version of
- ISAM Manager without the registration encouragement screens, full
- source code, a printed manual, free support and cheap upgrades as
- they become available.
-
-
- Disclaimer
-
- Users of ISAM Manager must accept this disclaimer of warranty:
-
- "ISAM Manager 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 ISAM Manager."
-
-
- The ASP
-
- This program is produced by a member of the Association of
- Shareware Professionals (ASP). ASP wants to make sure that the
- shareware principle works for you. If you are unable to resolve
- a shareware-related problem with an ASP member by contacting the
- member directly, ASP may be able to help. The ASP Ombudsman can
- help you resolve a dispute or problem with an ASP member, but
- does not provide technical support for members' products. Please
- write to the ASP Ombudsman at 545 Grover Road, Muskegon, MI
- 49442, USA or send a Compuserve message via Compuserve mail to
- ASP Ombudsman 70007,3536.
-
- INSTALLATION
-
-
- Introduction
-
- To Install ISAM Manager, simply insert disk 1 into drive A (or
- whatever floppy drive letter you are using), and type the
- following:
-
- A:INSTALL
-
- INSTALL will ask you for a drive and directory name to install
- ISAM Manager into, which will default to "C:\ISAMMGR". The
- following subdirectories off C:\ISAMMGR will also be created:
-
- INCLUDE - Include files
- LIB - Library files
- TUT1 - Tutorial 1 files
- TUT2 - Tutorial 2 files
- TUT3 - Tutorial 3 files
- SOURCE - ISAM Manager source code
- FSCREEN - FScreen Library source code
- KEYSRCH - KEYSRCH & ADDFILE Example program files
-
- You should now add "C:\ISAMMGR" to your DOS PATH statement, as
- this directory will contain some important executable files, and
- "C:\ISAMMGR\INCLUDE" should be added to your compiler's include
- file search path. "C:\ISAMMGR\LIB" contains the lib files which
- should be included. They are named as follows:
-
- imbl.lib - Borland C++ v 4.00 library for DOS
- imbwl.lib - Borland C++ v 4.00 library for Windows
- imml.lib - Microsoft Visual C++ v 1.00 library for DOS
- immwl.lib - Microsoft Visual C++ v 1.00 library for Windows
- imsl.lib - Symantec C++ v 6.10 library for DOS
- imswl.lib - Symantec C++ v 6.10 library for Windows
- imbos2.lib - Borland C++ for OS/2 v 1.00 library
-
- All DOS and Windows libraries are compiled for the large memory
- model. ISAM Manager will also work in compact memory model, but
- these libraries have been left out to save space - you will need
- to compile your own libraries if you wish to use the compact
- memory model. Remember to include a .lib file in each of your
- projects or make files. You may want to delete any .lib files
- that you know you won't be using.
-
-
- Building Libraries
-
- There are many reasons why you may want to build your own
- libraries - maybe you want to use the compact memory model, or
- you need to add a bug fix, or an enhancement of your own. The
- process is fairly straightforward, particularly for those
- compilers that allow you to create .lib files from within the
- integrated environment.
-
- To create a DOS library, simply compile all the files in the
- ISAM Manager source directory, except for WISAMMSG.CPP, and all
- the files in the ISAM Manager fscreen directory, and make a
- library from them. To create a Windows library, you simply need
- all the files in the ISAM Manager source directory, except for
- ISAMMSG.CPP.
-
- USER GUIDE
-
-
- Introduction
-
- In this USER GUIDE, we will be concentrating on the DDF file,
- its format and its use when programming with ISAM Manager.
-
-
- Introduction To DDF
-
- DDF stands for "Database Description File". The .DDF file is
- where you define the format of your data files, including the
- indexes. The format of the file is designed such that it will be
- easily extensible in the future to carry additional information.
- This is achieved by splitting the file up into sections which
- have their own begin and end commands. They are currently as
- follows:
-
- {BEGDATA}
- {ENDDATA}
- {BEGIDX}
- {ENDIDX}
-
- {BEGDATA} and {ENDDATA} specify the beginning and end of the
- Data Field definitions, and {BEGIDX} and {ENDIDX} specify the
- beginning and end of the Index definitions. All of these
- definitions MUST exist in a .DDF file in the order above. They
- must also each be placed on a line of their own, at the
- beginning of the line. The file may contain any comments you
- wish to place in it, so long as they are placed outside of these
- groups.
-
-
- Data Field Definitions
-
- These are defined in between the {BEGDATA} and {ENDDATA}
- commands. The first line after {BEGDATA} is a special line, and
- should contain the filename to be used for the data file,
- including the extension. The filename may also include directory
- path information, but must be less than 65 characters long in
- total.
-
- The subsequent lines, up to the {ENDDATA} statement, should
- contain the name and type information for all the data fields
- within each record. They will be stored in the data file in the
- order in which they are defined (though this does not alter the
- functional behaviour of the database). To simplify matters and
- shorten the learning curve, these definitions follow the normal
- C/C++ syntax, with 1 limitation - no pointers may be defined
- (they wouldn't make a great deal of sense in a database context
- anyway).
-
- The following data types are supported:
-
- char
- unsigned char
- short
- unsigned short
- int
- unsigned int
- long
- unsigned long
- float
- double
-
- Standard C or C++ comments are allowed after each definition
- (which is terminated with a semi-colon, as in C/C++), but each
- line MUST contain a definition. Please note that these lines are
- picked up and placed in the .H file generated by the DDF program
- without any changes being made. DDF will not check whether any
- comments placed after the data field definitions are in a
- correct format, and thus you will get a syntax error at compile
- time if you don't use the proper comment syntax on these lines.
-
- Here is an example of an incorrectly formatted Data Field
- definition section:
-
- {BEGDATA}
- DATA.DTA // You cannot place a comment on this line!
- char field1[20]; This will give a compile error
- int *field2; // Pointers are not allowed!!!
-
- // ^^^ Neither are blank lines (nor this line!)
- {ENDDATA}
-
- And here's a correct version:
-
- {BEGDATA}
- DATA.DTA
- char field1[20]; // This comment is perfectly OK
- int field2; /* So is this one */
- float a[23]; // Pretty silly, but it works!
- {ENDDATA}
-
- Index Definitions
-
- As with the Data Field Definitions, the line following the
- {BEGIDX} statement should contain the name of the file to be
- used to store the indexes. This MUST be a different name to the
- data file, or it won't work.
-
- The subsequent lines, up to the {ENDIDX} statement, should each
- contain an index definition. Comments are allowed after the
- definitions, but blank lines are not. The format you should use
- is as follows:
-
- *Index Name: field1, field2, field3; // Comment
-
- The asterisk at the beginning of the line is optional and
- denotes whether the index is 'unique' or not. A unique index
- will not allow two records with identical index values to be
- inserted, causing the insert() function to fail. Be careful when
- choosing to use a unique index - they should only really be used
- for indexes that contain values such as customer numbers,
- employee numbers etc, which should only occur once in the
- database.
-
- Following the asterisk (if there is one), is the index name.
- This name can contain whitespace characters (as shown above),
- and is used to select indexes within your program (though you
- can also switch between indexes by number, where the first index
- defined is number 0, and so on). The index name is terminated by
- a colon.
-
- What follows now is a list of up to 10 data field names,
- delimited by commas and terminated with a semi-colon. These are
- the fields that are contained within the index, in the order in
- which they are to be indexed.
-
- Here's an example of a complete .DDF file:
-
- {BEGDATA}
- EMPLOYEE.DTA
- int emp_no;
- char initials[6];
- char surname[21];
- char dept[2];
- long salary;
- {ENDDATA}
-
- {BEGIDX}
- EMPLOYEE.DTX
- Name: surname, initials;
- *Employee Number: emp_no;
- {ENDIDX}
-
-
- Indexing Peculiarities
-
- There are certain peculiarities with the way the indexing works
- that you should be aware of. They are as follows:
-
- With arrays of type char, a zero byte is considered to be the
- end of the array, and the rest of the array is padded out with
- zeros before being indexed. This is because char arrays are most
- commonly used to represent null-terminated strings, which this
- approach is ideally suited to. Just be very careful if you are
- using a char array to store anything else.
-
- When int or long types (both signed and unsigned) are stored in
- the index, their byte order is swapped due to the peculiarities
- of the Intel architecture, so that they are sorted correctly. If
- an array of type int or long is used within an index, the byte
- order will NOT be swapped, and so using the next() or prev()
- functions may give the impression that the index has not sorted
- them correctly.
-
- Floating point types will not be sorted properly in order. As
- there are very few cases where there is any merit in indexing
- using floating point types, this shouldn't cause a major
- problem, and can be worked around in any case.
-
-
- Using DDF.EXE
-
- The program DDF.EXE (for OS/2, you should run DDFOS2.EXE
- instead) is provided to convert the contents of a .DDF file into
- code that your compiler can understand. Simply specify the name
- of the .DDF file or files (wildcards and multiple arguments are
- allowed) to be processed on the command line. You do not need to
- specify the extension ".DDF". For example:
-
- DDF QWERTY
-
- In this example, DDF will create two new files -- QWERTY.CPP and
- QWERTY.H. If you then wish to use the QWERTY data file within
- your application, you simply need to #include "qwerty.h" in your
- source code, and compile and link QWERTY.CPP with the rest of
- your application. It's as simple as that!
-
- Because DDF creates these files, and overwrites any existing
- files of the same name, you should be careful that you don't use
- the same name for one of your source code files as you do for
- any of your .DDF files! Also, do not alter the code in either
- the .H file or the .CPP file. If you need to change anything, do
- it in the .DDF file.
-
-
- Using MAKSCR.EXE
-
- The program MAKSCR.EXE is provided to enable you to produce a
- 'quick-and-dirty' file maintenance program. This program can
- then be used as-is, or as the basis for a more complex and
- powerful data entry screen. The code produced by MAKSCR uses the
- FScreen Library for all of its screen I/O, though support for
- other screen libraries may appear in future releases. It will
- also #include the header file, "ATTRDEFS.H", which defines the
- colour schemes used within the display. You should alter
- ATTRDEFS.H to suit your tastes.
-
- MAKSCR sends its output to stdout. This allows you to redirect
- it to the file of your choice, or just view it on the screen.
- Here's an example:
-
- MAKSCR QWERTY.DDF > QWERMNT.CPP
-
- Then all you would need to do to create a basic file maintenance
- program for the QWERTY data file is to compile and link both
- QWERTY.CPP and QWERMNT.CPP (remembering, of course, to also link
- in the correct ISAM Manager library file for the memory model
- and compiler that you are using).
-
- MAKSCR has its limitations. Firstly, it will not successfully
- display more than about 20 fields. However the code will be
- there, so you can change the screen positions of any fields that
- have slipped off the screen. Secondly, it can't handle floating
- point numbers, and will ignore any that appear in the .DDF file.
-
- What follows is the output of MAKSCR when processing the example
- file, EMPLOYEE.DDF used earlier in this chapter. EMPLOYEE.DDF is
- also used in TUTORIAL 1. It may be helpful at this stage to
- examine the code below in conjunction with the function
- reference chapters and see if you can figure out how it is
- working.
-
- #include <fscreen.h>
- #include <attrdefs.h>
-
- #include "EMPLOYEE.H"
-
- dfEMPLOYEE employee;
-
- void draw_screen(void)
- {
- FSputs("emp_no", attrLEGEND, 3, 3);
- FSputs("initials", attrLEGEND, 4, 1);
- FSputs("surname", attrLEGEND, 5, 2);
- FSputs("dept", attrLEGEND, 6, 5);
- FSputs("salary", attrLEGEND, 7, 3);
- }
-
- void display_all(void)
- {
- FSclrbox(3, 10, 7, 79, attrSCREEN);
- FSputi(employee.emp_no, attrINPUT, 3, 10);
- FSputs(employee.initials, attrINPUT, 4, 10);
- FSputs(employee.surname, attrINPUT, 5, 10);
- FSputs(employee.dept, attrINPUT, 6, 10);
- FSputl(employee.salary, attrINPUT, 7, 10);
- }
-
- int input_data(int is_index = 0)
- {
- for (int x = 0; x < 5 && x >= 0;)
- {
- int FSerror = 0;
- switch(x)
- {
- case 0:
- if (is_index)
- {
- x++;
- break;
- }
- FSerror = FSinputi(employee.emp_no,
- attrINPUT, 3, 10);
- break;
-
- case 1:
- FSerror = FSinputs(employee.initials,
- attrINPUT, 4, 10, 5);
- break;
-
- case 2:
- FSerror = FSinputs(employee.surname,
- attrINPUT, 5, 10, 20);
- break;
-
- case 3:
- if (is_index)
- {
- x++;
- break;
- }
- FSerror = FSinputs(employee.dept,
- attrINPUT, 6, 10, 1);
- break;
-
- case 4:
- if (is_index)
- {
- x++;
- break;
- }
- FSerror = FSinputl(employee.salary,
- attrINPUT, 7, 10);
- break;
- }
-
- switch (FSerror)
- {
- case FS_ENTER:
- case FS_CURSORDOWN:
- x++;
- break;
-
- case FS_CURSORUP:
- case FS_BACKSPACE:
- x--;
- break;
-
- case FS_PGDN:
- x = 999;
- break;
-
- case FS_ESCAPE:
- case FS_PGUP:
- x = -1;
- break;
- }
- }
- if (x < 0)
- return IM_ERROR;
- return IM_OK;
- }
-
- int main(void)
- {
- static char *menopts[] = { "^Insert", "^Amend",
- "^Delete", "^Find", "^Next", "^Prev", "E^xit", NULL };
- FSinit();
- FSclrscr(attrSCREEN);
- draw_screen();
- employee.rew();
- employee.clear_buf();
- display_all();
- FStitle("EMPLOYEE FILE MAINTENANCE", attrTITLE, 0);
-
- for (;;)
- {
- switch (FSbarmenu(22, FS_CENTRE, 2, menopts,
- attrBMNORM, attrBMHIGH, attrBMHOTK))
- {
- case 0: // Insert
- employee.clear_buf();
- display_all();
- if (input_data() == IM_OK)
- employee.insert();
- else
- employee.rew();
- break;
-
- case 1: // Amend
- if (employee.retrieve() == IM_ERROR)
- break;
- display_all();
- if (input_data() == IM_OK)
- employee.amend();
- break;
-
- case 2: // Delete
- employee.erase();
- employee.clear_buf();
- display_all();
- break;
-
- case 3: // Find
- employee.clear_buf();
- display_all();
- if (input_data(1) == IM_OK)
- {
- if (employee.find() == IM_ERROR)
- if (employee.retrieve() ==
- IM_ERROR)
- if (employee.prev() ==
- IM_ERROR)
- employee.clear_buf();
- display_all();
- }
- else
- {
- employee.clear_buf();
- display_all();
- }
- break;
-
- case 4: // Next
- if (employee.next() == IM_ERROR)
- employee.prev();
- display_all();
- break;
-
- case 5: // Prev
- if (employee.prev() == IM_ERROR)
- employee.next();
- display_all();
- break;
-
- case 6: // Exit
- case -1: // <ESCAPE> Pressed
- return 0;
- }
- }
- return 0;
- }
-
-
- Limitations
-
- Maximum records per file: 2 billion (approx)
- Maximum data fields per record: 1000 (arrays count as 1 field)
- Maximum record size: 32,767 bytes
- Maximum index size: 500 bytes
- Maximum indexes per data file: 30
- Maximum data fields per index: 10 (arrays count as 1 field)
-
-
- PROGRAMMING GUIDE
-
-
- Introduction
-
- Programming in ISAM Manager is designed to be as simple and
- straightforward as possible. By using the powerful features
- available within the C++ programming language, such as
- inheritance and virtual functions, ISAM Manager is able to
- completely hide its complexity from you, the programmer. This
- means that you only need a rudimentary knowledge of C++ (in
- fact, a C programmer should be able to learn ISAM Manager just
- as quickly as an experienced C++ programmer), though obviously
- the more proficient you are at C or C++, the easier you will
- find things.
-
- One of the quickest ways to learn the system is to have a look
- through some of the example code provided, and also by using the
- MAKSCR program (see USER GUIDE for more details) and examining
- the code produced by it.
-
-
- Including Data Files
-
- To include a data file in your project is a very straightforward
- process. Once you have created a .DDF file and processed it with
- DDF.EXE (see USER GUIDE for more details), you will be left with
- a .H and a .CPP file of the same name. Simply #include the .H
- file in your code, then declare an instance of the file object
- like so:
-
- #include "qwerty.h"
-
- dfQWERTY qwerty;
-
- Notice that the class name is the name of the file in caps and
- preceded by 'df'. In this example, the data and index files will
- be opened or created, and ready for access within your program.
- Only one instance of each file object should be created in a
- program, and this should either be a global declaration, or the
- space should be allocated and removed by using new and delete
- (i.e. Don't create an instance of a file object on the stack as
- it will probably cause a stack overflow error).
-
- You can declare a data file as being closed by using the
- following syntax:
-
- dfQWERTY qwerty(moClosed);
-
- This can be useful if you are using lots of data files within a
- program, and DOS is running out of file handles. Just declare
- some of the least used files as closed, and open them when you
- need them, and close them when you've finished with them. Please
- be aware that if you declare a file as closed, it will still be
- opened when your program is initially run, and then closed
- again. This is so ISAM Manager can check the existence and
- validity of the index and data files before any processing is
- done on them.
-
- You can also specify your own names for the data and index files
- and paths, which will override any name specified in the .DDF
- file. For example:
-
- dfQWERTY qwerty("C:\ASDFG.DAT", "D:\ASDFG.IDX");
-
- This would specify a data file in the root directory of drive C,
- and an index file in the root directory of drive D, with the
- above names. With this alternative constructor, you can also
- specify a closed file - just put moClosed as the third argument,
- like so:
-
- dfQWERTY qwerty("C:\ASDFG.DAT", "D:\ASDFG.IDX", moClosed);
-
-
- Accessing A Data File
-
- In the above example, once you have included the QWERTY data
- file in your code, you can now access the records and fields
- within the file in a very straightforward way. The DDF FUNCTION
- REFERENCE chapter documents all the functions that you have at
- your disposal for accessing records by using an index, and we
- will cover some of them in more detail in this chapter. The
- fields that you declared in the .DDF file will now be available
- to your code. For example, if you declared a field in QWERTY.DDF
- like so:
-
- int test;
-
- You will now find that this field is a public member of the
- dfQWERTY class, and you can access it as a normal integer
- variable using the following syntax:
-
- qwerty.test
-
- It's as simple as that. When you read in a record from the file,
- the field variables will be updated with the values in the
- record, and when you amend or insert a new record into the file,
- the record will be made up from the contents of the field
- variables, and then added to the file. If you are searching for
- a particular record, you just need to set the field variables
- that are members of the currently selected index, call the
- find() function, and if a record is found, all the other field
- variables will be set accordingly. The find() function will only
- succeed if it finds an EXACT match. However, if it fails, the
- index cursor will be placed on the next record after the
- position where the matching record would have been, if there was
- one. You can then retrieve this record from the file, and into
- the field variables by calling the retrieve() function.
-
- If you haven't done so already, please read through the USER
- GUIDE chapter, and study the code example at the end of the
- chapter. Make sure you understand roughly how it works before
- you proceed any further. If you have trouble understanding it,
- you may want to work through the TUTORIAL chapters provided.
-
-
- Using Indexes
-
- Each data file has between 1 and 10 indexes associated with it.
- You can switch between these indexes by use of the set_idx()
- function provided. When you call functions such as find(),
- next() or prev(), they use the currently set index. You may also
- find the get_cur_idx(), get_idx_name() and get_no_idxs()
- functions helpful when dealing with indexes.
-
-
- Rebuilding Indexes
-
- If at any time the indexes of a data file become corrupted, they
- will need to be rebuilt. To do this, simply delete the index
- file, and the next time you run a program that uses that index,
- it will automatically be rebuilt.
-
-
- ISAMMSG.CPP
-
- ISAMMSG.CPP contains some functions which are called by
- ISAMMGR.CPP in the event of an error, or when the indexes are
- rebuilt. By default, ISAMMSG.CPP uses fprintf(stderr, ...) for
- its output. You can override this to suit the screen library you
- are using by writing your own version of ISAMMSG.CPP, or just
- rewriting the functions in one of your existing program modules.
- This will cause the version contained within the library file
- not to be linked. The functions defined within ISAMMSG.CPP are
- as follows:
-
- void IsamError(const char *errmsg);
- void IsamInitProgress(const char *fname, const char *idx);
- void IsamProgress(long recno);
- void IsamEndProgress(void);
-
- IsamError is called if an error occurs. errmsg contains the
- error message. ISAM Manager will call the abort() function as
- soon as IsamError returns, as any error reported by IsamError is
- critical. If you need to do any cleaning up of the screen, for
- example, before the program terminates, you should put the
- necessary code in your version of IsamError, and perhaps
- terminate the program yourself before ISAM Manager gets a chance
- to call abort(). IsamInitProgress, IsamProgress and
- IsamEndProgress are all used if the indexes need to be rebuilt
- at the start of a program. IsamInitProgress is first called with
- the name of the data file and the name of the index being
- processed. Then IsamProgress is called as the index is being
- rebuilt with the number of records processed. And finally,
- IsamEndProgress is called when the rebuild is complete.
-
- One word of warning however. If an index needs rebuilding, it is
- done by the class constructor, and will therefore happen before
- main() is called. So watch out and make sure you initialise
- your screen library (if you are using one) before any data files
- are declared.
-
- Here is the default ISAMMSG.CPP file which will be used if you
- don't re-define the functions:
-
- #include "isammsg.h"
-
- #include <stdio.h>
-
- void IsamProgress(long recno)
- {
- char bs[9] = { 8, 8, 8, 8, 8, 8, 8, 8, 0 };
- fprintf(stderr, "%s%8ld", bs, recno);
- }
-
- void IsamError(const char *errmsg)
- {
- fprintf(stderr, "%s\n", errmsg);
- }
-
- void IsamInitProgress(const char *fname, const char *idx)
- {
- fprintf(stderr, "Rebuilding Index File: \"%s\", Name:"
- " \"%s\"\nRecords Processed: ", fname, idx);
- }
-
- void IsamEndProgress(void)
- {
- fprintf(stderr, "\n");
- }
-
-
- Buffers
-
- ISAM Manager makes use of buffers to speed up its access to the
- indexes. By default, the number of buffers used is set to 16. To
- override this value, simply include the following line in one of
- your source files:
-
- int DMCacheSize = x;
-
- Replace 'x' with the number of buffers you wish to use.
-
-
- The ADDFILE & KEYSRCH Programs
-
- The ADDFILE and KEYSRCH programs are provided as an example of a
- real application that demonstrates the use of multiple data
- files, and their inter-relations. You will find them in the
- KEYSRCH subdirectory.
-
- ADDFILE is a program that will process through any number of
- files, extracting any text strings, and adding them to a KEYWORD
- data file. KEYSRCH can then locate all the files that contain a
- number of keywords very quickly. ADDFILE is quite slow. KEYSRCH
- is blindingly fast. With a Btree/ISAM system such as ISAM
- Manager, inserting records is relatively slow, but finding them
- is exceptionally fast, even when there are literally millions of
- records in a file.
-
- The syntax for calling these programs is as follows:
-
- ADDFILE <filename> ...
- KEYSRCH <keyword> ...
-
- You may give ADDFILE a list of filenames to process, and you can
- give KEYSRCH a list of keywords to process. KEYSRCH will find
- all the files that contain all the keywords specified.
-
- See if you can figure out how ADDFILE and KEYSRCH work. By
- understanding these two programs, you will go a long way towards
- understanding the ISAM Manager system as a whole.
-
- TUTORIAL 1
-
-
- Introduction
-
- This series of tutorials is designed to introduce you to the
- various concepts involved in database programming and, more
- particularly, programming using ISAM Manager. Example code is
- provided in the subdirectories TUT1, TUT2 and TUT3. You will be
- taken through various stages in the development of a simple
- employee database starting from the very simplest of screen form
- input programs and leading on to such things as batch
- processing, switching indexes and so on. This chapter, however,
- will cover basic screen form programming.
-
-
- DDF File
-
- The first and perhaps most important phase in the development of
- a database is the design of the .DDF file. For our example, we
- are going to use the following design (call the file
- EMPLOYEE.DDF):
-
- {BEGDATA}
- EMPLOYEE.DTA
- int emp_no;
- char initials[6];
- char surname[21];
- char dept[2];
- long salary;
- {ENDDATA}
-
- {BEGIDX}
- EMPLOYEE.DTX
- Name: surname, initials;
- *Employee Number: emp_no;
- {ENDIDX}
-
- Use your text editor to enter the above into a file called
- EMPLOYEE.DDF". Once you have done this, type "DDF EMPLOYEE",
- and, assuming you have entered everything correctly, DDF will
- exit with no errors and will have created the two files,
- "EMPLOYEE.CPP" and "EMPLOYEE.H".
-
-
- Automatic Program Generation
-
- We are now going to use the MAKSCR command provided with ISAM
- Manager to automatically generate a basic data entry program,
- with which we will be able to enter or search for data in the
- EMPLOYEE data file. To do this, type the following command:
-
- MAKSCR EMPLOYEE > EMPMAINT.CPP
-
- You will now have a second .CPP file -- EMPMAINT.CPP. This,
- combined with EMPLOYEE.CPP and EMPLOYEE.H, is all you need to
- create a basic data entry program -- ISAM Manager has
- effectively written all your code for you! To create a working
- .EXE program, simply compile both EMPLOYEE.CPP and EMPMAINT.CPP,
- and link them with the correct ISAM Manager library for your
- compiler and memory model.
-
-
- Altering The Source
-
- Now is probably a good time to familiarise yourself with some of
- the characteristics of the FScreen library, and the way MAKSCR
- writes its code. Try, for example, to edit EMPMAINT.CPP to force
- the input of dept to be upper case. You will find a copy of
- EMPMAINT.CPP listed in the USER GUIDE chapter as an example
- program.
-
- TUTORIAL 2
-
-
- Introduction
-
- In this chapter, we will be introducing another data file and
- seeing how we can link the two files together. The file we are
- going to create will hold information about the various
- departments within our hypothetical company and you should
- create a DDF file as follows called DEPT.DDF:
-
- {BEGDATA}
- DEPT.DTA
- char dept_code[2];
- char dept_name[41];
- int payrise;
- {ENDDATA}
-
- {BEGIDX}
- DEPT.DTX
- *Department Code: dept_code;
- {ENDIDX}
-
- Now follow the steps as in chapter 1 to create a screen form
- input program and enter a few departments.
-
-
- Data Validation
-
- The next thing we are going to do is to introduce some data
- validation. We now have a file containing all the departments in
- our company and it would be nice if, when entering an employee's
- department, the program was to check if that department was
- valid and if not, then give an appropriate error message.
-
- So edit the employee maintenance program (EMPMAINT.CPP) once
- again and add the department file to it. Now you will need to
- add the code to check the department file when the user inserts
- or amends and employee's record. The following function will do
- the trick:
-
- int dept_ok(void) // Validate that the dept of the currently
- { // selected employee record is correct
- strcpy(dept.dept_code, employee.dept);
- if (dept.find() == IM_OK)
- return 1; // Record found, so must be OK
- return 0; // Record not found, so return FALSE (0)
- }
-
- The rest I leave to you.
-
-
- Altering The Screen Display
-
- It would be nice if, upon entering a valid department code, the
- full name of the department is shown on the screen. As we
- already have the code for checking the department code, the
- field dept.dept_name will be automatically set whenever the
- dept_ok function is called AND succeeds in finding a record. So
- you merely have to create another function that also displays
- the contents of dept.dept_name, and then call it at all
- appropriate times. Here's an example of a function that will do
- this:
-
- void display_dept_name(void)
- {
- FSclrbox(6, 13, 6, 53, attrSCREEN);
- if (dept_ok())
- FSputs(dept.dept_name, attrINPUT, 6, 13);
- else
- FSputs("**INVALID DEPARTMENT**", attrINPUT, 6, 13);
- }
-
- The tricky bit is making sure that this function gets called at
- all the right times! Once again, I'll leave that to you.
-
- TUTORIAL 3
-
-
- Introduction
-
- In this chapter we will deal with the issue of batch processing.
- First we will write a function to produce a report and then
- adapt it to give each employee a pay rise according to the
- department he or she is in.
-
-
- Batch Processing
-
- Batch processing in the context of database programming is when
- a program processes a sequential batch of records in a file,
- possibly performing an operation on each or selected records. In
- this case, we want to award a pay rise to each employee in
- accordance with which department an employee is in, so the
- program will need to process the whole of the employee file.
- Here is an example function to process every record in the file:
-
- void process_file(void)
- {
- employee.rew(); // Rewind Employee File
-
- while (employee.next() == IM_OK) // Step through file
- {
- . // Processing for each record here
- .
- .
- }
-
- }
-
- As you can see from this example, all that is needed to do the
- job is a very simple loop. Now write a function that will step
- through the employee file and print (using fprintf(stdprn, ...))
- the Employee Number, Initials, Surname, Salary Department Code
- and Department Name (which you will need to read each time from
- the Department File) in that order. One thing to watch out for
- is that some compilers (Borland, at least) open stdprn in binary
- mode, not text mode. This means that at the end of each line,
- you will need a "\r\n" combination rather than just "\n". Add
- this function to the main bar menu of the Employee Maintenance,
- and then test it to make sure it works OK.
-
- You should now be able to confirm that your function is
- correctly processing the Employee File, so now write another
- function to increase each Employee's salary by the correct
- percentage according to Department and add this function to the
- main bar menu as well. To help you, here is the piece of code
- that will give each employee a payrise:
-
- while (employee.next() == IM_OK)
- {
- if (dept_ok()) // Function from Tutorial 2
- {
- employee.salary += (employee.salary *
- dept.payrise) / 100;
- employee.amend();
- }
- }
-
- One thing to watch out for when sequentially processing a file
- is that if you alter any fields in the current index of the file
- being processed and use amend() to amend the record, your
- position in the index will be altered and you may end up
- processing some records twice and missing others altogether. To
- avoid this, you should switch to an index whose fields are not
- going to be altered in any way by the routine. In this case we
- are OK as only the salary field is being altered, and that isn't
- in the index.
-
-
- Switching Indexes
-
- Back in TUTORIAL 1, we created the EMPLOYEE.DDF file, and
- defined two indexes. Until now, we have been using just the
- default "Name" index. It's now time to make use of the "Employee
- Number" index. What we want to do is change the report function
- that we've just written to list the employees in employee number
- order. To do this, all you need to do is switch index at the
- beginning of the function, and then switch back to the original
- index at the end. The commands to do this are as follows:
-
- employee.set_idx("Employee Number"); // Switch to Employee
- // Number index
- employee.set_idx("Name"); // And switch back again
-
- So put these commands in the code, re-compile and make sure all
- works well.
-
- ISAM MANAGER FUNCTION REFERENCE
-
-
- Introduction
-
- This is a guide to all the functions provided by the IsamMgr
- system which come under the broad category of 'file related'
- functions. Their prototypes and return value constants are all
- defined in the header file isammgr.h with the exception of
- clear_buf which is defined in a header file created by DDF. The
- functions are public members of the class IsamMgr, from which
- your file classes are derived.
-
-
-
- --------------------------------------------------------------
-
- amend
-
- Function Amends current record.
-
- Prototype int IsamMgr::amend(void)
-
- Explanation This function updates the currently selected record
- with the value of its field variables. The effect is similar to
- an erase followed by an insert except that the index cursor
- still points to the same record.
-
- Return value IM_OK or IM_ERROR if no record selected or index
- conflict.
-
- See also insert and erase.
-
- --------------------------------------------------------------
-
- clear_buf
-
- Function Clears the contents of the field variables.
-
- Prototype void IsamMgr::clear_buf(void)
-
- Explanation Clears the contents of the field variables to enable
- data to be entered for use by find or insert. Can also be used
- to clear the data displayed after erasing the current record.
-
- Return value None.
-
- --------------------------------------------------------------
-
- close
-
- Function Closes current file.
-
- Prototype void IsamMgr::close(void)
-
- Explanation Closes the current data and index files. This should
- be done before running another program to safeguard the files.
- There is also a limit of 20 open files imposed by DOS that may
- require the use of this function.
-
- Return value None.
-
- See also open
-
- --------------------------------------------------------------
-
- erase
-
- Function Erases current record.
-
- Prototype int IsamMgr::erase(void)
-
- Explanation The currently selected record is erased. The field
- variables will remain unchanged, and the index cursor position
- will be undefined, except that the next() function is guaranteed
- to take you onto the next record.
-
- Return value IM_OK or IM_ERROR if no record selected.
-
- See also amend, clear_buf and insert.
-
- --------------------------------------------------------------
-
- find
-
- Function Finds record.
-
- Prototype int IsamMgr::find(void)
-
- Explanation Attempts to find a record whose index exactly
- matches that of the field variables for the currently selected
- index. If the find is successful, the record data is retrieved
- into the field variables. If the find fails, then the cursor is
- placed on the next closest record in the index, which is not
- retrieved.
-
- Return value IM_OK or IM_ERROR if no exact match found.
-
- --------------------------------------------------------------
-
- get_cur_idx
-
- Function Get currently selected index number.
-
- Prototype int IsamMgr::get_cur_idx(void)
-
- Explanation Returns the number of the index currently in use.
-
- Return value Index number.
-
- --------------------------------------------------------------
-
- get_idx_name
-
- Function Get name of index number.
-
- Prototype char *IsamMgr::get_idx_name(int idxno)
-
- Explanation Returns a pointer to the name of the index number
- idxno.
-
- Return value The name of the currently selected index.
-
- --------------------------------------------------------------
-
- get_no_idxs
-
- Function Get number of indexes for file.
-
- Prototype int IsamMgr::get_no_idxs(void)
-
- Explanation Returns the number of indexes for the current file.
-
- Return value No of indexes.
-
- --------------------------------------------------------------
-
- insert
-
- Function Inserts new record.
-
- Prototype int IsamMgr::insert(void)
-
- Explanation Inserts new record into file and updates all indexes
- on that file.
-
- Return value IM_OK or IM_ERROR if index duplicated.
-
- See also amend and erase.
-
- --------------------------------------------------------------
-
- next
-
- Function Moves file cursor to next record in index.
-
- Prototype int IsamMgr::next(int no_recs = 1)
-
- Explanation Moves index cursor for the current index no_recs
- forward in that index and retrieves the record. If no value is
- given for no_recs, it will default to 1. no_recs must be
- positive.
-
- Return value IM_OK or IM_ERROR if end of file reached.
-
- See also prev and rew.
-
- --------------------------------------------------------------
-
- open
-
- Function Opens a file.
-
- Prototype void IsamMgr::open(void)
-
- Explanation Opens the data and index files if they are not
- already open.
-
- Return value None
-
- See also close.
-
- --------------------------------------------------------------
-
- prev
-
- Function Moves file cursor to previous record in index.
-
- Prototype int IsamMgr::prev(void)
-
- Explanation Moves index cursor for the current index no_recs
- backwards in that index and retrieves the record. If no value is
- given for no_recs, it will default to 1. no_recs must be
- positive.
-
- Return value IM_OK or IM_ERROR if beginning of file reached.
-
- See also next and rew.
-
- --------------------------------------------------------------
-
- retrieve
-
- Function Retrieves information from current record.
-
- Prototype int IsamMgr::retrieve(void)
-
- Explanation Retrieves the data contained in the currently
- selected record and places it in the field variables.
-
- Return value IM_OK or IM_ERROR if no record currently selected.
-
- --------------------------------------------------------------
-
- rew
-
- Function Moves file cursor to first record in index.
-
- Prototype void IsamMgr::rew(void)
-
- Explanation Positions the index cursor for the current index to
- the beginning of the index. Use next to move on to the first
- record.
-
- Return value None.
-
- --------------------------------------------------------------
-
- set_idx
-
- Function Sets index to use.
-
- Prototype void IsamMgr::set_idx(const char *name)
-
- void IsamMgr::set_idx(int idxno)
-
- Explanation Sets the index to use to the index named in the
- string name or the index number idxno.
-
- FSCREEN FUNCTION REFERENCE
-
-
- Introduction
-
- The FScreen Library is a collection of powerful C++ functions
- that allow you to read and write directly to the screen. This
- gives the functions a very large speed advantage over other
- functions that use DOS or BIOS to access the screen. In the
- FScreen Library are functions to allow you to create menus, open
- windows, move the cursor around the screen and other important
- functions all of which help your program to be presented as
- professionally as possible.
-
- The FScreen library is primarily provided for use by MAKSCR when
- creating quick-and-dirty data entry screens. It is not the most
- powerful screen library around, and we assume that you probably
- have your own preferred screen library already. For this reason,
- FScreen is considered as a free extra for ISAM Manager rather
- than an integral part of the system, and will not be ported to
- other platforms. For example, you will find the libraries for
- Windows 3 do not contain the FScreen functions.
-
-
- Monitor Types
-
- All monitors are supported but in 80x25 character mode only. The
- function FSinit must be called at the start of any program that
- uses FScreen functions. This detects the monitor type so that
- the direct screen access functions can make allowances for
- different screen memory locations and cater for possible 'snow'
- effects on old CGA monitors.
-
-
- Header File
-
- All function prototypes are contained in the header file
- FSCREEN.H which should be included in the relevant C++ files
- with the line:
-
- #include <fscreen.h>
-
-
- --------------------------------------------------------------
-
- FSbarmenu
-
- Function Allows selection of options via a bar menu.
-
- Prototype int FSbarmenu(int row, int col, int spaces,
- char *option[], int normcol,
- int highcol, int hotkeycol)
-
- Explanation FSbarmenu presents the user with a bar style menu
- from which options may be selected using the cursor keys or hot
- keys. The menu will be displayed on row row with spaces spaces
- between each option. The starting column will be col unless col
- is given a value of FS_CENTRE or FS_CENTER in which case the
- menu will be located centrally. The option array is a NULL
- terminated array of options of the following format: "^Option".
- The '^' character MUST be present in each option string and
- denotes the hot key letter for that option. normcol, highcol and
- hotkeycol are the colours for the main menu, the currently
- selected item and hot keys respectively.
-
- Return value IM_ERROR if an error has occurred or <ESCAPE> is
- pressed. Otherwise the option number where 0 denotes the first
- option and so on.
-
- See also FSmenu.
-
- Example #include <fscreen.h>
-
- main()
- {
- char *menopts[] = {"^Insert", "^Amend",
- "^Delete", "^Find",
- "^Next", "^Prev",
- "E^xit", NULL };
- FSinit();
- for (;;)
- {
- switch (FSbarmenu(22, FS_CENTRE, 2,
- menopts, attrBMNORM, attrBMHIGH,
- attrBMHOTK))
- {
- case 0:
- .
- .
- .
- }
- }
- }
-
- --------------------------------------------------------------
-
- FSbox
-
- Function Draws a box on the screen.
-
- Prototype void FSbox(int toprow, int topcol, int botrow,
- int botcol,int style, int attr)
-
- Explanation FSbox draws a box where the top left hand corner is
- at row toprow and column topcol and the bottom right hand corner
- is at row botrow and column botcol. The box can be any one of
- four styles dictated by the parameter style.Style HSVS is a
- single line box, HDVD is a double line box, HDVS has single
- vertical lines and double horizontal lines and HSVD has single
- horizontal lines and double vertical lines. The colour of the
- box lines is dictated by attr.
-
- Return value None.
-
- See also FSopwin and FSmenu.
-
- --------------------------------------------------------------
-
- FSclrbox
-
- Function Clears an area of the screen.
-
- Prototype void FSclrbox(int toprow, int topcol,
- int botrow, int botcol, int attr)
-
- Explanation FSclrbox clears a rectangular area of the screen
- where toprow is the row of the top left hand corner of the area,
- topcol is the column and botrow and botcol are the row and
- column respectively of the bottom right hand corner of the area.
-
- Return value None.
-
- See also FSclrscr and FSscroll.
-
- Example #include <fscreen.h>
-
- main()
- {
- int row, col, z;
- FSinit();
- for (row = 0, col = 0;row< 25 && col < 80;
- row++, col +=2)
- {
- FSclrbox(0, 0, row, col);
- for (z = 0; z < 32000; z++);
- }
- }
-
- --------------------------------------------------------------
-
- FSclrline
-
- Function Clears a row.
-
- Prototype void FSclrline(int row, int attr)
-
- Explanation FSclrline clears the line specified by row, setting
- the attribute to attr.
-
- Return value None.
-
- See also FSclrbox, FSclrscr and FSscroll.
-
- --------------------------------------------------------------
-
- FSclrscr
-
- Function Clears the screen.
-
- Prototype void FSclrscr(int attr)
-
- Explanation FSclrscr simply clears the screen, setting the
- attribute to attr. Like FSclrbox, it is a macro which translates
- into a call to FSscroll and is contained in the header file
- FSCREEN.H.
-
- Return value None.
-
- See also FSclrbox and FSscroll.
-
- --------------------------------------------------------------
-
- FSclwin
-
- Function Closes a window previously opened by FSopwin.
-
- Prototype int FSclwin(void)
-
- Explanation FSclwin closes the last window to be opened with
- FSopwin and restores the contents of the screen underneath the
- window area.
-
- Please note that FSopwin and FSclwin call FSreadscr and
- FSwritescr respectively. Therefore these functions should be
- used with great care if they are to be used in the same program.
- The basic rule is that is you use FSreadscr after opening a
- window, then you must use FSwritescr before closing that window.
-
- Return value IM_OK on success, IM_ERROR if you try to close a
- window when there are none open.
-
- See also FSopwin.
-
- --------------------------------------------------------------
-
- FSgetch
-
- Function Get a character from the keyboard.
-
- Prototype int FSgetch(void)
-
- Explanation This function calls the DOS interrupt service (int
- 21h) function 07h to receive unfiltered character input from the
- keyboard. This has the advantage over the standard getch()
- routine of not being responsive to <CTRL-C> being pressed.
-
- Return value The character read from the keyboard.
-
- --------------------------------------------------------------
-
- FSgetmode
-
- Function Obtains the current screen display mode.
-
- Prototype int FSgetmode(void)
-
- Explanation FSgetmode uses the BIOS interrupt service (int 10h)
- function 0Fh to obtain and return the current video mode. The
- main reason for the inclusion of this function is that it is
- used by FSinit to determine the video board in use.
-
- Return value The current video mode.
-
- --------------------------------------------------------------
-
- FSgetpos
-
- Function Obtains the current cursor position.
-
- Prototype void FSgetpos(int *row, int *col)
-
- Explanation FSgetpos uses the BIOS interrupt service (int 10h)
- function 03h to obtain the current location of the cursor. The
- row and column locations are then placed in row and col.
-
- Return value None.
-
- See also FSgotopos.
-
- Example #include <stdio.h>
- #include <fscreen.h>
-
- main()
- {
- int row, col;
- FSgetpos(&row, &col);
- printf("Cursor was located at (%d, %d)\n",
- row, col);
- }
-
- --------------------------------------------------------------
-
- FSgetstyle
-
- Function Obtain the current cursor style.
-
- Prototype void FSgetstyle(int *start, int *stop)
-
- Explanation FSgetstyle uses the BIOS interrupt service (int 10h)
- function 03h to obtain the current cursor style. The cursor
- style is described by a start and a stop value which dictate at
- which pixel line the cursor block starts and stops. For example,
- the standard start and stop values for a CGA display are 6 and 7
- respectively. FSgetstyle places these values in the variables
- start and stop.
-
- Return value None.
-
- See also FSsetstyle.
-
- Example #include <stdio.h>
- #include <fscreen.h>
-
- main()
- {
- int start, stop;
- FSgetstyle(&start, &stop);
- printf("Cursor style is (%d, %d)\n",
- start, stop);
- }
-
- --------------------------------------------------------------
-
- FSgetxy
-
- Function Returns the contents of a given screen coordinate.
-
- Prototype unsigned FSgetxy(int row, int col)
-
- Explanation FSgetxy finds the character and attribute at the
- screen location given by row and col. It is used by the
- windowing functions in order to save portions of the screen into
- memory for later recall.
-
- Return value FSgetxy returns the attribute and character at the
- specified screen location. The attribute is returned in the high
- byte and the character in the low byte.
-
- See also FSputa.
-
- --------------------------------------------------------------
-
- FSgotopos
-
- Function Sends the cursor to the specified screen location.
-
- Prototype void FSgotopos(int row, int col)
-
- Explanation FSgotopos uses the BIOS interrupt service (int 10h)
- function 02h to send the cursor to the screen location set by
- row and col which are the row and column of the cursor position
- respectively.
-
- Return value None.
-
- See also FSgetpos.
-
- --------------------------------------------------------------
-
- FSinit
-
- Function Initialises the FScreen system.
-
- Prototype void FSinit(void)
-
- Explanation FSinit determines what screen display adapter is
- present, and sets the global variable FSdisplaymode accordingly.
- The possible values are:
-
- 0 - EGA, VGA or other adapter.
- 1 - CGA adapter.
- 7 - Hercules / Mono adapter.
-
- Return value None.
-
- --------------------------------------------------------------
-
- FSinput
-
- Function Allow input and/or editing of character strings,
- characters, integers and long integers at a given point on the
- screen.
-
- Prototype int FSinputs(char *string, int attr, int startrow,
- int startcol, int length, int forceflag,
- const char *contents)
-
- int FSinputl(long &value, int attr, int startrow,
- int startcol, int length, long minval,
- long maxval)
-
- int FSinputul(unsigned long &value, int attr,
- int startrow, int startcol, int length,
- unsigned long minval,
- unsigned long maxval)
-
- int FSinputi(int &value, int attr, int startrow,
- int startcol, int length, int minval,
- int maxval)
-
- int FSinputui(unsigned int &value, int attr,
- int startrow,int startcol, int length,
- unsigned int minval, unsigned int maxval)
-
- int FSinputc(char &value, int attr, int startrow,
- int startcol, int length, int minval,
- int maxval)
-
- int FSinputuc(unsigned char &value, int attr,
- int startrow, int startcol, int length,
- unsigned char minval,
- unsigned char maxval)
-
- Explanation These functions provide a user input facility for
- character strings and numbers in various forms. Common to each
- function are the variables startrow, startcol, attr and length
- which specify the starting position of the editing area, colour
- and length of input respectively. The variable length has no
- default for character strings and must be specified. When using
- FSinputs, if forceflag is set to TOUPPER or TOLOWER then the
- input is forced to upper case or lower case respectively. The
- variable contents should point to a string containing values
- which are acceptable input. If the string begins with the
- character "^" then those characters listed will be those that
- are not allowed to be input. The numerical input functions can
- be used for single byte numbers (FSinputc & FSinputuc), two byte
- numbers (FSinputi & FSinputui) and four byte numbers (FSinputl &
- FSinputul). In each case the variables length, minval and maxval
- default to appropriate figures but can be set as required.
-
- Return value FS_CURSORUP, FS_CURSORDOWN, FS_BACKSPACE, FS_ENTER,
- FS_ESCAPE, FS_PGUP or FS_PGDN depending on the key pressed to
- exit the input field.
-
- --------------------------------------------------------------
-
- FSmenu
-
- Function Presents user with a scroll bar menu.
-
- Prototype int FSmenu(int toprow, int topcol, int style,
- char *options[], int normcol, int highcol)
-
- Explanation FSmenu pops up a menu for the user to make a
- selection from. The row and column of the top left-hand corner
- of the menu are toprow and topcol respectively. The function
- FSbox is called to draw the box using a line style of style.
- options is a NULL terminated array of char pointers which point
- to the option lines. normcol and highcol are the colours for the
- menu and the currently selected item respectively.
-
- Return value Either the number of the option selected where the
- first option is number 0, or IM_ERROR if <ESCAPE> pressed.
-
- See also FSbarmenu.
-
- --------------------------------------------------------------
-
- FSopwin
-
- Function Opens a window on the screen.
-
- Prototype int FSopwin(int toprow, int topcol, int botrow,
- int botcol, int style, int attr)
-
- Explanation A window is opened on the screen where the
- coordinates of the top left-hand corner are toprow and topcol
- and the coordinates of the bottom right- hand corner are botrow
- and botcol. A box is drawn on the perimeter of the window of
- style style and colour attr. The window may subsequently be
- closed by using the FSclwin function. A maximum of 50 windows
- may be opened at any given time.
-
- Please note that FSopwin and FSclwin call FSreadscr and
- FSwritescr respectively. Therefore these functions should be
- used with great care if they are to be used in the same program.
- The basic rule is that, if you use FSreadscr after opening a
- window, then you must use FSwritescr before closing that window.
-
- Return value IM_ERROR if an error occurs, otherwise IM_OK.
-
- See also FSclwin, FSbox, FSreadscr and FSmenu.
-
- --------------------------------------------------------------
-
- FSprompt
-
- Function Asks a Yes/No type question.
-
- Prototype int FSprompt(char *question, int attr, int row)
-
- Explanation The string "(Yes/No)? " is appended to question
- which is then echoed to the screen using the attribute attr
- centralised on row row. The function FSyesno is then called and
- its value returned.
-
- Return value 1 if "Yes" answered or 0 if "No" answered.
-
- See also FSyesno.
-
- --------------------------------------------------------------
-
- FSputa
-
- Function Sets a screen area to a given attribute value.
-
- Prototype void FSputa(int attr, int row, int col, int length)
-
- Explanation The screen area starting at the coordinates row, col
- for length characters has its attributes set to attr.
-
- Return value None.
-
- See also FSputs, FSgetxy.
-
- --------------------------------------------------------------
-
- FSput
-
- Function Write a string or number to the screen.
-
- Prototype void FSputs(char *string, int attr, int row, int col)
-
- void FSputl(long value, int attr, int row, int col)
-
- void FSputul(unsigned long value, int attr, int row,
- int col)
-
- void FSputi(int value, int attr, int row, int col)
-
- void FSputui(unsigned int value, int attr, int row,
- int col)
-
- void FSputc(char value, int attr, int row, int col)
-
- void FSputuc(unsigned char value, int attr, int row,
- int col)
-
- Explanation These functions put a number or string on the screen
- in the colour attr starting at the coordinates row, col. Use
- FSputs for a string, FSputc or FSputuc for single byte numbers,
- FSputi or FSputui for two byte numbers and FSputl or FSputul for
- four byte numbers.
-
- Return value None.
-
- See also FSputa.
-
- --------------------------------------------------------------
-
- FSreadscr
-
- Function Save the contents of an area of the screen.
-
- Prototype int FSreadscr(int toprow, int topcol, int botrow,
- int botcol)
-
- Explanation The contents of a rectangular area of the screen
- where the coordinates for the top left-hand corner are toprow
- and topcol and those for the bottom right-hand corner are botrow
- and botcol are read into an internal buffer which is malloc'ed
- by the function.
-
- Please bear in mind that this function is called by FSopwin and
- so extreme care needs to be taken when mixing calls to both
- functions.
-
- Return value IM_ERROR if the maximum no of windows have been
- opened (see FSopwin) or there is no available memory. Otherwise
- IM_OK.
-
- See also FSwritescr, FSopwin and FSmenu.
-
- --------------------------------------------------------------
-
- FSscroll
-
- Function Scrolls area of screen.
-
- Prototype void FSscroll(int toprow, int topcol, int botrow,
- int botcol, int rows)
-
- Explanation FSscroll calls the BIOS interrupt service (int 10h)
- functions 06h or 07h to scroll the area of the screen specified
- by toprow, topcol, botrow and botcol rows amount of rows. If
- rows is zero, the screen area is cleared.
-
- Return value None.
-
- See also FSclrbox and FSclrscr.
-
- --------------------------------------------------------------
-
- FSsetstyle
-
- Function Sets the cursor style.
-
- Prototype void FSsetstyle(int start, int stop)
-
- Explanation FSsetstyle use the BIOS interrupt service (int 10h)
- function 01h to set the current cursor style to start at
- position start and end at position stop.
-
- Return value None.
-
- See also FSgetstyle.
-
- --------------------------------------------------------------
-
- FStitle
-
- Function Puts a string centrally on the screen.
-
- Prototype void FStitle(char *string, int attr, int row)
-
- Explanation FStitle is a pre-processor macro which translates
- into a call to FSputs to put the string string centrally located
- on row row with a colour attribute of attr.
-
- Return value None.
-
- See also FSputs.
-
- --------------------------------------------------------------
-
- FSwritescr
-
- Function Restores screen contents saved by FSreadscr.
-
- Prototype int FSwritescr(int toprow, int topcol, int botrow,
- int botcol)
-
- Explanation The contents of the buffer saved by the last call to
- FSreadscr are restored to the screen within the area specified
- by toprow, topcol, botrow and botcol. Note that calls to
- FSreadscr and FSwritescr can be stacked. That is, a call to
- FSwritescr removes the last buffer created by FSreadscr and so
- the next call to FSwritescr will restore the contents saved by
- the previous call to FSreadscr.
-
- Please bear in mind that this function is called by FSclwin and
- so extreme care needs to be taken when mixing calls to both
- functions.
-
- Return value IM_ERROR if no buffers on the stack. Otherwise
- IM_OK.
-
- See also FSreadscr, FSopwin, FSclwin and FSmenu.
-
- --------------------------------------------------------------
-
- FSyesno
-
- Function Asks Yes/No question.
-
- Prototype int FSyesno(int attr, int row, int col)
-
- Explanation FSyesno waits for the user to press 'Y' or 'N' and
- echoes the response in full to the screen at position row, col
- using attribute attr.
-
- Return value 1 if answer is "Yes". 0 if answer is "No".
-
- See also FSprompt.
-
-