Dec 092017
 
Paragen documentation. Part 2 of 3.
File PDOCD.ZIP from The Programmer’s Corner in
Category Paradox DBMS
Paragen documentation. Part 2 of 3.
File Name File Size Zip Size Zip Type
PARAGEN.DOC 257735 55522 deflated

Download File PDOCD.ZIP Here

Contents of the PARAGEN.DOC file


















PARAGen

Version 2.2



A Code Generator for the

Paradox Engine






(c) 90,91 Innovative Data
Solutions, Inc.









INNOVATIVE DATA SOLUTIONS, INC.
4318 STEWART COURT
EAST CHICAGO, IN 46312

Information in this document is subject to change without notice and does
not represent a commitment on the part of Michael G. Mlachak, or Innovative
Data Solutions, Inc. The software described in this document is furnished
under a license agreement or nondisclosure agreement. The software may be
used or copied only in accordance with the terms of the agreement. No part
of this manual may be reproduced or transmitted in any form or by any
means, electronic or mechanical, including photocopying and recording, for
any purpose other than the purchaser's personal use without the written
permission of Michael G. Mlachak, or Innovative Data Solutions, Inc. This
document contains proprietary information which is protected by copyright
laws.




(c) Copyright 90, 91 by Michael G. Mlachak and Innovative Data Solutions, Inc.

All Rights Reserved












Paradox, Paradox Engine, Turbo-C, Turbo-C++, Borland C++ and Turbo Pascal
are registered trademarks of Borland International

Microsoft C, and Microsoft Windows are registered trademarks of Microsoft
Corporation

Mewel Window System is a registered trademark of Magma Software Systems

WordPerfect 5.1 is a registered trademark of WordPerfect Corporation

HP Series II is registered trademark of Hewlett Packard



This manual was produced with WordPerfect 5.1, on an HP Series II LaserJet
Printer

Printing History : _____________________________

First Edition - August 1990
Second Edition - March 1991
_____________________________

TABLE OF CONTENTS

INTRODUCTION
Contents of this Manual
Tables, Figures and Diagrams
About PARAGen
Typefaces Used in this Manual
Contacting Innovative Data Solutions
System Requirements
Features
USING PARAGEN
Installing PARAGen
Function Names and Data Types
Function Overview
Table Functions
Record Functions
Network Functions
Working with the User Interface
Running PARAGen
PARAGen Quick-Start
The Main Menu Screen
Maneuvering the Interface
Keyboard
Accelerators
The Mouse
Dialog Boxes and Controls
Radio Buttons
Check Boxes
Scroll Bars
Scroll Lists
Input Controls
Push Buttons
Main Menu Options
The System Button
Restore
Move
Size
Minimize
Maximize
Close
Table
Open
Create
Clear
Exit
About Paragen
Functions
Table
Record
Network
All
Clear
Fields
Options
Customize
Your Name
Project Name
Do_it!
A QUICK LOOK AT THE CODE
A SAMPLE PROGRAM
THE VIDLIB PROGRAM
CURRENT PRICES
PARAGen FUNCTION REFERENCE
RELEASE NOTES
APPENDIX
Text Messages of Functions in the Function Area
Warning Messages
Error Messages

TABLES FIGURES AND DIAGRAMS

System requirements
PARAGen features
Installation program
PARAGen data types
Table functions
Record functions
Network functions
PARAGen main menu
Radio button control
Check box control
Scroll bar control
Scroll list control
Input control
Push button control
System button
Table option
Table | Open dialog box
Table | Create dialog box
Table | Create field dialog box
Table | Create dialog box with field entries
Functions option
Functions | Table dialog box
Functions | Record dialog box
Functions | Network dialog box
Function area with tagged functions
Fields Option
Field select dialog box
Options option
Code generation option dialog box
Brace styles
Error function generation
Customize option
Customize | Your Name dialog box
Customize | Project Name dialog box
Do_it! option
Do_it! dialog box
PARAGen compiling hints
PARAGen comment block
PARAGen access structure
PARAGen handles
PARAGen function prototypes
PARAGen sample program
VIDLIB program
PARAGen current prices

ABOUT PARAGEN

Welcome to PARAGen, a software tool designed to make you, the PARADOX
programmer, more productive. PARAGen running under either DOS or WINDOWS
3.0 expedites the creation of C, C++, and Pascal code for accessing your
PARADOX applications. Instead of writing hundreds or perhaps thousands of
lines of code, PARAGen will generate the code for you based on existing
PARADOX tables already in place. You spend more time writing application
code, instead of writing low level PARADOX Engine code.

PARAGen with its simple, yet masterful designed menu system is easy to use.
It's as simple as running PARAGen against your tables, identifying which
PARADOX Engine functions you wish generated, and then compiling the
generated code. The source produced by PARAGen is properly prototyped and
commented for the specific language you specify. See the features section
for a broader overview of the language specific features.

This software tool becomes especially useful in the early phases of
development, when it is not uncommon for PARADOX data structures to change.
Since PARAGen produces separate code for each table, a table change simply
requires re-running PARAGen against the new table, and then re-compiling
and re-linking your application. The code generated by PARAGen can be
compiled and used in object form, or it may be built into a library.
Either, may be linked to your application specific code.

PARAGEN assumes you are at least partly familiar with the PARADOX Engine.

TYPEFACES USED IN THIS MANUAL

Table | Open The | between the two choices signifies that this is an
option that can be selected off the main menu screen or
menu bar. The T in table and O is underlined and in
bold type to signify these are options keyboard
accelerators.

TABLENAME The word TABLENAME refers to the current working table
on the work space in PARAGen. All references to
TABLENAME should be replaced with the actual table. If
FOOBAR.DB, is on the workspace then references to
TABLENAMEOpen and TABLENAMEClose in the manual and
reference section, are really FOOBAROpen and
FOOBARClose.

BOLDFACE or BoldFaceThis typeface is used to start a new section, and to
make the user(s) aware of notes of interest, and
special circumstances. It is also used to label
captions in diagrams and tables.

Underline This typeface is used designate the choices of a pull
down menu. For example when explaining what the Table
| Open option does, the Open is underlined.
Underlining can also be used in conjunction with
boldface above for special circumstances.

Italics Italics are used to show points of interests on menu
screens and dialog boxes. Usually used in conjunction
with lines, italics show how a particular menu item,
dialog box, or control operates in the current context.

KEYCAPS This typeface indicates a key on your keyboard. It is
often used to describe a particular key you should
press. (For example, hit ENTER to make a choice).

CONTACTING INNOVATIVE DATA SOLUTIONS, INC.

You can telephone Innovative Data Solutions, Inc., Technical Support
department between 7 AM and 5 PM Central time at (219) 397-8952. Please
have the following handy before you call:

Product name and serial number on your original distribution
disk. Please have your serial number ready, or we won't be able
to process your call.

Product version number. The version number for PARAgen is
available on the main menu from the Table | About ParaGen option.

Computer brand, model, and the brands and model numbers of any
additional hardware.

Operating system and version number. (The version number can be
determined by typing VER at the MS-DOS prompt, for the DOS
version of PARAGen. The WINDOWS version requires MICROSOFT
WINDOWS 3.0).

Contents of your AUTOEXEC.BAT file.

Contents of your CONFIG.SYS file.

You may also FAX bug reports, installation problems, and comments to above
number. If you prefer, write a letter with your comments and send it to:

Innovative Data Solutions, Inc.
Technical Support Department, PARAGen
4318 Stewart Court
East Chicago, IN 46312, USA

Support is also available through COMPUSERVE, at 76327,1410. Leave your
questions or comments there using MAIL, for the support staff to process.

SYSTEM REQUIREMENTS

____________________________________________________________
| |
| DOS WINDOWS |
| DOS 3.1 or higher Microsoft Windows 3.0 |
| 512K Ram 250K Ram |
| PARADOX Engine 1.0, 2.0 (*) PARADOX Engine 2.0 (*) |
| |
| LANGUAGES and COMPILERS SUPPORTED |
| |
| Borland C Family : Turbo-C 2.0, Turbo-C++, Borland C++ |
| Borland Pascal Family: Turbo Pascal 5.5, 6.0 |
| Microsoft C Family : Microsoft C 5.1, 6.0 |
| |
| NETWORK SUPPORT |
| |
| All networks that PARADOX supports. (See features) |
| |
|____________________________________________________________|


The information box above shows the system requirements needed for PARAGen.
PARAGen now supports three languages, seven compilers, and has built in
network support. NOTE: In order to link and compile the Pascal, or C++
specific code generated by PARAGEN, you will need version 2.0 of the
Engine. All Windows applications also require version 2.0. Version 2.0 of
the Engine, only supports standard and 386 enhanced mode under Windows 3.0.
Therefore PARAGen will not run in real mode. Version 1.0 of the Engine can
be used only if PARAgen generates C code.

FEATURES

The following tables, highlight some of the features of PARAGen version
2.2. These tables list the overall features as well as the code generation
features.


PARAGen Overall Features [2]
_________________________________________________________________________
| |
| Reduce hundreds of lines of hand coded low-level Engine calls to a |
| single function call |
| DOS and Microsoft WINDOWS versions available |
| Multiple language support for C, C++, and Pascal |
| Easy to use interface looks and feels the same in DOS and WINDOWS |
| Built in File Manager, to access tables on any drive and directory |
| Generate source code for only the functionality you want |
| DOS version supports 43 and 50 line modes |
| Support for up to 255 fields per table |
| Support for an unlimited number of tables |
| Works on keyed and encrypted tables |
| Create a new table right within PARAGen, no need for PARADOX |
| Customize source code generated, based on numerous options |
| Built in network support for the following networks: |
| IBM Token Ring, PC network with IBM PC Local Area Network Program |
| (1.12 or higher) |
| Novell Advanced Netware (2.0A or higher) |
| 3Com 3+ network |
| 3Com 3+Open network |
| Banyan Vines network (2.10 or higher) |
| AT&T StarGROUP (3.1 or higher) |
| Detailed run-time reference manual of PARAGen generated functions |
| Source code is available |
| Single set of source code, runs in both DOS & WINDOWS (see current |
| prices section for more info) |
| Example programs and make files included |
| Demo version is available for $5.00 |
| Royalty free, with all language features for only $129.00 |
| Both, DOS and WINDOWS versions available for $175.00 for a limited |
| time |
| ________________________________________________________________________|


PARAGen Code Generation Features [3]
_________________________________________________________________________
| |
| Allows code to be generated for a table you create in PARAGen |
| Generates C, C++ and Pascal source code |
| C and C++ generated header files contain ANSI prototypes |
| A separate C, CPP, H and HPP file are generated for each table |
| C and C++ code can be generated with 4 different brace styles |
| Pascal code is generated into a UNIT with the PARADOX table name |
| All functions generated use the PARADOX table name as a prefix |
| C and Pascal record structures are generated that correspond to the |
| actual PARADOX table |
| Code can be generated for speed or size |
| Code can be generated with or without tabs |
| Code can be generated with various degrees of error checking |
| Code can be generated to treat BLANK fields as doubles |
| All internal Engine errors go through a user defined function, which |
| can be modified |
| Field specific code is generated only for fields you choose |
| Generates a comment block with the project, programmer, #fields, key |
| fields, #records, etc. |
| Generates 14 table related functions |
| Generates 16 record related functions |
| Generates 10 network related functions |
|_________________________________________________________________________|

INSTALLING PARAGEN

The PARAgen diskette contains all the packed files needed to install
PARAGen. You MUST use the installation program to install PARAGen.
PARAGen can only be installed under DOS. To install PARAgen put the
distribution diskette in one of the floppy drives, change to that drive,
type PARAINST and hit the ENTER key. A screen similar to the one shown
below should appear:

___________________________________________________________________________
| |
| |
| |
| |
| PARAGen Installation Program (Version 2.2) |
| (C) Copyright 90, 91 Innovative Data Solutions, Inc. |
| |
| |
| |
| |
| |
| |
| |
| |
| Installation Directories for PARAGen Code Generator |
| |
| Directory for PARAgen Executable C:\PARAGEN |
| Directory for PARAGen demo(s) C:\PARAGEN\DEMO |
| |
| Type Directory Name ESC-Exit F2-Change Drive F10-Install |
| |
| |
| |
| |
|___________________________________________________________________________|


Simply type the names of the directories where the demo programs, and
PARAGen will be installed, and then hit F10. You can use the UP and DOWN
arrow keys, to move between directories. NOTE: If you already have an
installed version of PARADOX or PARADOX runtime that is included in your
DOS PATH, you might consider placing PARAGEN in one of those directories.
A pop up drive menu is available with F2, if you wish to change the drive
specification. If the directories you specify do not exist, the
installation program will place check marks next to these, and ask you for
permission to create them. Answering yes, proceeds with the installation,
while no allows you to re-input the above information.

Once the directories and drives are checked for the proper amount of disk
space, you will be asked for the PARAGen serial number. Type in the serial
number EXACTLY as it is on the disk label. Once the serial number is
verified, the installation program will un-pack the proper files.

You should see a screen similar to the one below:


___________________________________________________________________________
| |
| |
| |
| PARAGen Installation Program (Version 2.2) |
| (C) Copyright 90, 91 Innovative Data Solutions, Inc. |
| |
| UnPacking PARAGen Files |
| |
| % COMPLETION |
| |
| 100 Method: Crushed |
| 90 CRC : B046 |
| Install 80 or |
| 70 File : PARAGEN.EXE |
| Directory for PAR 60 Size : 382609 |
| Directory for PAR 50 Date : 02-20-1991 |
| 40 Time : 01:10PM |
| Type Director 30 Bytes : 73576 -Install |
| 20 |
| 10 |
| |
| ..Please Wait.. |
| |
|___________________________________________________________________________|


As the files are unpacking themselves you will see the method that was used
to pack the file, the CRC, the name of the file, the actual unpacked file
size, the date of the file, the time of the file, and the number of bytes
un-packed. A completion bar will appear to the left of the above
information, showing a visual representation of the activity so far. Once
the files are un-packed you will get a completion message box that shows
the drive and directory PARAGen was installed on, and a brief description
that explains how to run it.

WINDOWS users should see Chapter 4 of the PARADOX Engine 2.0 Users Guide.
It is important that the Dynamic Link Library (DLL) of Engine functions be
installed and the PARADOX Engine be configured, or PARAGen will not run.

If you are having problems or the installation program did not complete,
call Innovative Data Solutions, Inc. at (219)-397-8952, between the hours
of 9-5. NOTE: Once the installation program is run, PARAGen can not be
re-installed, unless you de-install it first. To do this, place the
original diskette in a floppy drive, change to that drive and type the
following, PARAINST /U , where path is the full path of where PARAgen
was installed. (EX: PARAINST /U C:\PARADOX). A message appears on the
screen letting you know, if the de-install process was successful.

FUNCTION NAMES and DATA TYPES

Function names that are generated by PARAGen are based upon your PARADOX
table name and the names of the fields in your PARADOX table. Please note
that although PARADOX allows you to specify field names with embedded
spaces and punctuation, PARAGen takes a dim view of such matters. PARAGen
will strip out all blank characters and replace all control and punctuation
characters of a field name with an underscore when it finds them. This is
to ensure that the field name used in the access structure will be
syntactically correct, and that the language in question (C, C++, or
Pascal), can compile it. You can continue to use field names embedded with
spaces and punctuation as long as you recognize that in this instance, that
the access structure names will not correspond exactly to the field names.
An example will illustrate the point much better. If your table is named
FOOBAR.DB, then the Open and Close functions generated by PARAgen would be
FOOBAROpen and FOOBARClose respectfully. If FOOBAR.DB, contains two fields
named Invoice Amount (type double) and # Items (type short), then a record
structure will be generated that contains the following structure
definition:

_________________________________________________________________
| |
| C,C++ Pascal |
| |
| typedef struct foobarentry { FOOBARENTRY = Record |
| double InvoiceAmount; InvoiceAmount : Double; |
| short _Items; _Items : Integer; |
| } FOOBARENTRY; END; |
|_________________________________________________________________|


Notice that the punctuation and control characters in the original field
names were replaced with underscores (_), and all blanks were stripped.


The following table gives an overview of how the PARADOX field types
correspond to the PARAgen access structure data types.

__________________________________________________________________________
| | | | |
|PARADOX | PARAgen | PARAGen | Field Type Explanation |
|Field Type | Pascal | C, C++ | |
| | Type | Type | |
|------------|-----------|-----------|-------------------------------------|
|Alpha (Axxx)| String | char [] | Alphanumeric (EX: A85) |
| | | | Any combination of characters and |
| | | | spaces up to specified width. |
| | | | Maximum width is 255 |
|------------|-----------|-----------|-------------------------------------|
|Numeric (N) | Double | double | Numbers with or without decimal |
| | | |digits |
|------------|-----------|-----------|-------------------------------------|
|Currency ($)| Double | double | Currency Amounts |
|------------|-----------|-----------|-------------------------------------|
|Date (D) | Integer | integer | Dates in the form mm/dd/yy, |
| | | | dd-mon-yy, or dd.mm.yy |
|------------|-----------|-----------|-------------------------------------|
|Short (S) | Integer | short | Nums < 32,767,no decimals allowed |
|____________|___________|___________|_____________________________________|


PARAGen treats dates as three separate record or structure entries.
Each of these is an integer corresponding to month, day, year. (See
Access Structure, for more info.)

FUNCTION OVERVIEW

PARAGen generated functions can be classified into three categories. These
are Table Functions, Record Functions, Network Functions. A brief overview
of each type of function follows. When looking at the function tables,
please remember that the actual word TABLENAME that appears in dark print,
will be replaced by the PARADOX table you want to generate code for. Some
of these functions may also take parameters. The intent here is to give a
brief overview to those who are not familiar with the PARADOX Engine. For
a more detailed description of each function with examples, please see the
PARAGen Reference guide.

TABLE FUNCTIONS

___________________________________________________________________________
| | | |
|PARAGen Function | Engine Call(s) | Description |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEOpen | PXTblOpen | |
| | PXRecBufOpen | |
| | PXFldHandle | Opens a table with or without |
| | | password protection |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEClose | PXTblClose | Closes a table |
|-------------------|-----------------|-------------------------------------|
|TABLENAMECreate | PXTblCreate | |
| | PXKeyAdd | Creates a table |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEEmpty | PXTblEmpty | Empties the records from the |
| | | specified table |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEDelete | PXTblDelete | Deletes the table and its family |
|-------------------|-----------------|-------------------------------------|
|TABLENAMECopy | PXTblCopy | Copies one table family to another|
|-------------------|-----------------|-------------------------------------|
|TABLENAMERename | PXTblRename | Changes the base name of a table |
| | | family |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEAdd | PXTblAdd | Adds records from one table to |
| | | another table |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEEncrypt | PXTblEncrypt | Encrypts a table |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEDecrypt | PXTblDecrypt | Decrypts a table |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEExist | PXTblExist | Tests if a table exists |
|-------------------|-----------------|-------------------------------------|
|TABLENAMEProtected | PXTblProtected | Tests if a table is encrypted |
|-------------------|-----------------|-------------------------------------|
|TABLENAMETblNRecs | PXTblNRecs | Finds the number of records in a |
| | | table |
|-------------------|-----------------|-------------------------------------|
|TABLENAMERecNum | PXRecNum | Finds the current record number in|
| | | a table |
|___________________|_________________|_____________________________________|


RECORD FUNCTIONS

__________________________________________________________________________
| | | |
|PARAGen Function | Engine Call(s) | Description |
|------------------|----------------------|--------------------------------|
|TABLENAMESrchKey | [1] PXRecBufEmpty | Searches a table based on a |
| | PXSrchKey | key or partial key match |
| | [2] PXDateEncode | |
| | [3] PXPutDoub | |
| | [3] PXPutDate | |
| | [3] PXPutAlpha | |
| | [3] PXPutShort | |
| | [4] PXDateDecode | |
| | [5] PXRecGet | |
| | [5] PXGetDoub | |
| | [5] PXGetDate | |
| | [5] PXGetAlpha | |
| | [5] PXGetShort | |
|------------------|----------------------|--------------------------------|
|TABLENAMESrchFld | PXSrchFld | Searches a table based on a |
| | PXFldHandle | specific field |
| | [3] and [5] above | |
|------------------|----------------------|--------------------------------|
|TABLENAMERecFirst | PXRecFirst, [3] above| Moves to the first record in a |
| | | table |
|------------------|----------------------|--------------------------------|
|TABLENAMERecNext | PXRecNext, [3] above | Moves to the next record in a |
| | | table |
|------------------|----------------------|--------------------------------|
|TABLENAMERecPrev | PXRecPrev, [3] above | Moves to the previous record in|
| | | a table |
|------------------|----------------------|--------------------------------|
|TABLENAMERecLast | PXRecLast, [3] above | Moves to the last record in a |
| | | table |
|------------------|----------------------|--------------------------------|
|TABLENAMERecAppend| PXRecAppend, [1] and | Appends a record to a table |
| | [5] above | |
|------------------|----------------------|--------------------------------|
|TABLENAMERecInsert| PXRecInsert, [1] and | Inserts a record into a table |
| | [5] above | |
|------------------|----------------------|--------------------------------|
|TABLENAMERecDelete| PXRecDelete | Deletes the current record |
|------------------|----------------------|--------------------------------|
|TABLENAMERecUpdate| PXRecUpdate, [1] and | Updates the current record |
| | [5] above | in a table |
|------------------|----------------------|--------------------------------|
|TABLENAMERecGoto | PXRecGoto | Moves to a specified record |
|------------------|----------------------|--------------------------------|
|TABLENAMERecGet | [1] and [3] above | Transfers current record to the|
| | | record transfer buffer |
|------------------|----------------------|--------------------------------|
|TABLENAMEFldType | PXFldType | Gets the field type for a given|
| | | field handle |
|------------------|----------------------|--------------------------------|
|TABLENAMEFldBlank | PXFldBlank | Tests if a field is blank |
|------------------|----------------------|--------------------------------|
|TABLENAMERecNFlds | PXRecNFlds | Finds the number of fields |
|------------------|----------------------|--------------------------------|
|TABLENAMEKeyNFlds | PXKeyNFlds | Finds the number of key fields |
|__________________|______________________|________________________________|


NETWORK FUNCTIONS

________________________________________________________________________
|| | |
|PARAGen Function | Engine Call(s) | Description |
|-----------------------|-----------------|------------------------------|
|TABLENAMENetRecLocked | PXNetRecLocked | Determines whether a record |
| | | has been locked |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetTblChanged | PXNetTblChanged | Tests if a table has changed|
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetTblRefresh | PXNetTblRefresh | Resynchronizes a table |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetTblUnlock | PXNetTblUnlock | Unlocks a table |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetTblLock | PXNetTblLock | Locks a table |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetRecUnlock | PXNetRecUnlock | Unlocks a record |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetRecLock | PXNetRecLock | Locks a record |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetRecGotoLock| PXNetRecGotoLock| Returns to a previously |
| | | locked record |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetFileUnlock | PXNetFileUnlock | Unlocks a file |
|-----------------------|-----------------|------------------------------|
| | | |
|TABLENAMENetFileLock | PXNetFileLock | Locks a file |
|_______________________|_________________|______________________________|

The functions generated by PARAGen almost always correspond to the PARADOX
Engine call. This makes it easy to determine what function needs to be
generated. A table in the APPENDIX shows a cross reference of the
relationship of the text used in the PARAGen system and the actual PARAGen
function generated. This should also aid in determining what function
needs to be generated.

WORKING WITH THE USER INTERFACE

PARAGen was re-designed from the ground up to be easier to use. It is now
an event driven interface that allows complete keyboard and mouse
interaction. This enables you, the user to process your PARADOX tables
faster by pointing, clicking and choosing. With this new version, the
whole process from opening a table, to picking the functions to be
generated, to generating the code for that table, should take only a few
minutes.

The interface is the same in the DOS and WINDOWS versions, so users moving
to the WINDOWS environment will not have a steep learning curve. This is
made possible by using the MEWEL WINDOW SYSTEM from Magma Software Systems
for the DOS version and the MICROSOFT WINDOWS SDK for the WINDOWS version.
The same source code runs under both versions. Many thanks go to Marc
Adler, from Magma Software, whose help was invaluable.

RUNNING PARAGEN

The DOS version of PARAGen is a stand alone product that requires no other
files. To run it change to the directory that contains the PARAGen
executable (PARAGEND.EXE) and type PARAGEND. If your DOS path already
contains the directory where the PARAGen executable resides, just type
PARAGEND.

The Windows version of PARAGen requires that the Dynamic Link Library (DLL)
of Engine functions (PXENGWIN.DLL) be installed and the PARADOX Engine be
configured, or it will not run. Please see INSTALLING PARAGEN for more
info. Once installed properly, the PARAGen executable PARAGENW.EXE can be
run several ways.

From the File Manager, move to the directory where you installed PARAGen
and locate the file PARAGENW.EXE. Double click, and PARAGen should run.
Another way to run PARAGen is from the File Menu. Click on the Run option,
and type in the full path where you installed PARAGen along with the
executable name (PARAGENW.EXE). An icon for PARAGen is supplied on the
installation diskette for those who want to add PARAGen to an new or
existing program group.

Once you run PARAGen, the main menu should appear and look similar to the
screen below.

PARAGen by Innovative Data Solutions, Inc.
Table Functions Fields... Options... Customize Do_it!...


FUNCTIONS





Function Area - Functions selected to be generated go here
(EX: Open Table
Table Exists?
Append a Record)





Table Name
Number of Fields
Number of Key Field
Project and Programmer Number of Records






Programmer: Not Specified
Project : Not Specified





PARAGEN QUICK-START

The PARAGen quick-start is for users who do not have the patience to wade
through a 100+ page manual.

To generate code for a PARADOX table, use the Table | Open option to select
the table to process. You may also create a new one from scratch by using
the Table | Create option. If you are creating a new table, that table is
made current once you create it. Next, you have to select the functions
you want to generate. You do this by choosing the Function | Table,
Function | Record, Function | Network, or Function | All option. Place
(X's) next to the functions you want to generate. If you are planning to
use PARAGen to search for fields in the table, and the fields you want to
search on are not key fields, you must select the Fields option. Select
the fields you want to place in the search function. If you do not choose
any fields, PARAGEN will issue a warning message during code generation,
telling you it was unable to generate the TABLENAMESrchFld function. Next,
set the code generation options that will be used for this session by
selecting the Options menu. If you want project and programmer information
to appear in the source code, you must choose the Customize option.
Choosing the Customize | Your Name option to change the programmer
information and the Customize | Project Name option to change the project
information. The last step in the process is to choose the Do_it! option
and generate the code. NOTE: The above section proceeds left to right on
the main menu bar starting with Table and ending with Do_it!. You may now
clear out the current working table by selecting the Table | Clear option,
or change the options and functions to be generated for the current table.

THE MAIN MENU SCREEN

The main menu consists of a window with a title across the top, and a menu
bar with the following pull down menu items: A Table option, a Function
option, a Field option, an Options option, a Customize option and a Do_it!
option. Only the Table option is active. This is because the other
options are only relevant to an open table, and the table has not been
opened yet. Items that are grayed in menus and options throughout PARAGen
are inactive by default, and will not process. This aids the user in
determining what can and can not be chosen. In the upper left hand corner
of the window, a () appears. This is the system menu button. The area
between the two lines is the function area. This is where the functions
you pick to be generated will appear. Only the text representation of the
functions generated will appear here. Towards the bottom left of the screen
is an area that holds programmer and project information. Towards the bottom
right, even though is does not display on this screen, is an area that holds
the current table name, number of fields in the table, number of key fields
in the table, and number of records in the table.

The System menu button contains these choices: Restore, Move, Size,
Minimize, Maximize, and Close.

The Table option contains these choices: Open, Create, Clear, Exit, About
PARAGen.

The Functions options contains these choices: Table, Record, Network, All,
Clear.

The Fields, Options and Do_it! options contain no choices, but display
various dialog boxes.

The Customize option contains these choices: Your Name, Project Name.

A detailed explanation of all options, choices and dialog boxes appears in
the following sections.

MANEUVERING THE INTERFACE

The user interface of PARAGen was designed to be easy to use. Moving
around, making choices, and selecting options can be done basically in
three ways. Using the keyboard, using special keys called accelerators to
process certain options, and using the mouse.

KEYBOARD

When using the keyboard, the TAB, LEFT, RIGHT, UP, and DOWN arrow keys can
be used to move throughout the main menu system and pull down options. ESC
will exit the current process. As you are moving, the choice you are on
will be highlighted. To make a selection simply hit the ENTER key. In
dialog boxes the TAB key will always take you to the next valid option.
This could be another section, or a terminating button response. Again
ENTER will choose the appropriate action. (See the section on Dialog Boxes
for more info).

ACCELERATORS

PARAGen supports the concept of key accelerators. On various options, and
menu items you will see a single letter, a colored letter, or an underlined
letter of a choice or option that stands out from the rest. This is known
as an accelerator. For example the Table option on the main menu bar has
the T highlighted. Accelerators are fast ways of processing options,
without having to maneuver through the menu system. If the accelerator is
on the main menu bar, or inside a dialog box, like the Table option above,
then a combination of the ALT key and the accelerator will process the
option. If the accelerator is on a pull down menu, then the accelerator
key alone is enough to process the option.

THE MOUSE

PARAGen also supports a mouse. The LEFT mouse button on a mouse will make
a choice. If the choice selected has a drop down menu like the Table
option on the main menu bar, then by holding the LEFT button down you can
drag the highlight bar over the various choices. To make a choice simply
let go of the LEFT button. The LEFT button also works in dialog boxes, to
select options and make choices.

DIALOG BOXES AND CONTROLS

A dialog box is a pop-up box that is used for obtaining additional input
from the user beyond what can easily be managed through a menu. All menu
items in PARAGen that invoke a dialog box are indicated by an ellipsis
(...) that has been added to the menu item. Therefore the Fields...,
Options..., and Do_it!... choices of the main menu bar have some sort of
dialog box processing. All dialog boxes in PARAGen are modal. This means
the user cannot switch between the dialog box and another window. The user
must explicitly end the dialog box, usually by clicking a push button
marked either OK or Cancel.

Inside a dialog box are controls, each of which initiate some specific
action. PARAGen uses the following controls: Radio buttons, Check boxes,
Scroll bars, Scroll lists, Input, and Push Buttons. An explanation of each
type of control and how it applies to PARAGen follows.

Radio Button Control

Language
( ) Turbo / Microsoft C
( ) Turbo C++
(X) Turbo Pascal



A radio button group control is used to indicate mutually exclusive
options. Only one button or option can be chosen by using the mouse LEFT
button or the keyboard UP and DOWN arrows and hitting SPACEBAR. When this
happens an (X) or circle is placed in the space provided to turn the button
option on. In this example case PARAGen uses radio buttons to chose the
Language to generate code for. Only one Language (Turbo Pascal) is chosen.



Check Box Control

Network Functions

[X] Record Locked?
[ ] Table Changed?
[ ] Table Refresh
[X] Table Unlock All None
[ ] Table Lock
[ ] Record Unlock
[ ] Record Lock OK Cancel
[ ] Go To Lock
[ ] File Unlock
[ ] File Lock





A check box control is a square box with text. The text usually appears to
the right of the check box. The check box functions as a toggle switch.
Clicking the box once with the LEFT mouse button or using the keyboard
SPACEBAR causes an [X] to appear. Clicking or hitting the SPACEBAR again
on the choice causes the [X] to toggle off. More than one item can be
toggled ON or OFF. In this example case PARAGen uses check boxes to choose
which network functions to generate code for. Only the Table Unlock and
Record Locked? functions will be generated.


Scroll Bar Control

Tabs/Spaces
[ ] Use Tabs

Spaces per TAB: 5


Thumb
Arrows

Scroll bars are positioned vertically (for up and down movement) or
horizontally (for left and right movement). You can click with the mouse
on the arrows at each end of a scroll bar or use the arrow keys. A "thumb"
travels the length of the scroll bar to indicate the approximate location
of the material shown in relation to the maximum and minimum amount
allowed. You can also drag the thumb with the mouse to move to a
particular setting. In this example a horizontal scroll bar is used to set
the TAB size for generated code. This scroll bar only becomes active if
the Use Tabs check box is not checked.


Scroll List Control
Highlight Bar

ORDER.DB
[-A-]
[-B-]
[-C-] Arrows
[-D-]
[-E-]



Scroll lists are a collection of text strings displayed as a scrollable
columnar list within a rectangle. PARAGen allows the user to either add,
remove, or select one of these text strings, depending on the situation.
Processing takes place by either double clicking on a choice or using the
keyboard ENTER key. To move or scroll through the list, click on the
arrows at each end of the list, or use the UP and DOWN arrow keys to move
the highlight bar. In this example a scroll list is used by the Table |
Open option to allow the user to select the PARADOX table to open.


Input Control

New Table Name

ORDER Input
Area

OK Cancel




Input controls are usually used for single line entry fields. The user is
usually asked for some type of information, that is processed later on.
Once inside an input, control the user usually types the information
requested. Full edit capabilities are allowed, which means the LEFT and
RIGHT arrow keys can be used to travel through the input string. The
DELETE key will erase the current character under the cursor while the
BACKSPACE key will erase the character to the left of the cursor. The
INSERT key will place you in overwrite mode, thus allowing input to
overwrite what is already there. PARAGen uses input controls to obtain
string and numeric input. In this example, a string input control is used
by the Table | Create option to obtain a new table name. This will be used
later when we create the new PARADOX table.
Push Button Control


Open


Cancel


<< Add Field Above..


>> Delete Field.....



Push button controls are used mostly to trigger an immediate action without
retaining any type of ON/OFF indication. If a push button begins with a (
<< ) or ( >> ), it usually means that this button is tied through a dialog
box to further processing. To select a push button, use the TAB key to
move the desired button and hit ENTER, or move the mouse to the desired
button and click the LEFT button. The buttons to the right, show some of
the buttons used in PARAGen. Open, is the button used in the Table | Open
option, to open the specified table. The Cancel button does nothing or
will undo what was already done. The OK button usually means proceed with
the next step. Two other buttons are shown that are used by the Table |
Create option. Both of these buttons will invoke dialog boxes. The first,
will call a dialog box to add a field to the field list above the current
field, while the second one will delete the current field from the list.
The ( << and >> ) are quite apparent here.)


MAIN MENU OPTIONS

An attempt will be made now to explain how PARAGen operates. Starting with
System button and ending with the Do_it! option, we will proceed by going
into great detail of how each option operates. Along the way will get into
a lengthy discussion of dialog boxes and controls. Please make sure you
have read, or at least browsed through, the DIALOG BOXES and CONTROLS
section above.

SYSTEM BUTTON

The System menu button contains these choices: Restore, Move, Size,
Minimize, Maximize, and Close. The diagram below shows where the System
button is located on the main menu, and its options .


System Button Title Bar

PARAGen by Innovative Data Solutions, Inc.
nctions Fields... Options... Customize Do_it!...
Restore
Move
Size
Minimize
Maximize

Close



The System button menu is invoked by clicking once on the button or using
the keyboard ALT SPACEBAR. Be careful not to double click on the button.
This is a quick way of getting completely out and closing down the PARAGen
application. It is the same as the Close option discussed below. Once the
menu is invoked you can click on any choice or use the UP and DOWN arrows
to move to a choice and hit ENTER. Some of the menu choices will be
grayed, because they are not active at this point. Some dialog boxes may
also contain the System Button with one or more of the following choices:

The Restore option is initially grayed and is used only to restore the
PARAGen application to its initial screen size after it has been shrunk
down to an icon. You can restore the application to its original screen
size by double clicking on the icon or using the ALT SPACEBAR sequence to
bring up the System menu and choosing Restore. This choice is valid in
both WINDOWS and DOS versions. In the DOS version you can only use the ALT
SPACEBAR to bring up the System menu after you have shrunk PARAGen to an
icon.

The Move option allows you to move the PARAGen window anywhere on the
screen. This is accomplished by using the keyboard arrow keys,UP, DOWN,
LEFT, and RIGHT. You can also use the mouse to move the window by clicking
the LEFT button on the title bar of the application (see above), holding
the LEFT button down and moving the window to a new position. You should
see an outline of the whole window as it moves. This choice is valid in
the WINDOWS and DOS version.


The Size option allows you to size the window PARAGen is defined in to a
different size. This is accomplished by using the keyboard arrow keys UP,
DOWN, LEFT, and RIGHT. You can also use the mouse to size the window by
clicking the LEFT button on a side of the window, holding the LEFT button
down and sizing the window to a ne position. You can also click a corner
of the window, hold the LEFT button down and size the window vertically and
horizontally at the same time. This choice is valid in the WINDOWS and DOS
version.

The Minimize option allows you to shrink the PARAGen application down to an
icon. This is helpful if you need the memory occupied by PARAgen to
process other applications. An icon is supplied for the WINDOWS version
while the DOS version puts a pseudo icon in the bottom right hand corner.
To restore PARAgen, use the Restore option. This choice is valid in both
DOS and WINDOWS versions. Please see the note above on the Restore option.

The Maximize option is the opposite of the Minimize option. It will take
PARAgen and make it occupy the whole screen. To restore PARAGen to its
default size, use the Restore option. This choice is valid for both DOS
and WINDOWS versions. The DOS version is already full screen when it
starts, so this choice really has no affect. It is here for compatibility
purposes.

The Close option will terminate the PARAgen application. There is no
confirmation before the program is terminated. NOTE: Use this option with
care, because all work you have done up to this point may be lost. (Please
also see the Table | Exit option).

TABLE OPTION

The Table option contains these choices: Open, Create, Clear, Exit, About
PARAGen. This option allows you to manage existing PARADOX tables, create
new ones, or clear existing ones. The advantage here is that you do not
need PARADOX to create a new table. The diagram below shows where the
Table option is located on the main menu, and its options .


PARAGen by Innovative Data Solutions, Inc.
Table Functions Fields... Options... Customize Do_it!...

Open...

Create...

Clear

Exit

About Paragen...



The Table | Open option presents a dialog box that allows you to open a
PARADOX table that already exists. The open dialog box looks similar to
the screen below:


Table Open

Open Table Name:

*.db File Spec


Tables in:F:\PARAGEN\MASTER


SAMPLE Arrow Open
FOOBAR
[-A-] File & Directory List
[-B-]
[-C-] Cancel
[DEMO] Arrow



The Open dialog box contains Open and Cancel push buttons. A static field
(Tables in:), is used to display the current disk drive and directory path.
An edit field (Open Table Name:), allows you to type in a filename, with an
optional file spec. The file specification defaults to *.DB, since PARADOX
tables use this extension for its data base files. The open dialog box
also contains a list box that displays all the files matching the file
specification (*.DB), all valid disk drive letters, and all child
subdirectories of the current drive and directory. All drives in the list
are preceded with a dash and are followed by a dash and enclosed in
parenthesis (EX: [-C-]). All subdirectories are also enclosed in
parenthesis (EX:[BETA]). Valid PARADOX files show up exactly like they
would if you used the DOS dir command, except the extension is stripped
off.

To open a file simply click the mouse on the file name (if it is in the
current directory), or change directories by double clicking on the new
directory or drive. You may also type in the full path and filename in the
File Spec area. You may scroll through list of files and directories, by
using the UP and DOWN arrow keys, or you can use the mouse to click on the
arrows on the scroll bar. The highlight bar should move and the list
should change, as well as the edit field and static directory field
mentioned above. Follow the directories by double clicking until you reach
the directory where the file is located. If you are using the keyboard use
the TAB key to get to the list box, then use the arrow keys (UP and DOWN)
to reach the file. You may change directories by hitting the ENTER key,
and repeating the process above. Once you reach the filename the edit
field mentioned above should contain the filename and extension. To open
the file you MUST choose the Open button, by clicking on it, or using the
TAB key to get to it and hit ENTER. If the Table name you specified is
protected, you will get another dialog box that prompts you for a password.
Type in the password in the space provided. If the file was opened
successfully, and you did not see any error messages, the dialog box should
clear and all of the menu bar options should now be active. A list of
error messages appears in the Appendix. If you want to quit for any
reason, or made a mistake just click on the Cancel button or TAB to it and
hit ENTER.

The Table | Create option presents a dialog box that allows you to create a
new PARADOX table that does not exist. This option starts out by asking
you via a dialog box, the name of the new table. The dialog box should
look something like the screen below:


New Table Name

Input
Area

OK Cancel Exit
Buttons


Enter the name of the new PARADOX table in the input area. The new name
may contain a path or a drive and a path. Use the mouse LEFT button to
click on the OK button, or use the TAB key to get to the OK button and hit
ENTER. NOTE: PARAGen will try to verify that the path or directory and
path are valid; it does not create them. If the input field is not valid,
you remain in the input area and are allowed to re-type the information.
If you made a mistake or want to exit use the mouse LEFT button to click on
the Cancel button, or use the TAB key to get to the Cancel button and hit
ENTER.

The next step is to obtain the field names, field types, key fields and
other information for setting up the new PARADOX table. This is done with
the create dialog box, which looks similar to the screen below:


Create New Table
Field Names: [ ] Current Field Data Type

<< Edit Field.......

Field List
Area << Add Field Below..


<< Add Field Above..


>> Delete Field.....

Action Buttons

Create Cancel Exit Button



The Create dialog box contains Create and Cancel push buttons. A static
field (Field Names:), is used to display the current data type for the
specified field, more on this later. This dialog box also contains four
other push buttons. Two of these buttons add fields to the list box on the
left, one deletes the specified field and one edits the current field. The
first three buttons Edit Field, Add Field Below, and Add Field Above will
invoke yet another dialog box to get the field name, type, and determine
whether the field is a key field. The list box which is to the left of the
four buttons mentioned above will contain the field names as you want them
to appear in the new PARADOX table.

Creating a table is easy. Simply start out by adding a field. It does not
matter if you choose the Add Field Above or Add Field Below option, because
no fields have been defined yet. Use the LEFT mouse button to click on one
of the above buttons. You may also use the TAB key to get to the proper
button and the hit ENTER. A new dialog box should appear on top of the
create dialog box. It should look something like the screen below:


Field Name/Type/Key Specification
Field Name:

Field Name

Field Types
( ) Dollars
(X) Numeric
( ) Short Field Type
( ) Date
( ) Alphanumeric [4]
Alpha Scroll
Bar
[ ] Key Field Key Field


OK Cancel Exit Buttons



When you enter this Field Name/Type dialog box you are sitting in the Field
Name edit field. The mode you entered the dialog box in, determines what
happens next.

If you entered in Add mode, then simply type the name of the new field you
want to add. Use the TAB key with the UP and DOWN arrow keys or mouse to
position yourself to the Field Type group box. Choose the data type for
this field by using the SPACEBAR or mouse LEFT button. If the field you
have chosen is an alphanumeric field, use the scrollbar to set its width.
Click the mouse on the arrows or use the TAB key to position to the
scrollbar and then use the LEFT or RIGHT arrows. The width field next to
the alphanumeric field should change as you move the scrollbar. See PARAGen
data types for more information on PARAGen and PARADOX data types. Next
determine if this field should be a key field. NOTE: Key fields must be
grouped together and must start in the first field. PARAgen will allow you to
place key fields anywhere in the list, but when you try to create the
table, you will get an error message. This was done intentionally, because
this is the way that PARADOX operates. Click on the Key Field check box to
make this field a key field. If you are using the keyboard, TAB down to
the Key Field check box and hit the SPACEBAR. An (X) should appear next to
the Key Field.

If you entered in Edit mode, the Field Name field should contain the name
of the field and the data type should be set as well as the key field if it
was chosen. Feel free to change any option, by using the steps outlined
above.

When you are done Adding or Editing use the TAB key or mouse to get to the
OK button and choose it by clicking or hitting ENTER. If you made a
mistake or want out for any reason simply choose the Cancel button.

If you Added or Edited a field, the list box will get updated with the new
field information, as well as the static Field Name data type field. To
Edit a field use the TAB key with the UP and DOWN arrows to get to the list
box or the LEFT mouse button to select the field name from the list. As
you move through the list the current choice should be highlighted. The
current data type for this field is also displayed next to the Field Name
field. PARAGen displays the field data types just like PARADOX does. (see
data types for more info). Choose the Edit Field button and go through the
steps mentioned above.

The Add Field Below button will add a field below the highlighted field in
the field list box. The Add Field Above button will add a field above the
highlighted field in the field list box.

The Delete Field button works almost the same as the Edit Field Option.
Use the TAB key with the UP and DOWN arrows to get to the list box or LEFT
mouse button to select the field name to delete from the list. It should
be highlighted. A message box should appear confirming that you really
want to delete the field. Answering Yes will delete the field, anything
else has no effect.

Here is the original Create option dialog box after six fields have been
entered. Notice that the highlightbar is on the third field in the field
list and that the current data type is N*, which is a numeric key.

Create New Table
Field Names: [ N* ]

Invoice Date << Edit Field.......
Invoice Number
Catalog Number
Ship Via << Add Field Below..
Unit Price
Discount
<< Add Field Above..


>> Delete Field.....



Create Cancel



The Create button on the above screen will be used to create the new table.
If there was an error during processing you will be presented with a
message and returned back to the Create dialog box. This enables you to
correct the error without having to re-enter all the field information
again. If the Create was successfull, the table will be opened, and the
main menu options become active. In our example above, fields one, two,
and three must be key fields or PARAGen will generate an error.

The Cancel button exits the Create dialog box without saving or creating.
There is no confirmation.

The Table | Clear option will clear the current PARADOX table that is
memory and erase all function names that were to be generated from the
function name area. A message box appears confirming the action. If you
answer Yes the, table is cleared from memory, and all menu bar options
except Table become in-active. At this point the only choice you have are
to Open an existing Table or Create a new one. If you answer No to the
confirmation message, nothing changes.

The Table | Exit option will exit and terminate PARAGen. There is no
confirmation message. PARAGen will save the current code generation
options along with the Project and Programmer information. These options
get saved in a file called PARAGEN.INI. In the WINDOWS version of PARAGen,
this file will be written in the WINDOWS directory. In the DOS version,
the file gets written in the current directory.

The Table | About Paragen option display a message box with the current
PARAGen version number, copyright notice and Innovative Data Solutions,
Inc's address and telephone number.

FUNCTIONS OPTION

The Functions option contains these choices: Table, Record, Network, All,
Clear. The Functions option is the option that allows you to choose the
functions that PARAGen generates. Remember the functions are grouped into
three categories: Table, Record and Network. See the funtion tables,
and the Appendix , for a more detailed reference on choosing the
appropriate functions to be generated. Choosing a function, is as simple
as putting an (X) mark next to the functions you want generated. Once the
functions are chosen from the categories mentioned above, the text for the
checked functions is placed in the Function Area. Please see Running
PARAGen , for the exact location of the Function Area. The diagram below
shows where the Functions option is located on the main menu, and its
options.


PARAGen by Innovative Data Solutions, Inc.
Table Functions Fields... Options... Customize Do_it!...


Table...
Record...
Network...
All
Clear







The Functions | Table option presents a dialog box that allows you to
choose the table related functions that you want generated. The table
dialog box should look similar to the screen below.


Table Functions

[X] Open Table Table
[X] Close Table Functions
[ ] Create Table
[ ] Empty Table
[ ] Delete Table
[ ] Copy Table All None Action
[ ] Rename Table Buttons
[ ] Add to Table
[X] Encrypt Table OK Cancel Exit
[X] Decrypt Table Buttons
[X] Exists?
[X] Protected?
[X] Number of Records
[X] Current Record #



To choose a table function to generate, move the mouse or use the UP and
DOWN arrow keys to move to the function, and hit SPACEBAR or click on the
LEFT mouse button. An (X) should appear in the check box next to the
function, signifying that this function will be generated. Remember check
boxes can have either ON or OFF states. To turn code generation OFF for
the function, simply repeat the above process and the (X) next to the
function should disappear. Repeat the above process for all table
functions you want to generate code for.

The action buttons of All and None, are supplied to speed up the tagging
process. The All button, places (X's) next to all table functions, while
the None button erases all (X's) next to the table functions. These two
buttons can be a real time saver. Use the TAB key, or mouse to get to this
button and either click with the LEFT button or hit ENTER.

The exit button of OK, is used to place the table functions tagged into the
Function Area, and return to the main menu. The diagram following , shows
what the screen will look like after several functions have been tagged for
code generation. When you return back to the table dialog box, PARAGen
remembers which functions you have tagged, and they should have an (X) next
to their name. If you made a mistake, or for some reason you want to get
out, use the Cancel button. It will undo all of the action that took place
during this session, and place all (X's) in their previous state. Use the
TAB key, or mouse to get to this button and either click with the LEFT
button or hit ENTER.

The Functions | Record option presents a dialog box that allows you to
choose the record related functions that you want generated. The record
dialog box should look similar to the screen below.

Record Functions

[ ] Search Key Record
[X] Search Field Functions
[X] First Record
[X] Next Record
[X] Previous Record
[X] Last Record
[X] Append a Record All None Action
[X] Insert a Record Buttons
[X] Delete a Record
[ ] Update a Record OK Cancel Exit
[ ] Go To a Record Buttons
[X] Get a Record's Value
[ ] Get a Field Type
[X] Field Blank?
[X] Number of Fields
[ ] Number of Key Fields



To choose a record function to generate, move the mouse or use the UP and
DOWN arrow keys to move to the function, and hit SPACEBAR or click on the
LEFT mouse button. An (X) should appear in the check box next to the
function, signifying that this function will be generated. Remember check
boxes can have either ON or OFF states. To turn code generation OFF for
the function, simply repeat the above process and the (X) next to the
function should disappear. Repeat the above process for all record
functions you want to generate code for. NOTE: If you opened a table with
the Table | Open option and the table does not have any key fields, the
Search Key and Number of Key Fields functions above will be grayed. Since
these two functions are only specific to keyed tables, code for them code
can not be generated, unless the table is keyed. PARAGen will not allow
you to tag either function, if the table is not keyed.

The action buttons of All and None, are supplied to speed up the tagging
process. The All button, places (X's) next to all record functions, while
the None button erases all (X's) next to the record functions. These two
buttons can be a real time saver. Use the TAB key, or mouse to get to this
button and either click with the LEFT button or hit ENTER.

The exit button of OK, is used to place the record functions tagged into
the Function Area, and return to the main menu. The diagram following ,
shows what the screen will look like after several functions have been
tagged for code generation. When you return back to the record dialog box,
PARAGen remembers which functions you have tagged, and they should have an
(X) next to their name. If you made a mistake, or for some reason you want
to get out, use the Cancel button. It will undo all of the action that
took place during this session, and place all (X's) in their previous
state. Use the TAB key, or mouse to get to this button and either click
with the LEFT button or hit ENTER.


The Functions | Network option presents a dialog box that allows you to
choose the network related functions that you want generated. The network
dialog box should look similar to the screen below.


Network Functions

[X] Record Locked? Network
[ ] Table Changed? Functions
[ ] Table Refresh
[X] Table Unlock All None Action
[ ] Table Lock Buttons
[ ] Record Unlock
[ ] Record Lock OK Cancel Exit
[X] Go To Lock Buttons
[ ] File Unlock
[ ] File Lock



To choose a network function to generate, move the mouse or use the UP and
DOWN arrow keys to move to the function, and hit SPACEBAR or click on the
LEFT mouse button. An (X) should appear in the check box next to the
function, signifying that this function will be generated. Remember check
boxes can have either ON or OFF states. To turn code generation OFF for
the function, simply repeat the above process and the (X) next to the
function should disappear. Repeat the above process for all network
functions you want to generate code for.

The action buttons of All and None, are supplied to speed up the tagging
process. The All button, places (X's) next to all network functions, while
the None button erases all (X's) next to the network functions. These two
buttons can be a real time saver. Use the TAB key, or mouse to get to this
button and either click with the LEFT button or hit ENTER.

The exit button of OK, is used to place the network functions tagged into
the Function Area, and return to the main menu. The diagram on following,
shows what the screen will look like after several functions have been
tagged for code generation. When you return back to the network dialog
box, PARAGen remembers which functions you have tagged, and they should
have an (X) next to their name. If you made a mistake, or for some reason
you want to get out, use the Cancel button. It will undo all of the action
that took place during this session, and place all (X's) in their previous
state. Use the TAB key, or mouse to get to this button and either click
with the LEFT button or hit ENTER.

The Functions | All option places all of the Table, Record and Network
functions into the Function Area and returns to the main menu. This is a
quick way of tagging all of the functions for a specific table.

The Functions | Clear option clears all of the Table, Record and Network
functions from the Function Area and returns to the main menu. This is a
quick way of clearing all of the functions for a specific table.



Here is an example of the main menu screen after several functions have
been chosen for code generation:


PARAGen by Innovative Data Solutions, Inc.
Table Functions Fields... Options... Customize Do_it!...


FUNCTIONS
Open Table Search a Field Record Locked?
Close Table First Record Table Changed?
Create Table Next Record Table Refresh
Empty Table Previous Record Table Unlock
Delete Table Last Record Table Lock
Copy Table Append a Record Record Unlock
Rename Table Insert a Record Record Lock
Add to Table Delete a Record Go To Lock
Encrypt Table Update a Record File Unlock
Decrypt Table Go To a Record File Lock
Table Exists? Get a Record's Value
Table Protected? Get a Field Type
Number of Records Field Blank?
Current Record # Number of Fields


Programmer: Michael Mlachak Table : INVOICE
Project : PARAGen Version 2.2 Fields : 8
KeyFields: 2
Records : 82



FIELDS OPTION

The Fields option will bring up a dialog box that allows you to choose the
fields that can be searched on with the TABLENAMESrchFld function. If the
fields you want to search on are part of a keyed table, you should use the
TABLENAMESrchKey function, because it is much faster. NOTE: PARAgen will
still generate the access structure with all of the fields intact. This is
in case you need the other fields for processing. Only the fields selected
will be put into the logic of the TABLENAMESrchFld generated function.
This allows you to search on multiple fields with one function. This is a
major improvement from version 1.x of PARAGen, where a single function call
was generated for each field. For more information on the TABLENAMESrchKey
and TABLENAMESrchFld function, please see the Reference Manual ,
and the section on A Quick Look at the Code.
The diagram below shows where the Fields option is located on the main
menu.


PARAGen by Innovative Data Solutions, Inc.

Table Functions Fields... Options... Customize Do_it!...
---------






Here is what the field dialog box looks like. It is explained in detail
below.


Search Field Select
Available Fields Selected Fields

Catalog Number Invoice Date
Discount Invoice Number
Ship Via
Unit Price






OK Cancel All Clear




The Fields dialog box contains OK, Cancel, All, and Clear push buttons. It
also contains two list boxes, one that contains the available fields from
the PARADOX table and, and another that will contain the fields that you
select. Only the fields that appear in the selected list will get
generated. These list boxes are labeled Available Fields and Selected
Fields respectfully. Notice that the field names in both list boxes appear
in alphabetical order. As you move the fields around, as explained below,
these list boxes remain in sorted alphabetical order.

To move an available field from the available list to the selected list
follow these steps: With the mouse, move the mouse to the field you want
to select from the available field list and hit the LEFT mouse button. The
current selection should be highlighted and the border of the available
list box will change. Double click on the highlighted choice, and the
field should move to the selected list box. If you are using the keyboard,
use the TAB key to get to the available field list box. The border should
change. Next use the UP and DOWN arrow keys to highlight the available
field to move. Hitting ENTER at this point will move the highlighted
choice to the selected list box. Repeat the above steps for each available
field you want to move.

To move a selected field from the selected list to the available list
follow these steps: With the mouse, move the mouse to the field you want
to select from the selected field list and hit the LEFT mouse button. The
current selection should be highlighted and the border of the selected list
box will change. Double click on the highlighted choice, and the field
should move to the available list box. If you are using the keyboard, use
the TAB key to get to the selected field list box. The border should
change. Next use the UP and DOWN arrow keys to highlight the selected
field to move. Hitting ENTER at this point will move the highlighted
choice to the available list box. Repeat the above steps for each selected
field you want to move.

The All button will move all of the fields from the available list to the
selected list.

The Clear button will move all of the fields from the selected list back to
the available list.

The OK button will mark the fields you have selected, save them, and exit
the dialog box. This prevents you from having to select them again, next
time you enter this option. If you enter this option again, the fields in
both the available and selected list boxes should have their previous
values.

The Cancel button will undo any changes you have made to the session so far
and exit the dialog box.

NOTE: If you do not choose any fields and the Search by Field function has
been selected, PARAGEN will issue a warning message during code generation,
telling you it was unable to generate the TABLENAMESRchFld function.

OPTIONS OPTION

The Options option will bring up a dialog box that allows you set various
PARAgen options. From within this dialog box you can set the code
generation language, the brace style, the code optimization, the engine
version, tabs or spaces, how blanks should be treated in the table, and
last but not least error function control. The options dialog box is
fairly large and complex, but it will be explained in detail. The diagram
below shows where the Options option is located on the main menu.


PARAGen by Innovative Data Solutions, Inc.

Table Functions Fields... Options... Customize Do_it!...
----------







The Options dialog box should look similar to the screen below.


Code Generation Options

Language Brace Style Optimization
(X) Turbo / Microsoft C ( ) Modified K and R ( ) Size
( ) Turbo C++ ( ) K and R (X) Speed
( ) Turbo Pascal (X) Standard C
( ) None


Engine Version Special OK
(X) 1.X ( ) 2.X [X] Treat Blank Doubles as 0.0

Error Function
Tabs/Spaces ( ) Always Called Cancel
[X] Use Tabs (X) On Error Only

Spaces per TAB: 3





The above dialog box shows the default options for PARAGen. These are C
language, standard C brace style, code generation for speed, engine version
1.x code, tabs instead of spaces, error function test on error only, and
treat doubles as blanks.

Lets examine the options more closely, starting with the Language option.

PARAGen can generate code for basically three languages: C, C++, and
Pascal. Choose the language you want to generate code for by clicking the
LEFT button of the mouse, or use the TAB key to get to the Language
section, use the UP and DOWN arrow keys to highlight the choice an then hit
SPACEBAR. NOTE: You can only generate code for one language at a time. If
you choose Pascal as your language of choice, you will notice several of
the other options become gray, and not selectable. At this time there is
no support for brace styles in Pascal and you must use version 2.0 of the
Engine. Remember PARAGen will generate separate source and header files
for C and C++ , and a Pascal unit for Pascal, that has the name of the
table you used in the Table | Open or Table | Create option. If the file
used in the Table | Open option was INVOICE.DB, the generated source will
be one of the following:

_______________________________________________________
| | ||
| Language | Source File | Header File|
|-------------------------------------------------------|
| C | INVOICE.C | INVOICE.H|
|-------------------------------------------------------|
| C++ | INVOICE.CPP | INVOICE.HPP|
|-------------------------------------------------------|
| Pascal | INVOICE.PAS | NA|
|____________________|_________________|________________|

The code generated for C++, does not contain any classes. The header file
contains the __cplusplus define wrapped around the C function prototypes.
This was done intentionally, because not even version 2.0 of the Paradox
Engine supports true C++ code, in a native class library. For more
information, see the section on a Quick Look at the Code.

PARAGen also supports four styles of braces. Each of which is unique in
its own way. Brace styles are only supported in the C and C++ language.
If the selection area is active, you may choose the brace style for the
code generation by clicking the LEFT button of the mouse, or by using the
TAB key to get to the Brace Style section, using the UP and DOWN arrow keys
to highlight the choice and hitting SPACEBAR. The diagram below shows what
the four brace styles look like on a sample section of code.
__________________________________________________
| |
|Modified K & R K & R |
| |
|if (ParagenIsGreat) { if (PargenIsGreat) { |
| BuyItNow(); BuyItNow(); |
| UseIt(Today); UseIt(Today); |
| SaveTime(Tomorrow); SaveTime(Tomorrow); |
| } } |
| |
|Standard C None |
| |
|if (ParagenIsGreat) if (ParaGenIsGreat) |
| { { |
| BuyItNow(); BuyItNow(); |
| UseIt(Today); UseIt(Today); |
| SaveTime(Tomorrow); SaveTime(Tomorrow); |
| } } |
| |
|__________________________________________________|

PARAGen provides the option of optimizing code for size or speed. All
languages can be optimized for speed or size. The first option generates a
function to populate the tables access structure, and makes calls to this
function, while the second option generates in-line code for each function
that returns an access structure to your application. There are several
factors that you should take into consideration when deciding which option
to select. Generating a function call will result in (generally) smaller
code size for your application. In cases where you are generating a large
number of functions, the object code size can be reduced greatly. On the
other hand, if you are generating a small number of functions, you may want
to choose the speed option. You will not only gain the speed benefit, but
will gain the ability to customize each function to return only the fields
you desire. Choose the optimization that you want by clicking the LEFT
button of the mouse, or use the TAB key to get to the Optimization section,
use the UP and DOWN arrow keys to highlight the choice and then hit the
SPACEBAR.

PARAGen supports both version 1.x and version 2.X of the PARADOX Engine.
If you choose version one of the Engine, PARAGen will use version one
specific variables and constants. Version two supports new features, more
control of variables, WINDOWS related information, and better ANSI
prototyping. Pascal users will not have access to this section, since
Pascal code generation is specific to version 2.X only. If you are
generating code that is going to be used use in the WINDOWS environment, it
is recommended you use version 2.X, because of the strong prototyping.
Choose the Engine version based on the Engine you are currently using.
Choose the Engine version that you want by clicking the LEFT button of the
mouse, or use the TAB key to get to the Engine Version section, use the UP
and DOWN arrow keys to highlight the choice and then hit the SPACEBAR. An
(X) should appear next to your choice.

PARAGen also allows you the flexibility of either using TABS or SPACES in
your output. If the editor you use to program has TAB support, it is
recommended that you use tabs. TABS are used by default. To turn TABS on
simply choose the Use Tabs check box by clicking the LEFT button of the
mouse, or use the TAB key to get to the Use Tabs check box, and then hit
the SPACEBAR. An (X) should appear next to your choice. If the (X) does
not appear hit the SPACEBAR again. If you would rather have SPACES in your
output instead of tabs, turn the (X) off in the Use Tabs check box, by
using the procedure above. This should activate the space scroll bar. You
may now use the mouse to click on the arrows or you can drag the thumb bar
to specify how many spaces are equivalent to one tab. The default is
three, and this number should change as you move the scrollbar. If you are
using the keyboard, use the TAB key to get down to the scroll bar and use
the LEFT and RIGHT arrow keys to set how many spaces are equivalent to one
tab. NOTE: The code that PARAGen generates is very structured. It is
possible that a very large TAB size (spaces in output) may cause errors
during compilation. This is due to the fact that all languages supported
by PARAGen have their limits for line length. If this happens, reduce the
number of spaces by two, and re-generate the code again.

PARAGen assumes by default that you want blanks treated as numbers.
PARAGen treats blank fields as numeric (0.0) by default. It does this by
using the special Engine function ISBLANKDOUBLE. All blank fields and
their associated access filled structures will contain 0.0 by default. If
you do not want this and would rather treat blanks like PARADOX would, make
sure this option is off. Use the mouse LEFT button to turn it off, or TAB
down to the Treat Blank Doubles as 0.0 field and hit the SPACEBAR. The (X)
next to the choice should disappear. CAUTION: Turning this option off may
cause unpredictable results. In C or C++ for example, the access structure
defined previously , would contain -NAN and give erroneous results. What
makes the situation even more complicated is the fact that -NAN cannot be
tested for. If you must turn this option off, you do so at your own risk
!!

PARAGen also has special error processing. It can generate code to always
process errors, or it can generate code to process errors on error only.
You must be aware of the fact that PARAGen generates an error function
called TABLENAMEError for each table, where all errors are processed. This
is a bare bones function that does basically nothing but return the PARADOX
Engine error code. Since this function acts as the central error
processor, it can be modified by the user. PARADOX Engine calls return
either a positive error, if their was an error, or SUCCESS (0). A DEFINE
and Constant are available in the C and C++ Engine header file and the
Turbo Pascal units for SUCCESS. The following section of code is from the
TABLENAMENetTblLock function and will serve to illustrate the error
processing mentioned above.

Pascal Code - Generate Error Always
____________________________________________________
| |
|INVOICERet := PXNetTblLock(INVOICETable,LockType); |
|INVOICERet := INVOICEError(INVOICERet); |
|if (INVOICERet <> PXSUCCESS) then |
| begin |
| INVOICENetTblLock := INVOICERet; |
| exit; |
| end; |
|INVOICENetTblLock := PXSUCCESS; |
| |
|____________________________________________________|

The INVOICERet error return from the PXNetTblLock function is passed to the
INVOICEError function always. If the INVOICEError function returns a
non-success we set the INVOICENetTblLock return and exit the
function, otherwise we return a success. This type of error processing
should rarely be used, because the error function even gets called on a
success. It was made available to users who requested it. The
INVOICEError function is shown further below.


Pascal Code - Generate On Error Only
____________________________________________________
| |
|INVOICERet := PXNetTblLock(INVOICETable,LockType); |
|if (INVOICERet <> PXSUCCESS) then |
| begin |
| INVOICERet := INVOICEError(INVOICERet); |
| if (INVOICERet <> PXSUCCESS) then |
| begin |
| INVOICENetTblLock := INVOICERet; |
| exit; |
| end; |
| end; |
|INVOICENetTblLock := PXSUCCESS; |
|____________________________________________________|


This type of error processing is more sensible. The INVOICERet from the
PXNetTblLock function is checked up front and only calls the error routine
INVOICEError if it was not successful. Otherwise we send the error code to
our error function, process it and set the value of the INVOICENetTblLock
function accordingly.

C, C++ Code - Generate Error Always
__________________________________________________________
| |
|INVOICERet = PXNetTblLock(INVOICETable,LockType); |
|if ((INVOICERet = INVOICEError(INVOICERet)) != PXSUCCESS) |
| return(INVOICERet); |
|return(PXSUCCESS); |
| |
|__________________________________________________________|

The same comments specified above in the Pascal Generate Always box apply
here. Remember the error function INVOICEError always gets called.

C, C++ Code - Generate On Error Only
______________________________________________________________
| |
|INVOICERet = PXNetTblLock(INVOICETable,LockType); |
|if (INVOICERet) |
| if ((INVOICERet = INVOICEError(INVOICERet)) != PXSUCCESS) |
| return(INVOICERet); |
|return(PXSUCCESS); |
|______________________________________________________________|


The same comments specified above in the Pascal Generate On Error Only box
apply here. Remember the error function INVOICEError only gets called only
on an error condition.

Pascal INVOICEError Function
______________________________________________________
| |
|FUNCTION INVOICEError(ErrCode:Integer):Integer; |
| |
|BEGIN |
| if (ErrCode > 0) then |
| INVOICEError := ErrCode; |
| INVOICEError := PXSUCCESS; |
|END; |
|______________________________________________________|

C, C++ INVOICEError Function

__________________________________
| |
|int INVOICEError(int ErrCode) |
|{ |
| if (ErrCode) |
| return(ErrCode); |
| return(PXSUCCESS); |
|} |
|_________________________________|

In C and C++, if the code optimization is set for Speed the error functions
defined above will be built into a macro (INVOICERetMacro) and called
in-line. The advantage to the above error functions or macros is that they
are totally modifiable. If you are working in the WINDOWS environment for
example, you may want to change the C and C++ INVOICEError function to
print out the text representation of the error (the PARADOX Engine has a
built in function to do so) in a message box. In some instances, the error
code probably can be ignored. In others it may not be FATAL enough to stop
processing. These are circumstances that are under your control. Please
see the PARADOX Engine manual for Engine error codes. NOTE: PARAGen will
always generate one of the above error functions. If you make changes to
it you should save it in a separate file, because next time the code gets
generated, it will get overwritten. A version that preserves all code
generation is in the works. Right now you will get a
message box that asks you for permission to overwrite the file.

CUSTOMIZE OPTION

The Customize option contains these choices: Your Name and Project Name.
This option allows you to customize the programmer and project information
that appears in a header block at the top of each source file generated.
The header block contains the following information: Project, Author,
Date, Time, Coding Style Information, Tab Type, PARADOX Table name with
number of key and non key fields, a list of the data base fields in the
table, and some generation information. The new project and programmer
information will also update the information that appears in the Project
and Programmer section on the main screen. Please see diagram on Running ,
Paragen for the exact location. The diagram below shows where the Customize

option is located on the main menu, and its options.


PARAGen by Innovative Data Solutions, Inc.
Table Functions Fields... Options... Customize Do_it!...

Your Name...
Project Name...





The Customize | Your Name option presents a dialog box that allows you to
enter your name. This information becomes the Programmer in the Project
Programmer area and the Author line in the commented source block. The
dialog box should look something like the screen below.


Programmer Name

Not Specified Input Area


OK Cancel Exit Buttons



Enter your name in the input area. PARAGen defaults to Not Specified. Use
the mouse LEFT button to click on the OK button, or use the TAB key to get
to the OK button and hit ENTER. The Programmer line in the Project
Programmer area should now contain the new name. If you made a mistake, or
want to exit use the mouse LEFT button to click on Cancel, or use the TAB
key to get to the Cancel button and hit ENTER.

The Customize | Project Name option presents a dialog box that allows you
to enter the name of the project you are working on. This information
becomes the Project in the Project Programmer area and the Project line in
the commented source block. The dialog box should look something like the
screen below.


Project Name

Not Specified Input Area


OK Cancel Exit Buttons



Enter the project name in the input area. PARAGen defaults to Not
Specified. Use the mouse LEFT button to click on the OK button, or use the
TAB key to get to the OK button and hit ENTER. The Project line in the
Project Programmer area should now contain the new project information. If
you made a mistake, or want to exit use the mouse LEFT button to click on
Cancel, or use the TAB key to get to the Cancel button and hit ENTER.

DO_IT! OPTION

The Do_it! option contains no choices. The diagram below shows where the
Do_it! option is loacted on the main menu.


PARAGen by Innovative Data Solutions, Inc.
Table Functions Fields... Options... Customize Do_it!...
---------





It presents a dialog box that generates the actual source code. This dialog
box is different from all of the others, because it presents a helpful and
visual reference as the code is being generated. This dialog box was
implemented to relieve the boredom of waiting as the code gets generated.
The Do_it! dialog box should look similar to the screen below.


Generation of Code
Message Area

Start of PARAGen Code Generation...

No. of Bytes for Operation : 0 Byte Counters
Total No. of Bytes Generated: 0 for Source

0 10 20 30 40 50 60 70 80 90 100 % Completion
COMPLETE Bar


Do_it! Action Cancel Exit
Button Button


The Do_It! dialog box contains Do_it! and Cancel push buttons. A message
area is presented across the top. Towards the middle of the dialog box you
will find some counters for the current operation and for the total number
of bytes generate so far. Underneath the byte counters is the visual
completion bar, which grows as code is being generated.

To generate code for the current table based on the options and functions
you have chosen, use the mouse LEFT button and click on the Do_it! button.
You may also use the TAB key to position yourself to the Do_it! button and
choose it by hitting ENTER. The code generation process should start
immediately. As it proceeds, the message area changes to show you the
current status and what function activity is taking place. NOTE: If you
are running on a fast machine, the messages will scroll by so fast that you
probably won't be able to see them. At the same time, the byte counters
should be getting updated and the completion bar should show you the
progress of the code generation. The Total Bytes Generated counter, is the
actual number of bytes that PARAGen has written. This includes the total
of the (.CPP) and (.HPP) files for C++, the (.C) and (.H) for C, and the
(.PAS) file for Pascal.

Once code generation is complete, the Do_it! button will change to an OK
button, and the Cancel button should become gray. To exit the Do_it!
dialog box, hit the ENTER key or use the mouse and click the LEFT button on
the OK button. You should exit back to the main menu screen.
CONGRATULATIONS: You have just generated code for your first PARADOX table.
You may now clear out the current working table by selecting the Table |
Clear option, or change the options and functions to be generated for the
current table.


A QUICK LOOK AT THE CODE

After you run PARAGen, you should see either one or two new files. These
files will appear in the directory that you used in the Table | Open or
Table | Create option. If you chose C or C++ as your target language, you
should see two files a TABLENAME.C or TABLENAME.CPP and TABLENAME.H or
TABLENAME.HPP. If Pascal was your target language you should see a file
called TABLENAME.PAS. Remember once again that TABLENAME is actually the
PARADOX table that you used in the Open or Create option above. The (.H,
or .HPP) file must be "#include"d in any of your C or C++ application code
where you wish to use the generated table functions. If you are using
Pascal, the UNIT must be must be specified in the USES statement of any
module that plans to use the generated code. NOTE: The PARADOX Engine
pascal unit name that is used by PARAGen in the USES statement of the
generated code is PXEngine. Version 2.0 of the Engine comes with two
UNITS, PXENG55.TPU which is a Turbo-Pascal 5.5 unit and PXENG60 which is a
Turbo-Pascal 6.0 unit. You MUST rename one of the UNITS mentioned above
(PXENG55 or PXENG60) to PXENGINE.TPU. The Pascal users guide that comes
with version 2.0 of the Engine states this explicitly. Your application
must also establish an access structure or record of the type defined in
the header files or unit (see below), for communicating with the generated
function calls. This access structure or record mechanism is used to pass
parameters to, and receive data from the generated functions. Remember the
above structures and records, are the equivalent of the actual PARADOX
table structure.

There are a couple of things to keep in mind when working with the
generated code. If you anticipate changing the structure of your PARADOX
table and reusing PARAGen, do NOT modify any source code in the C, C++, H,
HPP, or PAS files, unless you rename them first. PARAGen will overwrite
the current source, after a confirmation message, if you process the table
again. For the same reason, do not embed application-specific code in the
generated files -- it is generally considered a good programming practice
to 'modularize' your code. The TABLENAMERetMacro macro and TABLENAMEError
function are likely candidates for change, so remember to save copies of
these. PARADOX treats dates as long integers. This format is not
particularly useful in either 'C' or 'Pascal', therefore date fields are
converted to three integer fields, representing month, day, and year.
Other aspects of working with the code are covered later.

You can now compile the generated source. Keep the following points in
mind when you compile or link your code. The Paradox Engine manuals are
also an invaluable tool during this process, so try to keep them handy.
___________________________________________________________________________
| |
| Currently the PARADOX Engine only supports the large memory model for |
| C and C++. Compile your source using the large memory model. |
| |
| The PARADOX Engine makes use of the Pascal floating point-point types |
| Single and Double, so your Pascal programs need to be compiled with |
| the compiler directive $N+ to enable 8087 floating point code |
| generation. If you write programs to run on machines without a math |
| coprocessor, you will also want to enable the 8087 emulation compiler |
| directive, $E+. |
| |
| The Paradox Engine for Pascal loads it overlay file (PXENGINE.OVL) |
| onto the program's heap. Keep this in mind and make sure you leave |
| enough room for the overlay to load. The overlay file should be in |
| your path. If it is not in your path, you can give an explicit |
| location for it within your application using PXLoadOverlay. |
| |
| Be sure to include the (H, HPP, or Pascal UNIT) in whatever |
| application module that must accesses PARADOX. This enables type |
| checking, and makes the access structure available to you to use in |
| any module. |
| |
| If you are using make files in your develop process, make sure the |
| proper dependencies are set up based on the (H, HPP, C, CPP, and PAS |
| files). |
| |
| Remember to save your current source code if you made any changes. |
| PARAGen will always ask you if it is OK, before it starts to |
| overwrite any code. |
| |
| Compile the generated code and link with the object code, or create |
| a library by adding the object code to it. |
| |
| Have fun programming !! |
| |
|___________________________________________________________________________|

A SAMPLE PROGRAM

A sample PARADOX table INVOICE.DB is supplied on the distribution disks,
along with the code that was generated for this table by PARAGen. (See
INVOICE.C, INVOICE.CPP, INVOICE.H, INVOICE.HPP and INVOICE.PAS). We will
attempt to examine these files more closely. In an attempt to save space
we will only examine the C and C++ language aspect of the above table. We
will however, be making references to the Pascal code, and in some cases
using the actual Pascal code, so you may want to print out both versions so
you can use them as a reference.

Let's start by examining the (.H or .HPP) file. The first thing you should
notice is a header block. This header block is present at the top of every
file that PARAGen generates. It includes, the project, author, date, time,
coding style, tab style, table information, data base fields as they look
to PARADOX and PARAGen, and a generated by message. It should look
something similar to the screen below.

/*----------------------------------------------------------------
INVOICE.H Generated by PARAGen version 2.20
------------------------------------------------------------------
PROJECT : Not Specified
AUTHOR : Not Specified
DATE : 03/04/1991
TIME : 01:40PM
CODING STYLE : 2 - [Standard C]
TAB EXPANSION : ON
TABLE : INVOICE.DB - [Fields: 7, Key Fields: 2]
DATABASE FIELDS PARADOX PARAGEN
------- -------
(01) - Catalog Number CatalogNumber
(02) - Invoice Number InvoiceNumber
(03) - Invoice Date InvoiceDate
(04) - Unit Price UnitPrice
(05) - Amount Amount
(06) - Discount Discount
(07) - Ship Via ShipVia
GENERATED BY : Innovative Data Solutions, Inc. Paradox Code Generator
4318 Stewart Court
East Chicago, IN 46312
(219)-397-8952
----------------------------------------------------------------*/

Not much needs to be said about the header block. The actual field names
that are listed in the Data Base Fields, can and probably should be used
for reference. The new ANSI style end of line comment (//), was not used
for comments, because Turbo C 2.0 does not support them. The header block
looks similar for the Pascal source code, but all comments are Pascal
specific.

Following the header block are two lines of code that prevent the header
file from getting included more than once. This avoids getting duplicate
module definitions at link time. If you generated C++ code the standard
__cplusplus define is defined, to prevent name mangling of the functions.
The corresponding end of the name mangling should appear at the bottom of
the file. Both are flagged with comments for your convenience. The next
section defines some constants for the TABLENAMETblAdd and TABLENAMETblCopy
functions. These functions take parameters, and one of the parameters is
either source or destination, hence the defines. Get and Put defines are
set up for internal calls to the PARAGen functions that populate the access
structure. You need not concern yourself with these. The header file will
also will contain some defines (C, C++) or integer constants (Pascal)
called FSZxxxxx, if the field is an alpha field. The xxxxx will be replaced
by the field name that is alphanumeric. In our example, the ShipVia field
is an alphanumeric field and has a length of 10. You are probably asking
yourself, why do I need a constant? The answer is simple, if you plan to
populate this field, you need to know the maximum length it can hold. This
constant can be used for that maximum value. The Pascal code uses type
definitions for the Source, Destination, Get and Put defines above. It
also creates a global integer variable called FSZxxxxx with the field size
mentioned above.

In order to process the PARADOX Engine calls and resolve variables,
defines, and prototypes, we must include the "pxengine.h" file. Turbo
pascal users will note that PXEngine has been included in the USES
statement. Next you will notice a 'C' typedef of a structure. Pascal
users should see a record type. This is the access structure that we have
been referring to throughout this manual. It represents the access to and
from the PARADOX Engine and the PARADOX table. The sample
INVOICETABLEENTRY structure is shown below.

/*********************************************************************
'C' Access Structure
**********************************************************************/
typedef struct invoiceentry
{
double CatalogNumber; /* KEY FIELD */
double InvoiceNumber; /* KEY FIELD */
int InvoiceDateMonth;
int InvoiceDateDay;
int InvoiceDateYear;
double UnitPrice;
double Amount;
double Discount;
char ShipVia[FSZSHIPVIA+1];
} INVOICETABLEENTRY;


Note that the INVOICETABLEENTRY structure has 9 fields or records:
CatalogNumber, InvoiceNumber, InvoiceDateMonth, InvoiceDateDay,
InvoiceDateYear, UnitPrice, Amount, Discount and ShipVia. Also notice that
the first two fields are flagged as key fields, with a comment for
informational purposes. A record type is generated for Pascal users, that
has basically the same type. NOTE: Paragen uses the new modern style for
coding. That is, variables and functions will be mixed upper and lower
case. C and C++ users will have to pay strict attention to case, since
these languages are case sensitive. Pascal users should not have to worry
about case, but should try be consistent when using variables and
functions.

The CatlogNumber and InvoiceNumber fields of the structure are used to
process catalog and invoice numbers respectfully. These numbers are
numeric fields and may contain decimal points.

The InvoiceDate field, as well as all date fields, are broken up into their
component parts of Month, Day, and Year. Each one of these component parts
is processed as an integer. The reason is to make the date more accessible
in the generated language, and allow the user control on how it is
manipulated.

The UnitPrice, Amount, and Discount fields of the structure represent the
price for a single unit, the total amount of the invoice and the volume
discount in dollars. These numbers are treated as doubles and all
represent a monetary value.

The last field in the structure is the ShipVia field, an alphanumeric field
that contains the shipping method. Notice that the FSZSHIPVIA define
mentioned above is used for the character size of the array. The shipping
method can be no longer than 10 characters. The reason for the
FSZSHIPVIA+1 is because C and C++ reserve the last byte for a NULL
character. Pascal users need not worry about this, because all
alphanumeric fields are of type string.

In order to process the table, fields, and records within a table, the
PARAGen code that gets generated needs to communicate with the PARADOX
Engine calls via handles. These handles get generated next in the header
and Pascal source. The handles are global because almost every generated
function, uses these to talk to the Engine. There are basically three
types of handles: TABLEHANDLES, RECORDHANDLES, and FIELDHANDLES. The
handles from the INVOICE.PAS file are shown below.

(*----------------------------------------------------------------
Engine Handles and Global Variables
-----------------------------------------------------------------*)

VAR
INVOICETable : TableHandle;
INVOICERecord : RecordHandle;
INVOICECatalogNumber : FieldHandle; (* KEY FIELD *)
INVOICEInvoiceNumber : FieldHandle; (* KEY FIELD *)
INVOICEInvoiceDate : FieldHandle;
INVOICEUnitPrice : FieldHandle;
INVOICEAmount : FieldHandle;
INVOICEDiscount : FieldHandle;
INVOICEShipVia : FieldHandle;
INVOICERet : Integer;


The INVOICETable handle is the handle that is used to access and process
table functions, while the INVOICERecord handle is used in record related
functions. Notice each field in the INVOICE table has its own field
handle. These are used to access the data file via field specific
functions. For example if you used the INVOICESrchFld function to find all
invoices that were shipped via UPS 2 day, you must have an established
field handle for the ShipVia field. The other two global variables you
need to know about are the INVOICERet variable and the INVOICEName
constant. The INVOICERet variable is a global variable that is used to
return all PARADOX Engine calls. See pages above for an error function
and how the return code is used. The INVOICEName is a global constant that
contains the name of the PARADOX table we generated code for (INVOICE). C
and C++ users will notice there is a define wrapped around the above
handles and variables. This define GLOBAL, is set in the C and C++ source
file. This allows the handles and variables to be accessed globally by
this module. If you plan to reference any of these variables or handles
outside of the current module, the else clause of the above define sets the
handles and variables up as extern. This allows total access from any
module, and requires no intervention on your part.

The INVOICEOpen function establishes a TABLEHANDLE, a RECORDHANDLE, and
FIELDHANDLES for each field, as well as transfer buffers, so the subsequent
functions can access records and individual fields within a record. You
can see the great time savings that PARAGen has to offer by immediately
looking at the INVOICEOpen function. Imagine if your table had around
fifty or so fields. Would you like to write the code that set up the field
handles? Not only do you have to know the actual PARADOX field names, but
you have to set up or have available fifty FIELDHANDLES. Not a trivial
task, especially if the BOSS is breathing down your back, or your
application was due yesterday. You do not generally need to concern
yourself with the actual names generated for these handles. In most cases.
they are used internally by the PARAGen code. You will also notice that
key field handles are flagged with a comment for information purposes.

Last but not least in the header file, or top of the Pascal file are the
function prototypes. The compilers that PARAGen supports offer a type
checking feature for the arguments and return code in a function call.
Type checking is performed whenever an argument-type list is present in a
function declaration and that declaration appears before the definition or
use of that function. Pascal users also have to worry about type checking,
since the compiler would not let them use a function before it was defined.
Some sample prototypes from the INVOICE.H and INVOICE.PAS file appear
below.


FUNCTION INVOICEError(ErrCode:Integer):Integer;
FUNCTION INVOICETblOpen(Password:String):Integer;
FUNCTION INVOICETblClose:Integer;
FUNCTION INVOICESrchKey(SearchMode,NumKeysToSearch:Integer; var
RecordVal:INVOICETABLEENTRY):Integer;

int cdecl INVOICEError(int ErrCode);
int cdecl INVOICETblOpen(char *Password);
int cdecl INVOICETblClose(void);
int cdecl INVOICESrchKey(int SearchMode,int NumKeysToSearch,
INVOICETABLEENTRY *RecordVal);

By including the (H, HPP, or Pascal unit) in the source code that will be
compiled to access the PARADOX table, you will guarantee that the type
checking discussed above is available. Please note that some functions
take more than one parameter, and some take none at all. If you make a
mistake the compiler will catch it and complain loudly. (See the reference
manual for a more detailed function overview).

Notice that all of the functions generated by the PARAGen code generator
return an integer value. In most cases this will be the code returned by
the actual PARADOX Engine call. It is important that this return code be
checked for errors. PARAGen allows you the flexibility of overriding this
with the user defined error function. See the section on error functions
above for an in depth explanation of errors and error processing.

We will now discuss the C and C++ source file, making references to the
Pascal source when applicable.
The header comment block is the first thing present in the actual source
file. It is the same as the header block mentioned above. The BUFFERED
define in C and C++ source and the boolean constant in the Pascal source is
used to determine whether all data base writes should be buffered or not.
It defaults to FALSE. If writes are not buffered (FALSE), they get written
to disk when they happen. This is an added safety feature, and this is why
it is the PARAGen default. If writes are buffered (TRUE), the Engine
decides when it is optimal to write to disk. Following the above
information is the actual code generated by PARAGen. For every function
you tagged in the main menu, you should see a generated function in the
source. Most of the functions generated by PARAGen take pointers or
records as parameters.

Remember also that code can be generated for speed or size, so the code you
generate may not look like the demo INVOICE source supplied on the
distribution disk. The code on the disk was generated for speed, so all
references to the PXGet family of functions will happen in-line. If you
generated for size, another function called TABLENAMEPopulateRecord would
have been generated that contained the actual PXGet calls above, and a
single call to it would have been made in the source. Also note that the
generated code does not care about how to treat blank fields. This is
because all fields must be filled in by the user and there can never be a
blank field. Therefore, there is no need to generate and use the
ISBLANKDOUBLE function.

In order for you to digest the mountains of information above, we will
conclude this section by writing an application that uses the INVOICE table
above. This application DEMOINV.C and DEMOINV.PAS is also included on the
distribution diskette. This application does nothing fancy. It simply
scans the INVOICE data base table for all invoices that were sent out UPS 2
Day. The 'C' code for DEMOINV.C should look something similar to the
following screen. Special points of interest are numbered, so we can refer
to them later. The Pascal code is very similar.
__________________________________________________________________________
| |
| #include |
| #include |
| #include |
|1 #include "invoice.h" |
|2 #include "pxengine.h" |
| |
| void main(void); |
| |
| void main(void) |
| { |
|3 static INVOICETABLEENTRY Demo; |
| |
|4 if (PXInit()) |
| { |
| printf("Unable to initialize PARADOX Engine\n"); |
| exit(1); |
| } |
| |
|5 if ((INVOICERet = INVOICETblOpen(NULL)) != PXSUCCESS) |
| { |
| printf("Unable to open INVOICE table\n"); |
| exit(2); |
| } |
| |
|6 strcpy(Demo.ShipVia,"UPS 2 Day"); |
| |
|7 INVOICESrchFld(SEARCHFIRST,"Ship Via",&Demo); |
| do |
| { |
| printf("Invoice [%10.0f] Method [%s]\n",Demo.InvoiceNumber, |
| Demo.ShipVia); |
|8 } while (!INVOICESrchFld(SEARCHNEXT,"Ship Via",&Demo)); |
| |
|9 if ((INVOICERet = INVOICETblClose()) != PXSUCCESS) |
| printf("Unable to close INVOICE table\n"); |
| |
|10 if (PXExit()) |
| printf("Unable to close down PARADOX Engine\n"); |
| } |
|__________________________________________________________________________|

1 Always remember to include the table specific HEADER file or UNIT that
was generated by the PARAGen code generator in your application. This
will invoke error checking, prototype checking and allow you to use
the access structure or record for a particular table.

2 Always remember to include the PARADOX Engine header file or Turbo
Pascal UNIT. This is required by all Engine applications. It defines
global variables, types, etc., and contains the function prototypes of
all of the Engine functions.

3 Always clear out the access structure before setting up calls to any
PARAGen functions that use it. The static key word in C and C++ does
this. Pascal users will probably what to use the FillChar function to
accomplish the same result. This step is very important, especially
if you plan to use partial key (sub-key searches).

4 Always initialize the PARADOX Engine. Failure to do so, will result
in all further Engine calls failing.

5 Open the PARADOX table you plan to work with. If the table is
encrypted or protected, you may pass the password as the only
parameter. If the table is not protected or encrypted you must pass a
NULL. Pascal users may also use the password if it exists, but must
pass the NoPassword constant set up in the UNIT if the table is not
encrypted or protected. Notice that the global variable INVOICERet is
used to test the error condition. It is important that this error
return be checked, because this function sets up all of the table,
record, and field handles we talked about above. Failure to do so,
will result in all other Engine calls failing.

6 This line of code sets of the ShipVia field of the access structure or
record with the value we are going to search on. In this case it is
"UPS 2 Day".

7 This is the line that does the first search in our INVOICE table for
"UPS 2 Day". INVOICESrchFld uses the first parameter SEARCHFIRST or
SEARCHNEXT) to determine whether you are performing an initial or
subsequent search. In this case we are performing an initial search
so we set the first parameter to SEARCHFIRST. The second parameter is
the field we are going to search on. The field name must be the
actual PARADOX field name as it exists in the PARADOX table. In this
case we want to search on "Ship Via". NOTE: Remember the header
blocks of the source code show the names of the data base fields as
they exist in the PARADOX table. The last parameter is the access
structure populated with the field value we want to search on. We
populated the proper field in above. This parameter serves a dual
purpose. On input, one field of this structure contains a value to
search on, while on output the parameter gets filled with the record
found. Since I know ahead of time that the INVOICE table contains at
least four "UPS 2 Day" records, I make no attempt to check the error
return of the INVOICESrchFld function.

8 Next we go into a loop and print out the "UPS 2 Day" records as we
find them. Notice that the first parameter in the INVOICESrchFld
function has been changed to SEARCHNEXT. This enables us to find all
subsequent records. The loop terminates when we either get an error
or we can not find anymore records. Again the error code is not used
or checked. The important thing here is not how the error checking is
handled, but the fact that in five lines of code (three excluding the
two braces), we can search the whole table and print out the invoice
numbers for each "UPS 2 Day" record).

9 Always close down the table you have been working on. This frees the
table buffers, and all handles that are associated with the table. It
is a good programming practice to always do this, and not rely on the
PARADOX Engine to do so.

10 Always close down the PARADOX Engine. This also frees some internal
buffers, and does some associated housecleaning.

If you run the example program above, you should see four invoices that
were shipped via "UPS 2 Day". For a more complete example see the next
section.

THE VIDLIB PROGRAM

The distribution diskettes contain a another example of using PARAGen to
write an application. The application is called VIDLIB. VIDLIB was
designed to allow you to see some of the functions that PARAGen generated,
in action.

The VIDLIB screen should look similar to the screen below. This screen was
taken from the Pascal version of VIDLIB.


PARAGen-Video Library Demo..[Pascal Ver 1.1]
(C) 90, 91 Innovative Data Solutions, Inc.
Video Data
1-Title...: 2-Rating..:
3-Star(s).:
4-Cast....: 5-Director:
6-Company.: 7-Category: 8-Date.:

9-Price:$ 10-Tape #: 11-Run Time: 12-Format:
13-Start: 14-Stop.: 15-Rec Speed:

Options
AR-Add Record FR-First Record NT-Encrypt Table RT-Rename Table
CT-Close Table GR-Goto Record NR-Next Record SF-Srch Fld 1st
DT-Decrypt Table KF-Srch Key 1st OT-Open Table SN-Srch Fld Next
DR-Delete Record KN-Srch Key Next PT-Copy Table TT-Create Table
ET-Delete Table LR-Last Record PR-Prev Record YT-Empty Table
ER-Edit Record MT-Merge Table QU-Quit [Choice: ]

Paradox Information
File: None Records: 0 Fields: 0 Key Fields: 0 Rec No: 0
Error and Input Information




VIDLIB is a video tape library data base for DOS ONLY. The program allows
you to input the title, rating, stars, cast, director, company, category,
date, price, a tape number, run time, format, start and stop counters and
the recording speed of various video tapes. The PARADOX data base table
that drives VIDLIB is VLIB. It contains about ten data base records with
video tape information. PARAGen was used to generate the functions for
VLIB. These will be in VLIB.C, VLIB.H, and VLIB.PAS. There are also two
other files needed to build the VIDLIB application. One is VIDUTIL.C and
VIDUTIL.H, or VIDUTIL.PAS. These are low level bios routines that are used
to do screen, positioning and get input. The intent here was to try to
make VIDLIB as generic as possible. The other file that is needed is
VIDLIB.C, or VIDLIB.PAS. This is the actual code for VIDLIB. It does the
central processing, and calls the other PARAGen generated functions that
appear in the options section above. A special error function is used in
VIDLIB (VLIBError1), to show you how the standard VLIBError function can be
modified, for special purposes (See VIDLIB.C or VIDLIB.PAS).
VLIBError1 just prints out error and message information in the space
provided. (See diagram above).

Towards the top of the above diagram you will see the fields that are
supported in the VLIB table. Each one has a number next to it for input
purposes. The VLIB table contains two key fields, one for the video
category and another for the tile. This makes it easy, for example, to
find all comedies quite fast. In the middle of the screen, you will find
twenty-three options in alphabetical order arranged in four columns. In
the last column at the bottom, you will find the choice area. This is the
area that you will type in your option choice. Each option choice has a
two-letter mnemonic to the left of its title. This is the mnemonic that
you must use in the Choice area. To open the VLIB file for example, type
OT.

Underneath the options, you will find an information area and an error
message area. The information area contains information on the file you
are using, the number of records, the number of fields, and the current
record number. The error message area will show you the status of the
actual PARAGen function calls as they are being used. This area will get
updated with a different message every time you choose a different option.

To get started you must have the VLIB.DB and VLIB.PX files in the same
directory as the VIDLIB.EXE file. Type VIDLIB and you can begin to
explore. Since the data for the video tapes is stored in a table you
should start out by opening the table. The OT choice will open the video
library. The error message section should inform you of any errors. You
are positioned at the first record in the video data base, and all fifteen
fields on the screen above should have values.

Most of the choices are self explanatory, but a few need some explanation.
First, keep an eye on the record counter, it will get updated along with
all the fields every time you do something that is record related. (EX: FR,
LR, etc.). The Srch Key 1st option (KF), will prompt you for how many keys
to search on, then move you to the proper key fields to get the search
criteria. The only valid ones in the data base are (Comedy, Drama, Action,
and Musical). Once the criteria is set you do not have to set it again to
use Srch Key Next option (KN), which finds the next record. The (SF) and
(SN) options are used to search by field. (SF) searches for the first
occurrence of a field, while (SN) searches for the next occurrence. This
time you are asked which field to search on, and placed on that particular
field. Type in the required information and hit ENTER. The open option OT
does not use any password. If you encrypt the VLIB table, you will not be
able to use it again from within VIDLIB. You may of course Add a new
record by typing in information in all fifteen fields, or you may edit any
field(s) you choose. If you want the field to remain the same just hit
ENTER. In edit mode no special editing features are provided. Just type
in the new information right over the old information. (See the AR and ER
option.) Be careful with the (DT) option and the (YT) option, because
there is no confirmation before these options take effect. If you create a
table (TT), make sure you have a backup of the original table, because it
will create a new VLIB table, with no records. The rename option, will
rename VLIB to something else. Again, once it is renamed you will not be
able to re-use it from within VIDLIB. The copy and rename options (PT and
RT) use VLIB as the source in their parameter lists, and only prompt for
destination.

The VIDLIB application was intended to show you how powerful, PARAGen and
the PARADOX Engine can be together. PARAGen does most of the hard work,
thus allowing you to be more productive writing code for the actual
application. Feel free to modify the code or experiment by adding more
options. One final note: All of the functions were generated for the VLIB
table. Only a handful of them are used. You could reduce the size of the
(.EXE) file by stripping out the functions that are not called. Also
remember that using the PXErrMsg Engine function adds about 5K to your
(.EXE).

CURRENT PRICES

The current pricing scheme for PARAGen is as follows:

__________________________________________________________________________
| |
|PARAGen DOS version * : $ 129.00 |
|PARAGen WINDOWS version * : $ 129.00 |
|PARAGen DOS and WINDOWS version * : $ 175.00 |
|PARAGen Users and Reference Manual : $ 25.00 |
|PARAGen source code ** : $ 100.00 |
| |
|Commercial Site License for the Use of PARAGen |
|(Includes a diskette with programs for one OS and printed manual for each |
|computer) |
| 2 to 9 computers : $ 105.00 each |
| 10 to 24 computers : $ 95.00 each |
| 25 to 49 computers : $ 85.00 each |
| 50 to 99 computers : $ 75.00 each |
| 100 or more computers : $ 6000.00 one time fee |
| |
|All registered users will be entitled to updates for minimal charges. |
|__________________________________________________________________________|

* The DOS and WINDOWS version of PARAGen includes one printed bound User
Manual and Reference Manual. The combined DOS and WINDOWS version
includes two manuals, one for each version.

** The DOS version of the PARAGen code generator was written in Turbo C++
1.1, using only the C portion of the compiler. With a simple set of
defines, the same source code is used for both the WINDOWS and DOS
version. Complete make files are included to ease the compiling
process. The DOS version requires the MEWEL Window System version 3.3
from Magma Software. It currently supports numerous DOS C compilers.
The WINDOWS version requires the Microsoft SDK, and the Microsoft C
5.1 or higher. At the time this manual was printed, Borland
International announced a new compiler Borland C++, which was supposed
to generate WINDOWS 3.0 code. PARAGen has been fully tested with this
new compiler and it reveals no major problems. What this really means
is that one compiler can be used for both the DOS and WINDOWS version
of PARAGen.

PARAGEN FUNCTION REFERENCE

The second part of this manual provides information common to all of the
PARAGen functions.

Here you will find a reference guide, which is an alphabetical lookup of
every function that PARAGen generates. Each entry in the reference guide
contains the following:

A brief summary of what the function does
The syntax for calling the function in both C,C++ and Pascal
Where to find the prototypes, and what header file to use if any
A detailed description of how the function is implemented, how its
parameters are used, and how it relates to other PARAGen functions.
What the function returns and how important that return is
A reference list for other PARAGen related functions
An example of how the function is used, or a reference to a function
entry where there is such an example.

All functions begin with TABLENAME. Remember this should be replaced with
the actual PARADOX table that you generated code for. The function names
appear in alphabetical order, one to a page, and are displayed at the top
of each page, for easy reference. Some of the example pieces of code will
be given in C, while others will be given in Pascal. This was done
intentionally, to please both users.

The return codes discussed are the return codes that the Paradox Engine
returns. Remember, if you modify the TABLENAMEError function discussed on
previously , to trap for certain error codes or modify those error codes in any
way, then the error codes mentioned in the RETURN VALUE section of the
reference manual may not be valid or may be ignored totally. The RETURN
VALUE would contain a valid return code only if the TABLENAMEError function
has not been modified. If you are in doubt of what a valid return code is
please see the Paradox Engine manuals for more information.

FUNCTION TABLENAMEError - Process PARAGen errors

SYNTAX int TABLENAMEError(int ErrCode);
FUNCTION TABLENAMEError(ErrCode:Integer):Integer;

PROTOTYPE TABLENAME.H or TABLENAME.PAS

DESCRIPTION The TABLENAMEError function will process all PARAGen errors.
The ErrCode parameter is the error code that came from the
PARADOX Engine call. If ErrCode is greater than zero, which
signifies an error this function just returns the error back
to the calling program, otherwise it returns a PXSUCCESS.
Remember that this is the main error driver for all PARAGen
code. It may be modified to suit your specific application.
If it is modified you must save a copy of it before you
re-generate the code, or all changes will get overwritten.

RETURN VALUE Error code from PARADOX Engine call or PXSUCCESS

SEE ALSO Error Functions in users manual

EXAMPLE


INVOICERet := INVOICETblOpen(NoPassword);
INVOICERet := INVOICEError(INVOICERet);
if (INVOICERet <> PXSUCCESS) then
writeln('Unable to open Invoice table')
else
writeln("Table opened successfully');


FUNCTION TABLENAMEFldBlank - Tests if a field in TABLENAME is blank

SYNTAX int TABLENAMEFldBlank(FIELDHANDLE FldHandle,int *IsBlank);
FUNCTION TABLENAMEFldBlank(FldHandle:FieldHandle;
var IsBlank:Boolean):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMEFldBlank tests for a blank field in the field
specified by FldHandle. Field handles start at 1 for the
first field. PARAGen produces a separate field handle based
on the PARADOX field names. It has the format
TABLENAMExxxxx. Where xxxxx is the field name generated by
PARAGen. If the FldHandle argument is valid, the test sets
IsBlank to True to signify a blank field or False for a non
blank field. If the FieldHandle argument is invalid IsBlank
is False.

A blank field is a valid, special value for any numeric,
short number,alphanumeric, or date field. It means "not
known" or "not yet entered" and should not be confused with
zero (0) or NULL.

RETURN VALUE PXERR_INVFIELDHANDLE - Invalid field handle
PXSUCCESS - Success

SEE ALSO ISBLANKDOUBLE

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{
INVOICETABLEENTRY Rec;
int IsBlank;

PXInit();
INVOICERet = INVOICETblOpen("MASTER");
INVOICERet = INVOICERecFirst(&Rec);
if ((INVOICERet = INVOICEFldBlank(INVOICEShipVia,&IsBlank)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
else
{
if (IsBlank)
printf("Field is blank\n");
else
printf("Field is not blank\n");
}
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMEFldType - Gets the field type in TABLENAME for
a given field handle

SYNTAX int TABLENAMEFldType(FIELDHANDLE FldHandle,char *FldType);
FUNCTION TABLENAMEFldType(FldHandle:FieldHandle;
var FldType:NameString):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMEFldType returns the field type of the field given
by FldHandle for the table TABLENAME. The field type is
returned in the string FldType. Field handles start at 1
for the first field.

Field types are ascii strings up to 5 characters long. Date
fields have type D; numeric fields can be S ,$, or N;
alphanumeric fields are; Annn, where nnn is the width of the
field. The FldType array must be long enough to hold the
result. In C or C++, this means it must be at least 6
characters long, including the NULL terminating character.

RETURN VALUE PXERR_BUFTOSMALL - Buffer to small for result
PXERR_INVFIELDHANDLE - Invalid field handle
PXERR_INVTABLEHANDLE - Invalid table handle
PXSUCCESS - Success

SEE ALSO

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{
INVOICETABLEENTRY Rec;
char FldType[6];

PXInit();
INVOICERet = INVOICETblOpen("MASTER");
INVOICERet = INVOICERecFirst(&Rec);
if ((INVOICERet = INVOICEFldType(INVOICEShipVia,FldType)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
else
printf("Filed type for Ship Via field is %s\n",FldType);
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMEKeyNFlds - Finds the number of key fields in TABLENAME

SYNTAX int TABLENAMEKeyNFlds(int *NumKeyFields);
FUNCTION TABLENAMEKeyNFlds(var NumKeyFields:Integer):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMEKeyNFlds finds the number of key fields in the
primary index of the table specified. The number is
returned via a reference in the NumKeyFields argument. A
table with no primary index returns a 0 in NumKeyFields.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXSUCCESS - Success

SEE ALSO TABLENAMETblOpen, TABLENAMETblCreate, TABLENAMERecNFlds

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
VAR
NumKeyFields: Integer;
BEGIN

PXInit;
INVOICERet := INVOICETblOpen(NoPassword);
INVOICERet := INVOICEKeyNFlds(NumKeyFields);
if (INVOICERet <> PXSUCCESS)
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('Number of key fields in INVOICE is ', NumKeyFields);
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMENetFileLock - Locks the TABLENAME file

SYNTAX int TABLENAMENetFileLock(int LockType);
FUNCTION TABLENAMENetFileLock(LockType:Integer):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetFileLock is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit to use it. This function has an effect if the
table is shared; otherwise it always succeeds, but has no
actual effect.

TABLENAMENetFileLock locks the TABLENAME file with the lock
specified by LockType. LockType uses the following
mnemonics:

FL Full lock
WL Write lock
PFL Prevent full lock
PWL Prevent write lock

You can place multiple locks on the same table but some
locks take precedence. This function fails if other users
have imposed pre-emptive locks. (See chapter 2 of the
Paradox Users guide for more information).

To guarantee that you have absolute control over a file, you
can lock it first, then create it. The file lock endures
until you call either TABLENAMENetFileUnlock with the same
LockType to unlock it or PXExit.

RETURN VALUE PXERR_FILEBUSY - File is busy
PXERR_INVTABLENAME - Invalid file name
PXERR_INVLOCKCODE - Invalid lock code
PXERR_FILELOCKED - File is already locked
PXERR_NONETINIT - Engine not initialized with PXNetInit or
PXWinInit
PXSUCCESS - Success

SEE ALSO TABLENAMENetFileUnlock, TABLENAMENetTblLock,
TABLENAMENetTblUnlock, PXNetInit, PXWinInit

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
CONST
NetType = NotOnNet;
NetDir = '';

BEGIN
PXNetInit(NetDir,NetType,DefUserName);
INVOICERet := INVOICENetFileLock(WL);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
INVOICENetFileUnlock(WL);
PXExit;
END.

FUNCTION TABLENAMENetFileUnlock - Unlocks the TABLENAME file

SYNTAX int TABLENAMENetFileUnlock(int LockType);
FUNCTION TABLENAMENetFileUnlock(LockType:Integer):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetFileUnlock is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit to use it. This function has an effect if the
table is shared; otherwise it always succeeds, but has no
actual effect.

TABLENAMENetFileUnlock unlocks the TABLENAME file with the
lock specified by LockType. LockType uses the following
mnemonics:

FL Full lock
WL Write lock
PFL Prevent full lock
PWL Prevent write lock

You can place multiple locks on the same table but some
locks take precedence. This function fails if other users
have imposed pre-emptive locks. (See chapter 2 of the
Paradox Users guide for more information). It is therefore
possible to call TABLENAMENetFileUnlock more than once on
the same file with different LockType arguments, provided
that you registered those locks with TABLENAMENetFileLock.

The file lock endures until you call either
TABLENAMENetFileUnlock with the same LockType to unlock it
or PXExit.

RETURN VALUE PXERR_FILEBUSY - File is busy
PXERR_INVTABLENAME - Invalid file name
PXERR_INVLOCKCODE - Invalid lock code
PXERR_INVUNLOCK - Invalid unlock
PXERR_NONETINIT - Engine not initialized with PXNetInit or
PXWinInit
PXSUCCESS - Success


SEE ALSO TABLENAMENetFileLock, TABLENAMENetTblLock,
TABLENAMENetTblUnlock, PXNetInit, PXWinInit

EXAMPLE See next page


#include
#include "invoice.h"
#include "pxengine.h"

#define NETTYPE NOTONNET
#define NETDIR ""

int main(void)
{
PXNetInit(NETDIR,NETTYPE,DEFUSERNAME);
INVOICENetFileLock(WL);
if ((INVOICERet = INVOICENetFileUnlock(WL)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMENetRecGotoLock - Returns to a previously locked
record in TABLENAME

SYNTAX int TABLENAMENetRecGotoLock(LOCKHANDLE LckHandle);
FUNCTION TABLENAMENetRecGotoLock(LckHandle:LockHandle):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetRecGotoLock is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit to use it.

TABLENAMENetRecGotoLock changes the current record of the
open table TABLENAME. If successful the new current record
will be the locked record associated with LckHandle. The
LckHandle argument must be the lock handle previously
obtained with the call to TABLENAMENetRecLock, which locks
the target record.

This function is safer to use in multi-user environments
than TABLENAMERecGoto. TABLENAMERecGoto relies on a record

number, that is subject to change by other users, unless of
course the table has the appropriate table locks.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_INVLOCKHANDLE - Invalid lock handle
PXERR_NONETINIT - Engine not initialized with PXNetInit or
PXWinInit
PXSUCCESS - Success

SEE ALSO TABLENAMENetRecLock, TABLENAMENetRecUnlock,
TABLENAMENetRecLocked, TABLENAMERecGoto

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

#define NETTYPE NOTONNET
#define NETDIR ""

int main(void)
{
LOCKHANDLE LckHandle;

PXNetInit(NETDIR,NETTYPE,DEFUSERNAME);
INVOICETblOpen(NULL);
INVOICENetRecLock(&LckHandle);
if ((INVOICERet = INVOICENetRecGotoLock(LckHandle)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
INVOICENetRecUnlock(LckHandle);
INVOICETblClose();
PXExit();
return(INVOICERet);

}

FUNCTION TABLENAMENetRecLock - Locks a record in TABLENAME

SYNTAX int TABLENAMENetRecLock(LOCKHANDLE *LckHandle);
FUNCTION TABLENAMENetRecLock(var LckHandle:LockHandle):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetRecLock is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit. In a non-network DOS environment the lock is
has no effect and does not create a .LCK file.

TABLENAMENetRecLock locks the current record of TABLENAME.
If successful, the function returns PXSUCCESS and gives you
a lock handle via LckHandle. This lock handle is used in
subsequent unlocking calls.

By default only 32 locks can be active at one time. This
can be changed with the PXSetDefaults Engine function. A
record can be locked only once. You can use
TABLENAMENetRecLocked to check if the current record is
locked. PXNetErrorUser determines the name of the user who
caused the locking error. (For more information see
PXNetRecLock in the PARADOX Engine users manual).

A locked record remains locked until one of the following
occurs:

You unlock it with TABLENAMENetRecUnlock
You delete it with TABLENAMERecDelete
You close the table handle associated with the lock, by
using TABLENAMETblClose.
You exit the Engine via PXExit.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_RECLOCKED - Record is locked
PXERR_OUTOFLOCKHANDLES - Too many locks on table
PXERR_NONETINIT - Engine not initialized with PXNetINit or
PXWinInit
PXERR_RECDELETED - Another user deleted record
PXERR_TABLEEMPTY - Operation on empty table
PXSUCCESS - Success

SEE ALSO TABLENAMENetRecUnlock, TABLENAMENetTblChanged,
TABLENAMENetTblLock, TABLENAMENetRecGotoLock,
TABLENAMENetTblRefresh, TABLENAMENetRecLocked (Chapter 4 of
the Engine Users Guide)

EXAMPLE See next page

{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
CONST
NetType = NotOnNet;
NetDir = '';
VAR
LckHandle:LockHandle;

BEGIN
PXNetInit(NetDir,NetType,DefUserName);
INVOICETblOpen(NoPassword);
INVOICERet := INVOICENetRecLock(LckHandle);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE record locked successfully');
INVOICENetRecUnlock(LckHandle);
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMENetRecLocked - Determines whether a record has been locked in TABLENAME

SYNTAX int TABLENAMENetRecLocked(int *IsLocked);
FUNCTION TABLENAMENetRecLocked(var IsLocked:Boolean):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetRecLocked is a function uses in shared
environments. You must initialize the engine with PXNetInit
or PXWinInit to use it. This function only has an effect if
the table is shared,;otherwise it always succeeds, but has
no effect.

TABLENAMENetRecLocked tests the current record of the table
TABLENAME. If successful, the function returns PXSUCCESS
and sets TRUE or FALSE in the IsLocked parameter to indicate
if the record is locked or not. If the function fails the
IsLocked parameter is meaningless. IsLocked will be TRUE if
you or any other user has a lock on the current record.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_NONETINIT - Engine not initialize with PXNetInit or
PXWinInit
PXSUCCESS - Success

SEE ALSO TABLENAMENetRecLock, TABLENAMENetTblChanged,
TABLENAMENetTblRefresh, TABLENAMENetRecUnlock,
TABLENAMENetRecGotoLock (Chapter 4 of the Engine Users
Guide)

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, PXEngine, Invoice;
CONST
NetType = NotOnNet;
NetDir = '';
VAR
IsLocked:Boolean;

BEGIN
PXNetInit(NetDir,NetType,DefUserName);
INVOICETblOpen(NoPassword);
INVOICERet := INVOICENetRecLocked(IsLocked);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('Current record in INVOICE file is locked');
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMENetRecUnlock - Unlocks a record in TABLENAME

SYNTAX int TABLENAMENetRecUnlock(LOCKHANDLE LckHandle);
FUNCTION TABLENAMENetRecUnlock(LckHandle:LockHandle):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetRecUnlock is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit. This function only has an effect if the table
is shared; otherwise, it always succeeds but has no effect.

TABLENAMENetRecUnlock unlocks the previously locked record
specified by LckHandle in the table TABLENAME. If
successful, the function returns PXSUCCESS, unlocks the
record, and frees the lock handle.

The lock handle used must be the one obtained when the
record was originally locked with a call to
TABLENAMENetRecLock. This means you only unlock records
that you locked.

A locked record can also be unlocked under the following
conditions:

You delete it with TABLENAMERecDelete
You close the table handle associated with the lock, by
using TABLENAMETblClose.
You exit the Engine via PXExit.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_NONETINIT - Engine not initialize with PXNetInit or
PXWinInit
PXERR_INVLOCKHANDLE - Invalid lock handle
PXSUCCESS - Success

SEE ALSO TABLENAMENetRecLOck, TABLENAMENetTblChanged,
TABLENAMENetTblRefresh, TABLENAMENetRecLocked,
TABLENAMENetRecGotoLock (Chapter 4 of the Engine Users
Guide)

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, PXEngine, Invoice;
CONST
NetType = NotOnNet;
NetDir = '';
VAR
LckHandle:LockHandle;

BEGIN
PXNetInit(NetDir,NetType,DefUserName);
INVOICETblOpen(NoPassword);
INVOICENetRecLock(LckHandle);
INVOICERet := INVOICENetRecUnlock(LckHandle);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE file unlocked successfully');
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMENetTblChanged - Tests if TABLENAME has changed

SYNTAX int TABLENAMENetTblChanged(int *IsChanged);
FUNCTION TABLENAMENetTblChanged(var IsChanged:Boolean):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetTblChanged is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit. This function only has an effect if the table
is shared; otherwise, it always succeeds but has no effect.

TABLENAMENetTblChanged tests the table associated with
TABLENAME to determine if the table has been changed by
others since the last internal cache refresh.

On a network, if the table has been changed by other users,
its internal buffers could be out of date, making some
functions potentionally unreliable. To avoid this, call
TABLENAMENetTblRefresh to refresh and resynchronize the
Engines internal buffers.

On success, the function returns PXSUCCESS and sets
IsChanged to TRUE, otherwise IsChanged is False.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXSUCCESS - Success

SEE ALSO TABLENAMENetTblRefresh, TABLENAMERecGoto, TABLENAMERecNum,
TABLENAMETblNRecs, TABLENAMENetRecLock, TABLENAMERecUpdate,
TABLENAMERecInsert, TABLENAMERecAppend (Chapter 4 of the
Engine Users Guide)

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

#define NETTYPE NOTONNET
#define NETDIR ""

int main(void)
{
int IsChanged;

PXNetInit(NETDIR,NETTYPE,DEFUSERNAME);
INVOICETblOpen(NULL);
if ((INVOICERet = INVOICENetTblChnaged(&IsChanged)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
else
printf("Table has %s\n",IsChanged ? "changed" : "not changed");
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMENetTblLock - Locks TABLENAME

SYNTAX int TABLENAMENetTblLock(int LockType);
FUNCTION TABLENAMENetTblLock(LockType:Integer):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetTblLock is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit to use it. This function has an effect if the
table is shared; otherwise it always succeeds, but has no
actual effect.

TABLENAMENetTblLock locks the TABLENAME file with the lock
specified by LockType. LockType uses the following
mnemonics:

FL Full lock
WL Write lock
PFL Prevent full lock
PWL Prevent write lock

You can place multiple locks on the same table but some
locks take precedence. This function fails if other users
have imposed pre-emptive locks. (See chapter 2 of the
Paradox Users guide for more information).

TABLENAMENetTblLock works exactly like TABLENetFileLock
except that the table associated with TABLENAMENetFileLock
need not represent an existing table. (See PXNetFileLock in
the Paradox Engine manual for why you might want to lock a
non-existent table).

RETURN VALUE PXERR_TABLEBUSY - table is busy
PXERR_INVTABLENAME - Invalid table name
PXERR_INVLOCKCODE - Invalid lock code
PXERR_TABLELOCKED - table is already locked
PXERR_NONETINIT - Engine not initialized with PXNetInit or
PXWinInit
PXSUCCESS - Success

SEE ALSO TABLENAMENetFileLock, TABLENAMENetFileUnlock,
TABLENAMENetTblUnlock, (Chapter 4 of the Engine Users Guide)

EXAMPLE See next page


#include
#include "invoice.h"
#include "pxengine.h"

#define NETTYPE NOTONNET
#define NETDIR ""

int main(void)
{
int IsChanged;

PXNetInit(NETDIR,NETTYPE,DEFUSERNAME);
if ((INVOICERet = INVOICENetTblLock(WL)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
else
INVOICENetTblUnlock(WL);
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMENetTblRefresh - Resynchronizes TABLENAME

SYNTAX int TABLENAMENetTblRefresh(void);
FUNCTION TABLENAMENetTblRefresh:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetTblRefresh is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit to use it. This function has an effect if the
table is shared; otherwise it always succeeds, but has no
actual effect.

TABLENAMENetTblRefresh resynchronizes the table referenced
by TABLENAME, refreshing the internal cache if another user
has change the table since the last refresh (See
TABLENAMENetTblChanged).

On a network, if the table has been changed by other users,
its internal buffers could be out of date, making some
functions potentionally unreliable. TABLENAMENetTblRefresh
gets the internal buffers in synch again.

The following functions automatically update and
resynchronize a tables internal buffers (before performing
the function call): TABLENAMENetRecLock, TABLENAMERecUpdate,
TABLENAMERecInsert, TABLENAMERecAppend, TABLENameRecDelete.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_RECDELETED - Another user deleted record
PXSUCCESS - Success

SEE ALSO TABLENAMENetTblChanged, TABLENAMERecGoto, TABLENAMERecNum,
TABLENAMETblNRecs, TABLENAMERecGet, TABLENAMENetRecLock,
TABLENAMERecUpdate, TABLENAMERecInsert, TABLENAMERecAppend,
TABLENAMERecDelete

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
CONST
NetType = NotOnNet;
NetDir = '';

BEGIN
PXNetInit(NetDir,NetType,DefUserName);
INVOICETblOpen(NoPassword);
INVOICERet := INVOICENetTblRefresh;
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE table refreshed successfully');
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMENetTblUnlock - Unlocks the table TABLENAME

SYNTAX int TABLENAMENetTblUnlock(int LockType);
FUNCTION TABLENAMENetTblUnlock(LockType:Integer):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMENetTblUnlock is a function used in shared
environments. You must initialize the Engine with PXNetInit
or PXWinInit to use it. This function has an effect if the
table is shared; otherwise it always succeeds, but has no
actual effect.

TABLENAMENetTblUnlock removes the lock specified in LockType
from the table TABLENAME. LockType uses the following
mnemonics:

FL Full lock
WL Write lock
PFL Prevent full lock
PWL Prevent write lock

You can place multiple locks on the same table but some
locks take precedence. This function fails if other users
have imposed pre-emptive locks. (See chapter 2 of the
Paradox Users guide for more information). It is therefore
possible to call TABLENAMENetFileUnlock more than once on
the same file with different LockType arguments, provided
that you registered those locks with TABLENAMENetFileLock.

RETURN VALUE PXERR_TABLEBUSY - Table is busy
PXERR_INVTABLENAME - Invalid table name
PXERR_INVLOCKCODE - Invalid lock code
PXERR_INVUNLOCK - Invalid unlock
PXERR_NONETINIT - Engine not initialized with PXNetInit or
PXWinInit
PXSUCCESS - Success

SEE ALSO TABLENAMENetFileLock, TABLENAMENetTblLock,
TABLENAMENetFileUnlock, (Chapter 4 of the Engine Users
Guide)

EXAMPLE See next page


#include
#include "invoice.h"
#include "pxengine.h"

#define NETTYPE NOTONNET
#define NETDIR ""

int main(void)
{
PXNetInit(NETDIR,NETTYPE,DEFUSERNAME);
INVOICETblOpen(NULL);
INVOICENetTblLock(WL);
if ((INVOICERet = INVOICENetTblUnlock(WL)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMEPopulateRecord - Populates internal access structure

SYNTAX int TABLENAMEPopulateRecord(TABLENAMETABLEENTRY *RecordVal,
int GetOrPut);
FUNCTION TABLENAMEPopulateRecord(var RecordVal:TABLENAMETABLEENTRY;
GetOrPut:GetOrPutType):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION The TABLENAMEPopulateRecord function is a utility function
generated by PARAGen that either fills or extracts the
access structure RecordVal. The GetOrPut parameter
determines whether to get the values stored in the access
structure or put the values in the access structure. If
GetOrPutType is GET or Get, then the access structure
RecordVal is populated with the values in the record buffer.
If GetOrPutType is PUT or Put, the the values stored in
RecordVal are placed into the record buffer.

This function should only get generated if you choose the
size optimization switch on the options screen. Each
PARAGen generated function that needs to get or put values
to the access structure will make a call to this function.

RETURN VALUE PXERR_INVRECHANDLE - Invalid record handle
PXERR_INVFIELDHANDLE - Invalid field handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Argument out of range
PXSUCCESS - Success

SEE ALSO

EXAMPLE


int INVOICERecLast(INVOICETABLEENTRY *RecordVal)
{
INVOICERet = PXRecLast(INVOICETable);
INVOICERetMacro();
INVOICERet = PXRecGet(INVOICETable,INVOICERecord);
INVOICERetMacro();
INVOICERet = INVOICEPopulateRecord(RecordVal,GET);
INVOICERetMacro();
return(PXSUCCESS);
}

FUNCTION TABLENAMERecAppend - Appends a record to TABLENAME

SYNTAX int TABLENAMERecAppend(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecAppend(var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecAppend appends the contents of the record or
structure specified in RecordVal into the open table
TABLENAME. The appended record becomes the new current
record.

TABLENAMERecAppend empties the record transfer buffer before
it populates the record.
If TABLENAME is indexed, TABLENAMERecAppend works just like
TABLENAMERecInsert; that is the new record is inserted in
the correct indexed position. If TABLENAME is not indexed
the record is inserted as the last record.

To undo TABLENAMERecAppend, you must use TABLENAMERecDelete.
To overwrite an existing record, use TABLENAMERecGoto, or
TABLENAMESrchKey to access the target record, then use
TABLENAMERecUpdate.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_KEYVIOL - Key violation
PXERR_INVRECHANDLE - Invalid record handle
PXERR_TABLEWRITEPRO - Table is write-protected
PXERR_TABLELOCKED - Table is locked
PXERR_SXCANTUPDATE - Can't modify unkeyed table with
non-maintained secondary
index
PXSUCCESS - Success

SEE ALSO TABLENAMERecGet, TABLENAMERecInsert, TABLENAMERecUpdate,
TABLENAMERecDelete. TABLENAMESrchKey

EXAMPLE See next page


#include
#include "invoice.h"
#include "pxengine.h"

#define NETTYPE NOTONNET
#define NETDIR ""

int main(void)
{
static INVOICETABLEENTRY Rec;/* an empty record to be filled later */

PXNetInit(NETDIR,NETTYPE,DEFUSERNAME);
INVOICETblOpen(NULL);
if ((INVOICERet = INVOICERecAppend(&Rec)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMERecDelete - Deletes the current record from TABLENAME

SYNTAX int TABLENAMERecDelete(void);
FUNCTION TABLENAMERecDelete:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecDelete deletes the current record from
TABLENAME. If successful, the current record his deleted
from the table. When the current record is deleted, the new
record becomes the nearest record after the deleted one.

TABLENAMERecDelete does not itself impose any locks, but it
checks for other user locks, and fails if a record or table
is locked. It is the programmers responsibility to place or
unlock locks before calling this function. If the record
was previously locked by the caller TABLENAMERecDelete
removes the lock before deleting the record.

if TABLENAMERecDelete finds the target current record has
already been deleted an error is returned.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_RECDELETED - Another user deleted record
PXERR_TABLELOCKED - Table is locked
PXERR_RECLOCKED - Record is locked
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_TABLEEMPTY - Table is empty
PXERR_SXCANTUPDATE - Can't modify unkeyed table with
non-maintained secondary
index
PXSUCCESS - Success

SEE ALSO TABLENAMERecInsert, TABLENAMERecAppend, TABLENAMERecUpdate

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, PXengine, Invoice;
CONST
NetType = NotOnNet;
NetDir = '';

BEGIN
PXNetInit(NetDir,NetType,DefUserName);
INVOICETblOpen(NoPassword);
INVOICERet := INVOICERecDelete;(* Delete the current record *)
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('record deleted successfully');
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMERecFirst - Moves to the first record of TABLENAME
and gets contents

SYNTAX int TABLENAMERecFirst(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecFirst(var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecFirst changes the current record handle of
TABLENAME. If successful, the new current record will be
the first record of the table. First is interpreted in
light of the index order implied by TABLENAME.
TABLENAMERecFirst then populates the access structure
RecordVal with the contents of the first record.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_TABLEEMPTY - Operation on empty table
PXERR_INVRECHANDLE - Invalid record handle
PXERR_RECDELETED - Another user deleted record
PXERR_INVFIELDHANDLE - Invalid field handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Argument out of range
PXSUCCESS - Success

SEE ALSO TABLENAMERecGoto, TABLENAMERecLast, TABLENAMERecNext,
TABLENAMERecPrev

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
VAR
Rec: InvoiceTableEntry;

BEGIN
PXInit;
INVOICETblOpen(NoPassword);
INVOICERet := INVOICERecFirst(Rec);(* Move to record 1, get values *)
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('First invoice number:',Rec.InvoiceNumber);
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMERecGet - Transfers current record in transfer buffer
to access structure

SYNTAX int TABLENAMERecGet(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecGet(var RecordVal:TABLENAMETABLEENTRY)
: Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecGet transfers the data in the current record
transfer buffer associated with the open TABLENAME to the
access structure RecordVal.

In a shared environment, you should apply either a record or
table lock, as appropriate to ensure that the current record
cannot be deleted by another user while it is in use. You
should use table locks when the alternative is a large
number of record locks.

RETURN VALUE PXERR_INVRECHANDLE - Invalid record handle
PXERR_INVFIELDHANDLE - Invalid field handle
PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Argument out of range
PXERR_RECDELETED - Another user deleted record
PXERR_TABLEEMPTY - Operation on empty table
PXSUCCESS - Success

SEE ALSO TABLENAMERecAppend, TABLENAMERecInsert, TABLENAMERecDelete,
PXGet..., PXPut...


EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{
INVOICETABLEENTRY Rec;

PXInit();
INVOICETblOpen(NoPassword);
INVOICERecGoto(1); /* Simulate TABLENAMERecFirst */
if ((INVOICERet = INVOICERecGet(&Rec)) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("First invoice number: %10.2f",Rec.InvoiceNumber);
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMERecGoto - Moves to a specified record in TABLENAME

SYNTAX int TABLENAMERecGoto(RECORDNUMBER RecordNumber);
FUNCTION TABLENAMERecGoto(RecordNumber:Longint):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecGoto changes the current record handle of the
target table TABLENAME. If successful, the new current
record will be that given by RecordNumber.

In a shared environment, the position of the record, as
given by a record number is unreliable. It may change at
any time as a result of users adding or deleting records.
You can use TABLENAMENetTblChanged to test if another user
has changed a table, indicating that the internal buffers
are not up to date. The internal cache, is refreshed when
updating a record, locking a record, when a new block is
read in, or when you call TABLENAMENetTblRefresh.

The TABLENAMERecNum and TABLENAMETblNRecs functions are only
reliable immediately after a refresh operation, unless the
table is write locked. It is generally safer to use
relative positioning and searching then to rely on record
numbers.

TABLENAMERecGoto does not explicitly place any locks, so its
is your responsibility to apply them before changing the
target record.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_OUTOFRANGE _ Argument is out of range
PXERR_TABLEEMPTY - Operation on empty table
PXSUCCESS - Success

SEE ALSO TABLENAMERecFirst, TABLENAMERecLast, TABLENAMERECNext,
TABLENAMERecPrev, TABLENAMENetTblRefresh

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;

BEGIN
PXInit;
INVOICETblOpen(NoPassword);
INVOICERet := INVOICERecGoto(4);(* Go to record 4 *)
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('Record 4 is now the current record');
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMERecInsert - Inserts a record into TABLENAME

SYNTAX int TABLENAMERecInsert(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecInsert(var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecInsert inserts the contents of the record or
structure specified in RecordVal into the open table
TABLENAME. The appended record becomes the new current
record.

TABLENAMERecInsert empties the record transfer buffer before
it populates the record.
If TABLENAME is indexed, TABLENAMERecInsert works just like
TABLENAMERecAppend; that is the new record is inserted in
the correct indexed position. If TABLENAME is not indexed
the record is inserted just before the current record.

To undo TABLENAMERecInsert, you must use TABLENAMERecDelete.
To overwrite an existing record, use TABLENAMERecGoto, or
TABLENAMESrchKey to access the target record, then use
TABLENAMERecUpdate.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_KEYVIOL - Key violation
PXERR_INVRECHANDLE - Invalid record handle
PXERR_TABLEWRITEPRO - Table is write-protected
PXERR_TABLELOCKED - Table is locked
PXSUCCESS - Success

SEE ALSO TABLENAMERecAppend, TABLENAMERecUpdate, TABLENAMERecDelete,
TABLENAMESrchKey

EXAMPLE See next page


#include
#include "invoice.h"
#include "pxengine.h"

#define NETTYPE NOTONNET
#define NETDIR ""

int main(void)
{
static INVOICETABLEENTRY Rec;/* an empty record to be filled later */

PXNetInit(NETDIR,NETTYPE,DEFUSERNAME);
INVOICETblOpen(NULL);
if ((INVOICERet = INVOICERecInsert(&Rec)) != PXSUCCESS)
printf("%s\n",PXErrMsg(INVOICERet));
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMERecLast - Moves to last record in TABLENAME and
gets contents

SYNTAX int TABLENAMERecLast(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecLast(var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMEReclast changes the current record handle of
TABLENAME. If successful, the new current record will be
the last record of the table. Last is interpreted in light
of the index order implied by TABLENAME. TABLENAMERecLast
then populates the access structure RecordVal with the
contents of the last record.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_TABLEEMPTY - Operation on empty table
PXERR_INVRECHANDLE - Invalid record handle
PXERR_RECDELETED - Another user deleted record
PXERR_INVFIELDHANDLE - Invalid field handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Argument out of range
PXSUCCESS - Success

SEE ALSO TABLENAMERecGoto, TABLENAMERecFirst, TABLENAMERecNext,
TABLENAMERecPrev

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
VAR
Rec: InvoiceTableEntry;

BEGIN
PXInit;
INVOICETblOpen(NoPassword);
INVOICERet := INVOICERecLast(Rec);(* Last record, get values *)
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('Last invoice number:',Rec.InvoiceNumber);
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMERecNext - Moves to next record in TABLENAME and
gets contents

SYNTAX int TABLENAMERecNext(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecNext(var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecNext changes the current record handle of
TABLENAME. If successful, the new current record will be
the next record in the table, following the current record.
Next is interpreted in light of the index order implied by
the open table TABLENAME. TABLENAMERecLast then populates
the access structure RecordVal with the contents of the next
record.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_TABLEEMPTY - Operation on empty table
PXERR_ENDOFTABLE - End of table
PXERR_INVRECHANDLE - Invalid record handle
PXERR_RECDELETED - Another user deleted record
PXERR_INVFIELDHANDLE - Invalid field handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Argument out of range
PXSUCCESS - Success

SEE ALSO TABLENAMERecGoto, TABLENAMERecFirst, TABLENAMERecLast,
TABLENAMERecPrev

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{
INVOICETABLEENTRY Rec;

PXInit();
INVOICETblOpen(NoPassword);
INVOICERecGoto(2);
if ((INVOICERet = INVOICERecNext(&Rec)) != PXSUCCESS)/* Get 3rd one */
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("Third invoice number: %10.2f",Rec.InvoiceNumber);
INVOICETblClose();
PXExit();
}

FUNCTION TABLENAMERecNFlds - Finds the number of fields in TABLENAME

SYNTAX int TABLENAMERecNFlds(int *NumFields);
FUNCTION TABLENAMERecNFlds(var NumFields:Integer):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecNFlds finds the number of fields in the target
table. The number is returned in the NumFields parameter.
This function references TABLENAME using its handle, so
TABLENAME must be opened first with TABLENAMETblOpen before
using it.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXSUCCESS - Success

SEE ALSO TABLENAMETblOpen, TABLENAMERecNFlds, TABLENAMETblCreate

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{
int NFields;

PXInit();
INVOICETblOpen(NoPassword);
if ((INVOICERet = INVOICERecNFlds(&NFields)) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("Number of fields in INVOICE is %d\n", NFields);
INVOICETblClose();
PXExit();
}

FUNCTION TABLENAMERecNum - Finds the current record number in TABLENAME

SYNTAX int TABLENAMERecNum(RECORDNUMBER *NumRecords);
FUNCTION TABLENAMERecNum(var NumRecords:Longint):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecNum returns the current record number of the
table referenced by TABLENAME. The number is returned in
NumRecords.

In shared environments, the record number may not be
reliable unless you have applied the appropriate locks.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_TABLEEMPTY - Operation on empty table
PXSUCCESS - Success

SEE ALSO TABLENAMETblNRecs, TABLENAMERecGoto

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{
int RecNum;

PXInit();
INVOICETblOpen(NoPassword);
INVOICERecGoto(2);
if ((INVOICERet = INVOICERecNum(&RecNum)) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("Current record number is %d\n", RecNum);
INVOICETblClose();
PXExit();
}

FUNCTION TABLENAMERecPrev - Moves to previous record in TABLENAME
and gets contents

SYNTAX int TABLENAMERecPrev(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecPrev(var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecPrev changes the current record handle of
TABLENAME. If successful, the new current record becomes
the record before the previous current record. Previous is
interpreted in light of the index order implied by the open
table TABLENAME. TABLENAMERecPrev then populates the access
structure RecordVal with the contents of the previous
record.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_TABLEEMPTY - Operation on empty table
PXERR_STARTOFTABLE - Start of table
PXERR_INVRECHANDLE - Invalid record handle
PXERR_RECDELETED - Another user deleted record
PXERR_INVFIELDHANDLE - Invalid field handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Argument out of range
PXSUCCESS - Success

SEE ALSO TABLENAMERecGoto, TABLENAMERecFirst, TABLENAMERecLast,
TABLENAMERecNext

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
VAR
Rec: InvoiceTableEntry;

BEGIN
PXInit;
INVOICETblOpen(NoPassword);
INVOICERecLast(Rec);
INVOICERet := INVOICERecPrev(Rec);(* prev record *)
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('Next to last invoice number:',Rec.InvoiceNumber);
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMERecUpdate - Updates the current record in TABLENAME

SYNTAX int TABLENAMERecUpdate(TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMERecUpdate(var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMERecUpdate places (updates) the contents of the
record or structure specified in RecordVal into the current
record in the open table TABLENAME. The updated record
remains the new current record for the table.

TABLENAMERecUpdate empties the record transfer buffer before
it populates the record. In a shared environment you need
to place appropriate locks before updating a record to
ensure data integrity.

If a key of a record was altered (assuming there is a key),
the action of TABLENAMERecUpdate is equivalent to a call to
TABLENAMERecDelete followed by a call to TABLENAMERecInsert.
The new record is moved properly.

To undo a TABLENAMERecUpdate, you must save the old record
and use TABLENAMERecUpdate again with these old values.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_KEYVIOL - Key violation
PXERR_INVRECHANDLE - Invalid record handle
PXERR_RECDELETED - Another user deleted record
PXERR_TABLEWRITEPRO - Table is write-protected
PXERR_TABLEEMPTY - Table is Empty
PXERR_TABLELOCKED - Table is locked
PXERR_RECLOCKED - Record is locked
PXERR_SXCANTUPDATE - Can't modify unkeyed table with
non-maintained secondary
index
PXSUCCESS - Success

SEE ALSO TABLENAMERecAppend, TABLENAMERecInsert, TABLENAMERecDelete,
TABLENAMESrchKey

EXAMPLE See next page


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{
static INVOICETABLEENTRY Rec =
{
643667,/* new catalog number */
886868,/* new invoice number */
3, /* new month */
22, /* new day */
91, /* new year */
345.00 /* new unit price */
310.50,/* new amount after discount */
.10, /* discount */
"UPS Grnd"/* ship via */
};

PXInit();
INVOICETblOpen(NoPassword);
INVOICERecGoto(2);
if ((INVOICERet = INVOICERecUpdate(&Rec)) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("Record updated successfully\n");
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMESrchFld - Searches TABLENAME on a specified field,
and gets contents

SYNTAX int TABLENAMESrchFld(int SearchMode,char *FieldToSearch,
TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMESrchFld(SearchMode:Integer;
FieldToSearch:String;
var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMESrchFld initiates a search on the table given by
TABLENAME. A match is sought on the field given by
FieldToSearch. FieldToSearch is the actual field name as it
exists in TABLENAME. The comment block at the beginning of
the generated source contains a list of the fields as they
exist in the original table. The value to be matched is the
value in the access structure RecordVal for the particular
field in question. Note that searches are case sensitive.
Once the record is found, the RecordVal structure is
populated with the values of the whole record including the
field searched on. RecordVal serves a dual purpose in this
function: on input one specific field contains a value to
search on, on output it contains the whole record if it is
found.

You can control the scope of the search by setting the
argument SearchMode to SEARCHFIRST, SEARCHNEXT, or
CLOSESTRECORD. With SearchMode set to SEARCHFIRST, the
search starts at the first record. With it set to
SEARCHNEXT, the search proceeds from the record after the
current record. CLOSESTRECORD, also starts at the first
record. These three search modifiers are mutually
exclusive.

For non-indexed tables, the Engine performs searching
through a simple sequential scan. The order of the records
is the natural order of records in the table. CLOSESTRECORD
is not supported in non-indexed tables. If no match is
found, the current record cursor is left unchanged.

RETURN VALUE PXERR_INVFIELDNAME - Invalid field name
PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_INVRECHANDLE - Invalid record handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Arguments out of range
PXERR_RECNOTFOUND - Record not found
PXERR_RECDELETED - Another user deleted record
PXERR_TABLEEMPTY - Operation on empty table
PXSUCCESS - Success

SEE ALSO TABLENAMESrchKey

EXAMPLE See next page


#include
#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{

static INVOICETABLEENTRY Rec;

PXInit();
INVOICETblOpen(NoPassword);
strcpy(Rec.ShipVia,"UPS 2 Day");/* search for 1st UPS 2 day invoice */
if ((INVOICERet = INVOICESrchFld(SEARCHFIRST,"Ship Via",&Rec)) !=
PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("1st invoice with shipped via UPS 2 day is: %10.2f\n",
Rec.InvoiceNum);
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMESrchKey - Searches TABLENAME for a key match

SYNTAX int TABLENAMESrchKey(int SearchMode, int NumKeysToSearch,
TABLENAMETABLEENTRY *RecordVal);
FUNCTION TABLENAMESrchKey(SearchMode,NumKeysToSearch:Integer;
var RecordVal:TABLENAMETABLEENTRY)
:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMESrchKey initiates a search on the primary index of
TABLENAME. A match is sought on the key field(s) of the
table given by NumKeysToSearch. They key must be the
primary key or a subset of the primary key. A subset is the
first NN fields, where NN must be <= the number of fields
compromising the primary key. If the key value is matched,
the RecordVal structure is populated with the values of the
whole record found, including the keys being searched on.

You can control the scope of the search by setting the
argument SearchMode to SEARCHFIRST, SEARCHNEXT, or
CLOSESTRECORD. With SearchMode set to SEARCHFIRST, the
search starts at the first record. With it set to
SEARCHNEXT, the search proceeds from the record after the
current record. CLOSESTRECORD, also starts at the first
record. These three search modifiers are mutually
exclusive.

For compatibility with the Engine version 1.0, you can also
use

SEARCHFIRST | CLOSESTRECORD

Which means the same thing as CLOSESTRECORD by itself.

RETURN VALUE PXERR_INVFIELDNAME - Invalid field name
PXERR_INVTABLEHANDLE - Invalid table handle
PXERR_INVRECHANDLE - Invalid record handle
PXERR_TYPEMISMATCH - Data type mismatch
PXERR_OUTOFRANGE - Arguments out of range
PXERR_RECNOTFOUND - Record not found
PXERR_RECDELETED - Another user deleted record
PXERR_TABLEEMPTY - Operation on empty table
PXSUCCESS - Success


SEE ALSO TABLENAMESrchFld

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
VAR
Rec:InvoiceTableEntry;

BEGIN
PXInit;
INVOICETblOpen(NoPassword);
FillChar(Rec, sizeof(Rec),#0);
Rec.CatalogNumber := 12345;
INVOICERet := INVOICESrchKey(SearchFirst,1,Rec);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('Invoice number for 1st catalog number matching 12345: ',
Rec.InvoiceNum);
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMETblAdd - Add records to or from TABLENAME

SYNTAX int TABLENAMETblAdd(char *FileName,int SrcOrDest);
FUNCTION TABLENAMETblAdd(FileName:String;
SrcOrDest:SrcOrDestType):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblAdd adds records to or from TABLENAME. If the
SrcOrDest argument is SOURCE or Source, TABLENAME is used as
the source for the adding. In this case, records are added
from the TABLENAME table to the table specified in FileName.
If the SrcOrDest argument is DESTINATION or Destination,
FileName is used as the source for adding. In this case
records are added from the table specified in FileName to
the TABLENAME table. Note that if a key violation occurs,
the record is overwritten.

The FileName parameter can include a valid DOS path. Any
extensions other than .DB are ignored; the extension of .DB
is assumed. Note that C and C++ call for an additional
esacpe character (\\) for the path separator.
(EX:\\PARAGEN\\DEMO)

Both tables must exist and have assignment compatible record
structures. Both tables must also be closed.

If possible the source table receives a write lock (WL),
allowing other users to read but not write the source table.
The destination table, if possible, gets a prevent write
lock, preventing other users from issuing a write lock that
would interfere with the add operation.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEOPEN - Source or destination table open
PXERR_STRUCTDIFFER - Table structures are different
PXERR_TABLEEMPTY - Table is empty
PXERR_TABLEFULL - Table is full
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_OUTOFDISK - Not enough disk space to complete
operation
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - Insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblOpen, TABLENAMETblCopy, TABLENAMETblRename

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
CONST
Filename = 'INVOICE2';

BEGIN
PXInit;
INVOICERet := INVOICETblAdd(Filename,Source);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('Records successfully added to :',FileName);
PXExit;
END.

FUNCTION TABLENAMETblClose - Closes table TABLENAME

SYNTAX int TABLENAMETblClose(void);
FUNCTION TABLENAMETblClose:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblClose closes a table previously opened with
TABLENAMETblOpen. You can not close an unopened table.

Closing tables promptly is considered good programming
practice, since it is essential to good housekeeping and
guarantees all unsaved changes to the table are correctly
saved to disk.

TABLENAMETblClose, frees a table handle and all the table's
associated memory allocations, such as record handle
buffers. It also unlocks any records locked by the caller
if they are still open.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXSUCCESS - Success

SEE ALSO TABLENAMETblOpen

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{

PXInit();
INVOICETblOpen(NoPassword);
if ((INVOICERet = INVOICETblClose()) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("INVOICE table closed successfully\n");
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMETblCopy - Copies to or from the TABLENAME family

SYNTAX int TABLENAMETblCopy(char *FileName,int SrcOrDest);
FUNCTION TABLENAMETblCopy(FileName:String;
SrcOrDest:SrcOrDestType):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblCopy copies a table family to or from TABLENAME.
If the SrcOrDest argument is SOURCE or Source, TABLENAME is
used as the source for the copying. In this case, the table
family is copied from the TABLENAME family to the family
specified in FileName. If the SrcOrDest argument is
DESTINATION or Destination, FileName is used as the source
for copying. In this case the table family is copied from
the table specified in FileName to the TABLENAME table.

The FileName parameter can include a valid DOS path. Any
extensions other than .DB are ignored; the extension of .DB
is assumed. Note that C and C++ call for an additional
esacpe character (\\) for the path separator.
(EX:\\PARAGEN\\DEMO)

All objects such as forms, report formats, image settings,
validity checks, and indexes associated with base table name
will get copied.

Both tables names must be valid. If both exist, they both
must be closed. Existing destination family members are
overwritten if TABLENAMETblCopy succeeds. If the
destination table does not exist TABLENAMETblCopy will try
to create one, together with any family members present in
the source family.

If possible the source table receives a write lock (WL),
allowing other users to read but not write the source table.
The destination table, if possible, gets a prevent write
lock, preventing other users from issuing a write lock that
would interfere with the add operation.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEOPEN - Source or destination table open
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_OUTOFDISK - Not enough disk space to complete
operation
PXERR_OUTOFMEM - Not enough memory to complete operation
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - Insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblOpen, TABLENAMETblCopy, TABLENAMETblRename

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
CONST
Filename = 'INVOICE2';

BEGIN
PXInit;
INVOICERet := INVOICETblCopy(Filename,Source);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE table family successfully copied to :',FileName);
PXExit;
END.

FUNCTION TABLENAMETblCreate - Creates table TABLENAME

SYNTAX int TABLENAMETblCreate(int TableSize);
FUNCTION TABLENAMETblCreate(TableSize:Integer):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblCreate creates a new (empty) table TABLENAME
with the original fields, and index if the table is keyed.
This function will only create a PRIMARY index. The
TableSize argument is used to set the maximum size for the
table. It must be 64, 128, or 256 giving maximum table
sizes of 64MB, 128MB, and 256MB. If TableSize is less than
or equal to zero (0), the original size of the table is
used.

The TableSize parameter only effects the size of the table
when it is created.

TABLENAMETblCreate first checks to see if a table of the
same name exists. If a table does exist but is not
currently open, it and all family members are deleted
without warning, before the new table is created. To avoid
this use, TABLENAMETblExist to test if the table exists.

In a shared environment, a full lock (FL) is placed on the
table to prevent access by other users until the table
creation is complete.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLEOPEN - Unable to perform operation on open table
PXERR_OUTOFRANGE - Argument is out of range
PXERR_INVPARAMETER - Invalid parameter
PXERR_OUTOFDISK - Not enough disk space to complete
operation
PXERR_OUTOFMEM - Not enough memory to complete operation
PXERR_RECTOOBIG - Record too big for index
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - Insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblOpen, TABLENAMETblDelete, TABLENAMEEmpty,
PXTblMaxSize

EXAMPLE See next page


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{

PXInit();
if ((INVOICERet = INVOICETblCreate(0)) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("INVOICE table created successfully\n");
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMETblDecrypt - Decrypts TABLENAME with password

SYNTAX int TABLENAMETblDecrypt(char *Password);
FUNCTION TABLENAMETblDecrypt(Password:String):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblDecrypt decrypts the table TABLENAME. It does
this by adding the Password argument to the system, and then
issuing the decrypt call. The Password is not deleted from
the system. If the table is open, you must first close it.

On a network, beware of network protocol for rights and
privileges.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_TABLEOPEN - Table is open
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMEEncrypt, TABLENAMEProtected, PXPswAdd

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{

PXInit();
if ((INVOICERet = INVOICETblDecrypt("PARAGEN")) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("INVOICE table decrypted successfully\n");
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMETblDelete - Deletes TABLENAME and its family

SYNTAX int TABLENAMETblDelete(void);
FUNCTION TABLENAMETblDelete:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblDelete deletes the TABLENAME table, together
with any associated family objects that might exist. All
objects such as forms, report formats, image settings,
validity checks, and indexes associated with TABLENAME will
get deleted.

The Engine does not check if any of these files are valid
PARADOX files. All files matching these names will be
deleted from disk, so use TABLENAMETblDelete with caution.

In a shared environment, a full lock (FL) is placed on the
table to prevent access by other users until the table
creation is complete.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_TABLEOPEN - Table is open
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblCreate, TABLENAMETblEmpty

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;

BEGIN
PXInit;
INVOICERet := INVOICETblDelete;
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE table family successfully deleted');
PXExit;
END.

FUNCTION TABLENAMETblEmpty - Removes all records from TABLENAME

SYNTAX int TABLENAMETblEmpty(void);
FUNCTION TABLENAMETblEmpty:Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblEmpty removes all of the records from TABLENAME,
but leaves the table structure intact.

In a shared environment, a full lock (FL) is placed on the
table to prevent access during this operation. On a
network, beware of network protocol for rights and
privileges.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_TABLEOPEN - Table is open
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblCreate, TABLENAMETblDelete

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;

BEGIN
PXInit;
INVOICERet := INVOICETblEmpty;
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE table successfully emptied');
PXExit;
END.

FUNCTION TABLENAMETblEncrypt - Encrypts TABLENAME with password

SYNTAX int TABLENAMETblEncrypt(char *Password);
FUNCTION TABLENAMETblEncrypt(Password:String):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblEncrypt encrypts TABLENAME with Password. If
the table TABLENAME is open, you should close the table with
TABLENAMETblClose.

An encrypted table can only be accessed by a user who
provides a current password. (See TABLENAMETblOpen).

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_TABLEOPEN - Table is open
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblProtected, TABLENAMETblDecrypt, PXPswAdd,
PXPswDel

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{

PXInit();
if ((INVOICERet = INVOICETblEncrypt("PARAGEN")) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("INVOICE table encrypted successfully\n");
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMETblExist - Test if the table TABLENAME exists

SYNTAX int TABLENAMETblExist(int *Exists);
FUNCTION TABLENAMETblExist(var Exists:Boolean):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblExist sets Exists to TRUE if the table TABLENAME
exists. Otherwise Exists is set to FALSE.

If the table TABLENAME is a valid table name, the function
returns PXSUCCESS, whether the table is found or not. If
the table TABLENAME is invalid, an error message is
returned.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXSUCCESS - Success

SEE ALSO TABLENAMETblNRecs, TABLENAMETblNFlds

EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;
VAR
Exists: Boolean;

BEGIN
PXInit;
INVOICERet := INVOICETblExists(Exists);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE table exists');
PXExit;
END.

FUNCTION TABLENAMETblNRecs - Finds the number of records in TABLENAME

SYNTAX int TABLENAMETblNRecs(RECORDNUMBER *NumRecords);
FUNCTION TABLENAMETblNRecs(var NumRecords:Longint):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblNRecs returns the number of records in
TABLENAME. The number is returned in the argument
Numrecords.

In a shared environment, no implicit locks are requested by
this call, but you should be aware that other users may be
adding and deleting records. It is your responsibility to
lock the table or use TABLENAMENetTblChanged and
TABLENAMENetTblRefresh to ensure that number of records
obtained is valid.

RETURN VALUE PXERR_INVTABLEHANDLE - Invalid table handle
PXSUCCESS - Success

SEE ALSO TABLENAMERecNUm

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{

RECORDNUMBER NumRecs;

PXInit();
INVOICETblOpen(NULL);
if ((INVOICERet = INVOICETblNRecs(&NumRecs)) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("INVOICE table has %d records\n",NumRecs);
INVOICETblClose();
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMETblOpen - Opens TABLENAME with password

SYNTAX int TABLENAMETblOpen(char *Password);
FUNCTION TABLENAMETblOpen(Password:String):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblOpen opens the table TABLENAME with Password.
If Password is NULL (C, C++) or NoPassword (Pascal), then it
does not get added to the system. This function opens all
indexes in addition to the master table. A define in C and
C++ and a global boolean in pascal called BUFFERED,
determines whether posted records are buffered or saved to
disk immediately. If BUFFERED is TRUE records get saved to
disk as they are posted. If BUFFERED is False, the Engine
decides when it is optimal to save the changes.

TABLENAMETblOpen also sets up a global TABLEHANDLE, a global
RECORDHANDLE, and global FIELDHANDLES for each field in
TABLENAME. All other PARAGen related functions in TABLENAME
will make use of these handles.

To reduce the number of active table handles, you should
close tables and indexes, using TABLENAMETblClose, as soon
as possible. By default the total number of files
(including tables and objects) that can be opened at any one
time is 5. You can change this default with PXSetDefaults.
Closing a table flushes and frees buffers, ensuring the
timely, updating of disk files.

RETURN VALUE PXERR_OUTOFTABLEHANDLES - No more table handles available
PXERR_OUTOFFILEHANDLES - No more file handles available
PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEOPEN - Unable to perform operation on open table
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_TABLECORRUPTED - Table is corrupted
PXERR_OUTOFDISK - Not enough disk space to complete
operation
PXERR_OUTOFMEM - Not enough disk space to complete operation
PXERR_OUTOFRANGE - Argument is out of range
PXERR_TABLENOTINDEXED - Table is not indexed
PXERR_XCORRUPTED - Primary index is corrupted
PXERR_SXCORRUPTED - Secondary index is corrupted
PXERR_SXOUTOFDATE - Secondary index is out of date
PXERR_SXNOTFOUND - Secondary index was not found
PXERR_SXOPEN - Secondary index is already open
PXERR_XSORTVERSION - Sort for index different than table
PXERR_OUTOFSWPBUF - Not enough swap buffer space to complete
operation
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - Insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblClose


EXAMPLE


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;

BEGIN
PXInit;
INVOICERet := INVOICETblOpen(NoPassword);
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE table opened successfully');
INVOICETblClose;
PXExit;
END.

FUNCTION TABLENAMETblProtected - Tests if the table TABLENAME is
encrypted

SYNTAX int TABLENAMETblProtected(int *IsProtected);
FUNCTION TABLENAMETblProtected(var IsProtected:Boolean):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblProtected tells you if the table TABLENAME is
password protected. Provided that the specified table
exists, the value in IsProtected is set to TRUE if the table
is protected, and to FALSE if is not protected. The table
does not have to be open for this function to work properly.

RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table was not found

SEE ALSO TABLENAMETblEncrypt, PXPSwAdd, PXPswDel

EXAMPLE


#include
#include "invoice.h"
#include "pxengine.h"

int main(void)
{

int IsProtected;

PXInit();
if ((INVOICERet = INVOICETblProtected(&IsProtected)) != PXSUCCESS)
printf("%s\n", PXErrMsg(INVOICERet));
else
printf("INVOICE table is %s\n",
IsProtected ? "protected" : "not protected");
PXExit();
return(INVOICERet);
}

FUNCTION TABLENAMETblRename - Changes the base name of TABLENAME
and its family

SYNTAX int TABLENAMETblRename(char *DestTable);
FUNCTION TABLENAMETblRename(DestTable:String):Integer;

PROTOTYPE TABLENAME.H, TABLENAME.HPP, or TABLENAME.PAS

DESCRIPTION TABLENAMETblRename renames the TABLENAME table, together
with any associated family objects that might exist. All
objects such as forms, report formats, image settings,
validity checks, and indexes associated with TABLENAME will
get renamed to whatever is in the argument DestTable.

The DestTable parameter can include a valid DOS path. Any
extensions other than .DB are ignored; the extension of .DB
is assumed. Note that C and C++ call for an additional
esacpe character (\\) for the path separator.
(EX:\\PARAGEN\\DEMO)

The DestTable may or may not exist, If it exists, it must
be closed.

The Engine does not check if any of these files are valid
PARADOX files. All files matching these names will be
renamed on disk without confirmation, so use
TABLENAMETblRename with caution.

In a shared environment, a full lock (FL) is placed on the
DestTable table to prevent access by other users until the
table renaming is complete.


RETURN VALUE PXERR_INVTABLENAME - Invalid table name
PXERR_TABLENOTFOUND - Table not found
PXERR_TABLEWRITEPRO - Table is write protected
PXERR_OUTOFDISK - Not enough disk space to complete
operation
PXERR_OUTOFMEM - Not enough memory to complete operation
PXERR_TABLEOPEN - Table is open
PXERR_TABLEBUSY - Table is busy
PXERR_TABLELOCKED - Table is locked
PXERR_INSUFRIGHTS - insufficient password rights
PXSUCCESS - Success

SEE ALSO TABLENAMETblCopy, TABLENAMETblDelete

EXAMPLE See next page


{$N+,F+}
PROGRAM Sample;
USES
Crt, Pxengine, Invoice;

BEGIN
PXInit;
INVOICERet := INVOICETblRename('NewTbl');
if (INVOICERet <> PXSUCCESS) then
writeln('Error :', PXErrMsg(INVOICERet))
else
writeln('INVOICE table family successfully renamed');
PXExit;
END.

RELEASE NOTES

PARAGen 2.2 Release Notes


The MF-Merge File option in the C and C++ version of the VIDLIB demo
program should be MT-Merge Table. To fix the problem change line 83 of
VIDLIB.C and line 82 of VIDLIB.CPP to:

PrintText(18,23,"MT-Merge Table");




A new Language option has been added for Turbo Pascal for Windows.
The option Turbo Pas/Windows will produce code to acces the Paradox
engine based on the PXENGINE.PAS file supplied with Turbo Pascal for
Windows. The following lines must be added to PXENGINE.PAS in order
for PARAGen to work properly. (New lines are flagged with *) :


*const
* MaxFlds = 255;

{ Type definitions }
type
* NameString = string[25];
* NameArray = array[1..MaxFlds] of NameString;
* NamesArrayPtr = ^NameArray;
TableHandle = word; { table handle }
RecordHandle = word; { record handle }
FieldHandle = word; { field number 1.. }
LockHandle = Integer; { lock handle }
RecordNumber = LongInt; { record number 1.. }
Date = LongInt; { representation of date }
* TDate = Longint;
* WordArray = array[1..MaxFlds] of Word;
* FieldHandleArray = WordArray;

Once you make the changes, the .PAS should be compiled into the UNIT.
Make sure to include the directory where you compile the UNIT in
the Options | Directories | Unit Directories of the TPW environment.
The code that PARAgen generates should then compile withou a hitch.


A new global variable called TABLENAMEPathName has been added to support
table manipulation across paths and directories. Remember TABLENAME is the
actual name of the table you are working on. This variable now contains
the full path and file name (drive, directory and PARADOX table name). It
gets set in the Open dialog box or the Create dialog box. The variable
resides in the .H, .HPP, or .PAS file generated by PARAGen. The previous
version of generated code used to hard code the tablename in the generated
function calls, thus requiring you to have the .DB, .PX, etc. in the same
directory as the executable. This variable now overcomes that difficulty.
By changing the contents of this variable, you can now maintain the table
in various directories. Please remember that C and C++ calls for an
additional escape character (\) for the path seperator (EX:
C:\\DATA\\DATAFILE). The following functions generated by PARAGen now
use this global variable:

TABLENAMETblAdd
TABLENAMETblCopy
TABLENAMETblCreate
TABLENAMETblDelete
TABLENAMETblDecrypt
TABLENAMETblEmpty
TABLENAMETblEncrypt
TABLENAMETblExist
TABLENAMETblOpen
TABLENAMETblProtected
TABLENAMETblRename

A save message box has been added to the TABLE | Exit option. If you wish
to save the current session options click the mouse on the YES box or use
the TAB key to get their and hit ENTER. Clicking on the NO box or tabbing
to it and hitting ENTER will NOT save the current options. In previous
versions the options were always saved.

The Fields... dialog box (Search Field Select) has been changed. An
asterik (*) now appears to the left of each field name in the Selected
Field and Available Field list boxes, if the field is a key field. This
enables you to visually see which fields are key fields. Each list box
will consist of two parts: The non key sorted field list followed by the
sorted key field list if it exists. The key fields will be the last fields
in the list. Each part of the list will sorted in ascending alphabetical
order.



The status area that shows the Project and Programmer information along
with the current Table information has been updated to show the current
working directory. This directory appears under the Project and Programmer
information and shows the fully qualified path of the current working
directory. It will get updated every time you enter the Open or Create
dialog box.


PLANNED ENHANCEMENTS (Possible)

True OOP support for C++ and Pascal. Classes are being developed for C++
and Pascal that will allow true object oriented programming. PARAGen will
be able to generate these classes as well as the code needed to access
these classes.

Re-generation preservation. PARAGen will be able to determine if changes
were made to any of the functions it can generate. This will enable you to
make changes to existing functions and re-generate the code without having
to make the changes again. PARAGen will preserve all changes that it can
recognize.

All options including tagged functions and and fields will be saved. This
will make code re-generation a simple and easy process.

Macro capabilty to record and play back keystrokes and save them in a
script. This will allow complete re-generation with a single keystroke.

Stripped down command line version that will enable users to process the
above scripts, without having to go through the user interface.

Support for the ACCSYS library of PARADOX functions from Copia
International.




APPENDIX

TEXT MESSAGES OF GENERATED FUNCTIONS

Text Message PARAGen Function

Add to Table.................................TABLENAMETblAdd
Append a Record..............................TABLENAMERecAppend
Close Table..................................TABLENAMETblClose
Copy Table...................................TABLENAMETblCopy
Create Table.................................TABLENAMETblCreate
Current Record #.............................TABLENAMERecNum
Decrypt Table................................TABLENAMETblDecrypt
Delete a Record..............................TABLENAMERecDelete
Delete Table.................................TABLENAMETblDelete
Empty Table..................................TABLENAMETblEmpty
Encrypt Table................................TABLENAMETblEncrypt
Field Blank?.................................TABLENAMEFldBlank
File Lock....................................TABLENAMENetFileLock
File Unlock..................................TABLENAMENetFileUnlock
First Record.................................TABLENAMERecFirst
Get a Field Type.............................TABLENAMEFldType
Get a Record's Value.........................TABLENAMERecGet
Go To a Record...............................TABLENAMERecGoto
Go To Lock...................................TABLENAMENetRecGotoLock
Insert a Record..............................TABLENAMERecInsert
Last Record..................................TABLENAMERecLast
Next Record..................................TABLENAMERecNext
Number of Fields.............................TABLENAMERecNFlds
Number of Key Fields.........................TABLENAMEKeyNFlds
Number of Records............................TABLENAMETblNRecs
Open Table...................................TABLENAMETblOpen
Previous Record..............................TABLENAMERecPrev
Record Lock..................................TABLENAMENetRecLock
Record Locked?...............................TABLENAMENetRecLocked
Record Unlock................................TABLENAMENetRecUnlock
Rename Table.................................TABLENAMETblRename
Search by Field..............................TABLENAMESrchFld
Search by Key................................TABLENAMESrchKey
Table Changed?...............................TABLENAMENetTblChanged
Table Exists?................................TABLENAMETblExist
Table Lock...................................TABLENAMENetTblLock
Table Protected?.............................TABLENAMETblProtected
Table Refresh................................TABLENAMENetTblRefresh
Table Unlock.................................TABLENAMENetTblUnlock
Update a Record..............................TABLENAMERecUpdate

PARAGEN Function Text Message

TABLENAMEFldBlank.................................Field Blank?
TABLENAMEFldType..................................Get a Field Type
TABLENAMEKeyNFlds.................................Number of Key Fields
TABLENAMENetFileLock..............................File Lock
TABLENAMENetFileUnlock............................File Unlock
TABLENAMENetRecGotoLock...........................Go To Lock
TABLENAMENetRecLock...............................Record Lock
TABLENAMENetRecLocked.............................Record Locked?
TABLENAMENetRecUnlock.............................Record Unlock
TABLENAMENetTblChanged............................Table Changed?
TABLENAMENetTblLock...............................Table Lock
TABLENAMENetTblRefresh............................Table Refresh
TABLENAMENetTblUnlock.............................Table Unlock
TABLENAMERecAppend................................Append a Record
TABLENAMERecDelete................................Delete a Record
TABLENAMERecFirst.................................First Record
TABLENAMERecGet...................................Get a Record's Value
TABLENAMERecGoto..................................Go To a Record
TABLENAMERecInsert................................Insert a Record
TABLENAMERecLast..................................Last Record
TABLENAMERecNext..................................Next Record
TABLENAMERecNFlds.................................Number of Fields
TABLENAMERecNum...................................Current Record #
TABLENAMERecPrev..................................Previous Record
TABLENAMERecUpdate................................Update a Record
TABLENAMESrchFld..................................Search by Field
TABLENAMESrchKey..................................Search by Key
TABLENAMETblAdd...................................Add to Table
TABLENAMETblClose.................................Close Table
TABLENAMETblCopy..................................Copy Table
TABLENAMETblCreate................................Create Table
TABLENAMETblDecrypt...............................Decrypt Table
TABLENAMETblDelete................................Delete Table
TABLENAMETblEmpty.................................Empty Table
TABLENAMETblEncrypt...............................Encrypt Table
TABLENAMETblExist.................................Table Exists?
TABLENAMETblNRecs.................................Number of Records
TABLENAMETblOpen..................................Open Table
TABLENAMETblProtected.............................Table Protected?
TABLENAMETblRename................................Rename Table

WARNING MESSAGES

Source file(s) already exist overwrite them ?

PARAGen has found source files that already exist with the same names. If
you answer YES/OK, PARAGen will overwrite these files with the new
contents, NO/CANCEL nothing happens.

Clear current working table from memory?

PARAGen is asking if you want to delete the current working table from
memory. If you answer YES, PARAGen will clear the table out. You must
then use either use the Table | Open or Table Create option to reload a
table. Answering NO will do nothing.

No functions selected, nothing to generate.

You tried to generate function code, but there were not any functions
selected. Select the functions to generate from the Functions choice on
the main menu.

Table exists already, overwrite

PARAGen has found a table with this name already. It is asking for
permission to overwrite it. If you answer YES/OK, it will overwrite the
table with the new contents, else nothing happens.

Delete field XXXXXXXXXXX are you sure?

PARAGen is asking for permission to delete the current field specified by
XXXXXXXXXXXXX. This warning only occurs in the Table | Create option.
Answering YES/OK, deletes the current field, else nothing happens.

No fields present in table, nothing to (create/delete/edit).

No fields are in the newly created table. Therefore there is nothing to
delete, edit or create. Add some fields using one of the add options, Add
Field Above, or Add Field Below.

No fields specified, unable to generate SrchFld function.

No field names were selected to be placed in the TABLENAMESrchFld function.
Therfore it will not be generated. Chosse the Fields option off the main
menu to select the fields to search on.

Blank field names are not allowed.

Blank field names are not allowed in a newly created table. Enter a valid
field name or CANCEL to exit.

Field XXXXXXXX already exists, please try another name.

A duplicate field name was found during the creation of a new table. Enter
a valid field name, or change the current name to something different.
CANCEL will exit.



Invalid path/filename specified for table

An invalid path, filename, or an invalid path and filename were specified
in the Table | Create option. You must specify a valid path. PARAGen does
not create the directory or subdirectories if they do not exist. If the
filename exists, you will prompted with an overwrite option.

ERROR MESSAGES

File is corrupt

The PARAGen executable, PARAGENW.EXE or PARAGEND.EXE has been corrupted.
This error is a fatal error and should be reported to Innovative Data
Solutions, Inc., at once.

Unable to open file XXXX

PARAGen was unable to open the specified file. Make sure the file is a
valid PARADOX table, and try again.

PARADOX Engine initialization failed.

The PARADOX Engine was not able to intialize. See the PARADOX Engine
manual for details.

No file specified.

PARAGen has detected that there was no file name specfied in the Table |
Open dialog box. Type in a valid file name and try to Open the file again.

Wildcards not allowed.

PARAGen will not except wildcards for a file name as the file spec during
the Table | Open process. You must use the Open dialog list box to
determine where a file exists and to chosse it. Wildcards are only allowed
for the DOS extension.

Non-consecutive key found, field XXXXXX

PARAGen has found a non-consecutive key while trying to create a new table.
XXXXXX, is the field found to be non-consecutive. Remember, keys must be
consecutive starting in field one (1).

Internal Error

PARAGen has found an internal error during processing, please call
Innovative Data Solutions and report the error immediately.

OTHER ERRORS

The following errors are all errorrs returned by the PARADOX Engine. For
more information consult the PARADOX Engine Users Manual, and Reference
Guide.

Invalid table name Table was not found
Unable to perform operation on open fileTable is write protected
Table is corrupted Not enough disk space to complete operation
Not enough memory to complete operationArgument is out of range
Primary index corrupted Sort of index different from table
Not enough swap buffer space for operationTable is busy
Table is locked Insufficient password rights
Invalid table handle Invalid field handle
Buffer to small for result


 December 9, 2017  Add comments

Leave a Reply