Dec 212017
 
.DLL for accessing dBase files/Clipper NTXs from within Visual Basic.
File VXBASE.ZIP from The Programmer’s Corner in
Category BASIC Language
.DLL for accessing dBase files/Clipper NTXs from within Visual Basic.
File Name File Size Zip Size Zip Type
README.TXT 115213 30767 deflated
TPCREAD.ME 199 165 deflated
VXBDLL.ZIP 154855 153948 deflated
VXBTEST.ZIP 80411 76339 deflated

Download File VXBASE.ZIP Here

Contents of the README.TXT file


vxBase 2.02 October 21, 1992
-----------------------------

IMPORTANT NOTE TO EXISTING VXBASE USERS:
----------------------------------------
See the VXLOAD.EXE discussion below.

Prerequisites
-------------
vxBase is a dynamic link library of xBase functions that has been
customized for use with Microsoft Visual Basic. You must have
Visual Basic in order to run the VB sample application.
If you are intending to use vxBase with another language (such as
C), create the directory \VB before beginning installation of vxBase.
The default installation directory is \VB, which is where
Visual Basic is normally set up. The directory that vxBase is
installed into MUST exist. If \VB does not exist, or if you wish
to install vxBase into another directory, ensure that it exists
prior to installation.

vxBase Installation
-------------------
If INSTALL.EXE is resident on this diskette, use the
program manager RUN command A:INSTALL to install
vxBase. If changing the default directory from \VB,
the directory being changed to MUST exist.


ZIP version
-----------
vxBase is distributed on a single diskette or on bulletin boards
as two compressed .ZIP files. The first ZIP file is vxbdoc.zip, which
contains the documentation in a Windows Write file. This file is
essential to understanding and using vxBase. If it is missing, contact
the author at the address below. The documentation is separated from
the rest of vxBase to allow potential users to preview it before
installing and actually using vxBase. This is especially helpful to
potential users who extract vxBase from a bulletin board. They can
evaluate the system from a documentation standpoint before committing to
downloading the larger system.

Unzip vxbdoc.zip and view or print it. The manual is more than
180 pages long. It was formatted for an Epson 24-pin printer using
standard Courier fonts. Printed manuals may be obtained for $20.00.
See the end of the documentation for ordering information.

The second ZIP file (vxbase.zip) contains the sample source code
and Visual Basic project files, vxbase.txt which includes all of the Visual
Basic declarations for the routines in the vxBase DLL, the vxBase DLL
itself, and VXLOAD.EXE - a Visual Basic Design Mode Utility.

If you are going to upload vxBase to a bulletin board, it must be
sent as it was received - in two ZIP files.

When the system ZIP file is decompressed, it contains this readme.doc
file and 2 more ZIP files. These ZIP files are:

vxbdll.zipthe vxBase DLL and vxload.exe
vxbtest.zipsample source code and vxbase.txt

To install vxBase, first make a subdirectory under your \vb
directory named \vb\vxbtest and copy the vxbtest.zip file there. Unzip it
and delete the vxbtest.zip file from your hard disk. To run the sample
application it is essential that these files be in directory \vb\vxbtest
because this path is hard-coded into the sample code. If you MUST put it
somewhere else, you'll have to modify the file names in the source code to
reflect your location.

Unzip vxbdll.zip and place the resulting files (VXBASE.DLL and VXLOAD.EXE)
in your \windows directory.

To run the sample program, see the Sample Application section in the
manual. Remember to run vxload.exe before starting Visual Basic.


Better Memory Management in Design Mode with VXLOAD.EXE
-------------------------------------------------------
NOTE: vxload.exe included with vxbase is a utility that simply
loads vxbase.dll and runs in an iconized state. It is
highly recommended that you run this program immediately
PRIOR to calling up Visual Basic in Design Mode. vxload
controls the vxbase memory. Any crashes when testing a vxbase
program in design mode will not affect the vxbase memory pool
at all if vxload is running. Copy vxload.exe to your \windows
directory and set it up as a group item next to your VB icon.

It is also suggested that you add the following two lines of
code to your initialization procedure (somewhere after the call
to vxInit()):

Call vxSetLocks(FALSE)
j% = vxCloseAll()

vxSetLocks is described in detail below.

Adding these two lines to the init procedure will close any
files that were left open as a result of a Design Mode VB
error. vxSetLocks will ensure that any open files left over
from a crashed VB run will not have any leftover locks on
your second and subsequent runs of the program while in Design
Mode - and vxCloseAll will close any leftover files so you can
start off with a clean slate.

If you wish to use the default locking scheme in your finished
.EXE, remove the vxSetLocks(FALSE) that you set up for design mode
testing before compiling (and the vxCloseAll as well although
that is not critical).

If your vxBase program terminates abnormally (or you use the VB End
menu item to terminate), and then you exit Visual Basic, an
attempt to close VXLOAD.EXE from the system menu that appears
when you click on its icon will result in a "Task Sequence Closure
Error". This is because your vxBase Visual Basic program never
called vxDeallocate, which removes Visual Basic from the vxBase
task list being maintained by VXLOAD. If this happens to you,
simply double click the VXLOAD icon to bring the VXLOAD window
into view and select the EXIT menu item. Closing VXLOAD in this
fashion ignores the task list.

vxBase 2.02 October 21, 1992
-----------------------------
(1) formatted vxMemoRead with memo ending in 2 spaces caused
GPF. Problem corrected.

(2) Multitask index select error corrected.

(3) Obscure "DataBase not selected" and "Internal index root
seek errors" corrected.

(4) Win API OpenFile function substituted for MSC _sopen to
stop error when opening more than 15 files

(5) vxLocked/vxIsRecLocked now reports correct lock status
on network files. Previously, only the status as imposed
by the current workstation was reported.

(6) vxUseDbf, vxUseDbfRO, and vxUseNtx now position the
record pointer to the top of the file and fill the
record buffer a la Clipper. Filters are respected.

(7) On multiuser Retry? message boxes, caption now set to
vxSetErrorCaption string instead of "vxbase" if present.

(8) Search algorithm in vxBrowse changed. If a table has been
defined with the vxTablexxx functions, the search is limited
to browse displayable data only. The search also will not
cross field boundaries as it does in the raw data display (where
the entire record is searched - unchanged from previous releases).

(9) VX_FLAT style added to vxCtlStyle. Define Global Const VXFLAT = 3
in global module before using as an attribute with vxCtlStyle.
VX_FLAT flattens VX_RECESS and VX_RAISE control styles. This attribute
may be used effectively to indicate the readiness of a text box to
accept data. If the text box is drawn on the form with no borders
and colored light gray, it is invisible on the form. You can use
vxCtlStyle with VX_RECESS, VX_RAISE, and VX_FLAT to dynamically
change the control's appearance.

(10) Italian support added to vxSetLanguage (VX_ITALIAN).

(11) The type of an index expression is now tested when the index is
opened with vxUseNtx. If the expression evaluates as numeric or
as a date, the open is denied. YOU MUST USE CHARACTER INDEX
EXPRESSIONS IN VXBASE. Use The STR() function to convert
numbers to strings and the DTOS() function to convert dates
to strings within your index expressions.

(12) date insertion in memo editor via F5 key now conforms to
international standards set with vxSetDate.

(13) potential sharing violation when opening a read only file
with vxUseDbfRO (or subsequent vxUseNtx calls) corrected.

(14) made vxErrorMsg and vxChrToInt functions exportable for
C users.

(15) Field functions changed to speed up alias testing.

(16) Error 912 incorrectly defined in manual as "Index key
does not exist" when it should have been "Index key
already exists". Occurs when attempting to add a key
whose key expression and record number already exist
in the index.

(17) vxAreaDbf now reports system wide area as reported in the
documentation.

(18) potential close error with vxCloseAll() corrected.

(19) sporadic no index key addition with big files corrected.

(20) vxZap now clears associated dbt file as well.

(21) VGA determination algorithm changed to allow 3d support
on ps/2 monitors.

(22) alias names defined with vxSetAlias now allowed in xBase
expressions with the classic alias delimiter "->"
(e.g., "master->namefld"). The delimiter for alias name use
in vxBase function calls remains the same (i.e., "master.namefld").

(23) vxCopy now respects filters. It may be used to create file
subsets.

(24) vxCtlFormat passes Enter and Escape keys to VB default procedure.

(25) Logical vxNtxRecNo is now synchronized with a physical vxGo.

(26) 2.00 file open error when using vxSetupPrinter corrected.

(27) vxFilterReset memory deallocation corrected.

(28) vxBrowse creeping window corrected when using a parent window
that has no menu bar.

(29) vxUseNtx creeping select area corrected if subsequent calls to
index open routine.


Functions Added to Release 1.07
-------------------------------
(1) vxBrowseSetup allows the user to fine tune the appearance of a
Browse table (both the old window browse and the new vxCtlBrowse).

(2) vxCtlBrowse allows the placement of a browse table in a form multiline
text box. Communication with the browse table is enabled with the new
vxCtlBrowseMsg function. The Browse table no longer has to be
terminated when a selection is made, etc. It also allows dynamic
memo linking. All standard events and procedures attached to the
text box may be used in normal fashion while the browse is
running.

(3) vxCtlBrowseMsg communicates with a vxCtlBrowse. Messages the programmer
can pass are both interrogatory and procedural (e.g., VXB_GETCURRENTREC
extracts the record number of the currently highlighted record and
VXB_REFRESH redraws the browse starting at a different record number).

(4) vxCtlFormat adds TEXT FORMATTING to vxBase. Add declaration
and global constants as defined below.

(5) vxCtlHwnd gets the window handle associated with a Visual Basic control.

(6) vxCtlPenWidth added to control the depth of Recessing and Raising
a control when using vxCtlStyle. Add declaration as defined below.

(7) vxDbfCurrent reports the current database select area. Add
declaration as defined below.

(8) vxErrorTest added to test the result of a vxBase function that uses
the alternate error method set by vxSetErrorMethod. Add VxErrorStruc
type and vxErrorTest function declaration as defined below.

(9) vxGetVersion returns a string containing the current
vxBase version number. Add declaration as defined below.

(10) vxFieldTrim returns a string representing the defined field with
trailing spaces removed. Add declaration as defined below.

(11) vxLocate searches for a record from and including the current
record position that satisfies a logical xBase expression.
The search direction may be specified. Add declaration and
constants as defined below.

(12) vxLocateAgain searches for a record from and NOT including
the current record position that satisfies a logical xBase
expression as defined by the last vxLocate for the selected
database. The search direction may be specified. Add declaration
and constants as defined below.

(13) vxNtxCurrent reports the current index select area. Add declaration
as defined below.

(14) vxNtxRecNo returns the ordinal position of the key in the
current index. Add declaration as defined below.

(15) vxPrinterDefault returns a string describing the Windows default
printer in a format suitable for use by vxPrinterSelect

(16) vxPrinterEnum enumerates all printers on the system and
returns a string suitable for setting the default printer
with vxPrinterSelect. Add declaration as defined below.

(17) vxPrinterSelect changes the default Windows printer. The
printer setup string must be in the same format as that
returned by vxPrinterEnum. Add declaration as defined below.

(18) vxReplDateString replaces a field with a date string
formatted as per vxSetDate (default "mm/dd/yy"). This goes hand
in glove with dates input into text boxes via vxCtlFormat
or displayed with vxDateString. Add declaration as defined below.

(19) vxReplRecord replaces the entire record buffer with the data
pointed to by a record typedef or string (see vxRecord). BE
CAREFUL with this function. No data checks are implemented!
Add declaration as defined below.

(20) vxSeekFast speeds up seek times on Read Only files by 35%.
Add declaration as defined below.

(21) vxSetAlias allows field qualification in all vxBase field
functions. Add declaration as defined below.

(22) vxSetErrorMethod allows an alternate method of trapping errors
found by vxBase. The normal method is to report the error through
a message box at run time. If you use the alternate method,
nothing is reported (for most functions); instead, an error
structure is filled with information about the error which
may be extracted with the vxErrorTest function. Add declaration
as defined below.

(23) vxSetMeters allows you to turn the analog meter bars displayed
by vxPack, vxReindex, and vxTestNtx on or off (default is ON).
Add declaration as defined below.

(24) vxSetRelation adds true relational capability to vxBase.
Add declaration as defined below.

(25) vxTableFieldExt added to provide column definitions
to vxBrowse when using vxSetRelation to add multi-file
fields on the same browse row. Add declaration as defined below.


International Functions Added
-----------------------------
The following functions all deal with the problem of a database
that contains characters from the high end of the ANSI or OEM
character sets, which is commonplace if the database stores data in
a language other than English.

(1) vxSetAnsi(FALSE) properly handles databases that were created
with a DOS based application (such as Clipper). These databases
are OEM databases. Characters with diacritical marks in the
high end of the OEM character collating sequence are NOT the
same as the ANSI characters. It is necessary for vxBase to
translate the characters to ANSI (both Windows and vxBase
native mode) before they can be used in a vxBase application.
They also must be translated back again when they are written.

The default value of vxSetAnsi is TRUE (no translation takes
place). If the database was created and is maintained by vxBase
(or DataWorks), and the database is going to be used exclusively
by Windows applications, vxSetAnsi should be TRUE.

(2) vxCollate allows the programmer to create his own collating
sequence table (for EITHER an ANSI database or an OEM database).
The OEM character set in particular does not use any kind of
logical collating sequence for characters with diacritical marks.
The ANSI table handles these characters more intelligently - but
its sequence is also incorrect for some languages.

It is necessary to define a collating sequence table to properly
build an index that uses these characters.

(3) vxSetCollate can toggle a defined collating table on or off.


=====================================================================
vxBrowseSetup
=====================================================================

Declaration
-----------
Declare Sub vxBrowseSetup Lib "vxbase.dll" (ByVal Menus%,
ByVal PrintMenu%, ByVal QCol%, ByVal V3D%, ByVal FontName$,
ByVal FontSize%, ByVal Weight%, ByVal Italic%, ByVal Hdr%,
ByVal MinMax%, ByVal Thresh%)

Purpose
-------
Controls the appearance and some of the functionality of a vxBrowse or
vxCtlBrowse.

Parameters
----------
Menus% controls the standard menus added to a vxBrowse window. If FALSE,
both the Utility menu and the Query menu are suppressed. This parameter
has no effect on a vxCtlBrowse because a vxCtlBrowse has no menus.

PrintMenu% controls the placement of the "Print" menu item on the
vxBrowse menus. If the value is 0 (zero), no print menu item will be
added; if 1, the print menu item appears on the standard edit menu (the
default); if 2, the print menu item will appear on the Utilities menu.
This parameter has no effect on a vxCtlBrowse.

QCol% is the number of the column (relative to 1) that responds to
Quick Key seeks. If this parameter is specified, an asterisk "*" is
placed in front of the header text for that column to indicate that
this column is seekable with quick key strokes.

V3D% if TRUE will display the browse table in 3d format on a gray
background. If FALSE, the browse is displayed as conventional
black text on a white background. Each record and column is separated
with a light gray line to give the appearnce of a grid.

FontName$ is the name of an available font that will be used to display
the browse table. It must be a valid name. A good place to look at an
enumeration of your fonts is in the list box of fontnames on the VB
properties bar for a text box.

FontSize% is the size of the font in points. This number is device
dependent to some extent (on your video resolution). Experiment before
assuming that a given font size will yield the desired result.

Weight% is a vxBase Global constant that specifies the weight of the
font. The following constants are defined in vxbase.txt:

Global Const VX_DONTCARE = 0
Global Const VX_THIN = 100
Global Const VX_EXTRALIGHT = 200
Global Const VX_LIGHT = 300
Global Const VX_NORMAL = 400
Global Const VX_MEDIUM = 500
Global Const VX_SEMIBOLD = 600
Global Const VX_BOLD = 700
Global Const VX_EXTRABOLD = 800
Global Const VX_HEAVY = 900

Italic% if TRUE will display the font in italic. If FALSE (the
default), the display is not in italic.

If you do not wish to change the font (from the default Windows
System font), pass the font name as a space, the fontsize as 0,
the weight as 0, and italic as FALSE.

Hdr% defines the type style used in the column headers. The default
is FALSE (which is shadowed text). If passed as TRUE, the header text
is displayed in a flat style.

MinMax% defines whether or not minimize and maximize buttons will
appear on the browse window. If FALSE (the default) there are no buttons;
if TRUE, the buttons appear. This parameter has no effect on vxCtlBrowse.

Thresh% defines the number of records used as a threshold for
implementing the vxBase relative scroll thumb positioning algorithm. The
default value is 5000 (which is what you get if you specify 0).

Thresh% Explanation: If the user positions the vertical scroll thumb, the
browse display will begin at a point that is relative to the proportion
of the new thumb position to the vertical scroll bar length. In other words,
if the thumb is positioned to the middle of the vertical scroll bar,
the record pointer is moved to the middle of the file.
This is easy if no indexes are being used (and in this case the threshold
does not apply). We simply take the number of records and divide by 2 and
that's where we start the display.
If the file is indexed, however, we must position the record pointer to
the logical middle of the file. This means we have to count keys (just like
vxNtxRecNo does) until we reach the middle key and then position the record
pointer to the physical record pointed to by the ntx key entry.
This can take time if the file is large. An optimum size that yields a
respectably short time is about 5000 records (which is the default
threshold). If the file is larger than this, vxBase uses a key analysis
algorithm to determine the approximate position of the file (high key
value minus low key value times the scroll thumb proportion plus the low
key value equals an approximate key we can softseek on). This algorithm
works quite well on a database that is regularly sequenced (for example,
a name and address file with a fairly regular distribution of names
throughout the alphabet will yield a key close to "M" to start the
display at if the thumb is positioned in the middle of the scroll bar).
If your database contains more than 5000 records, and the distribution
of keys is irregular (e.g., many duplicate keys or duplicate starting
portions of keys or lots of A's and Z's with nothing in between), then you
will likely wish to increase the threshold value to a number greater than
the number of records in the file to use the exact relative positioning
algorithm.
What's more important? Speed or an accurate thumb? This is a question
for the ages.

Returns
-------
Nothing.

Usage
-----
Use this procedure to fine tune the appearance and functionality of
your browse tables (both of the vxBrowse and the vxCtlBrowse variety).

Note: the database you are going to be browsing must be open and
selected when the call to this procedure is issued.


Example
-------
' the browse must be set up either prior to
' or during the load of the form that contains
' the text box that will hold the browse
' --------------------------------------------
Sub Form_Load ()
vxClientDbf = vxUseDbf("\ab2\abacus\sam\vxuser.dbf")
vxCl1Ntx = vxUseNtx("\ab2\abacus\sam\vxuser.ntx")

Call vxTableDeclare(VX_RED, ByVal 0&, ByVal 0&, 0, 1, 6)
Call vxTableField(1, "Serial", "vxser", VX_FIELD)
Call vxTableField(2, "Name", "vxname", VX_FIELD)
Call vxTableField(3, "Company", "vxcompany", VX_FIELD)
Call vxTableField(4, "Phone", "vxphone", VX_FIELD)
Call vxTableField(5, "City", "vxcity", VX_FIELD)
Call vxTableField(6, "Country", "vxcountry", VX_FIELD)

Call vxBrowseCase(VX_UPPER)
Call vxBrowseSetup(0, 0, 1, 1, "Arial Narrow", 15, VX_SEMIBOLD,
FALSE, 0, 0, 0)
End Sub



See Also
--------
vxBrowse
vxBrowseCase
vxBrowsePos
vxCtlBrowse
vxCtlBrowseMsg
vxMenuDeclare
vxMenuItem
vxSetLanguage
vxSetRelation
vxTableDeclare
vxTableField
vxTableFieldExt
vxTableReset


=====================================================================
vxCollate
=====================================================================

Declaration
-----------
Declare Sub vxCollate lib "vxbase.dll" (CharMap As Integer)

Purpose
-------
Define a collating sequence table to be used for indexing other than
the native collating table (ANSI or OEM depending on the setting of
vxSetAnsi).

Parameters
----------
CharMap is the first element in an array of 256 integers. Each integer
represents the new collating sequence number for the character that would
normally occupy that slot (array index - 1).

The collating sequence table is composed of 256 characters that range in
value from zero to 255. Consequently, the index (minus 1) into the character
map represents the current native character. By placing a different number
into the integer at that spot we change its collating sequence to the new
number.

For example, suppose you wanted a space character to be first (lowest) in
your new collating sequence. A space is represented by decimal 32 (it is the
33rd character in the set which begins at zero) in both the ANSI and OEM
character sets. To make a space the lowest value in your index collating
sequence, you would place a zero in CharMap(33). The index number is the
same as the decimal value of the character you wish to change plus one (for
relative zero).

Note that the first integer in the array is passed BY REFERENCE rather
than by value.

Returns
-------
Nothing.

Usage
-----
This function is used primarily for non-English language databases. The
collating sequence of characters with diacritical marks that are used heavily
in languages other than English is certainly incorrect in the OEM character
set (for any language) and could be incorrect for certain languages if you
are using ANSI databases as well (e.g., Swedish). To maintain index keys in
a sequence that the user can understand, this function must be used to build
a collating table.

The example below shows you how to build a true descending index in English
(the DESCEND() xBase function simply complements the bits in the key and
creates a normal ascending index that results in descending order).

vxCollate can also be used for purposes like this but you must be careful to
toggle the use of the table on and off with vxSetCollate. The table shown in
the example would only be turned on for the file and index that it applied to.
If there is more than 1 index for the file, using a table like this WILL be
disastrous.

The new collating sequence table passed to vxCollate() MUST contain
256 elements. If fewer than 256, Windows will crash with a GPF.

THIS IS A SYSTEM WIDE FUNCTION THAT APPLIES TO ALL CONCURENT VXBASE TASKS!

Example
-------
Dim CharMap(256) As Integer

Sub Form_Load ()
Call vxInit
Call vxCtlGraySet
Call vxCtlGraySet
Call vxSetLanguage(VX_GERMAN)
Call vxSetLocks(FALSE)
Call vxSetString(0)
j% = vxCloseAll()

' using OEM databases
' -------------------
Call vxSetAnsi(FALSE)

' create descending collating sequence table
' ------------------------------------------
i% = 255
For j% = 1 To 256
CharMap(j%) = i%
i% = i% - 1
Next j%
Call vxCollate(CharMap(1))

' build descending index
' ----------------------
vxDbf = vxUseDbf("\vb\vxuser.dbf")
vxBackNtx = vxCreateNtx("\vb\vxback.ntx", "upper(vxname)")
j% = vxClose()


' turn off table usage until required
' -----------------------------------
Call vxSetCollate(FALSE)

End Sub

See Also
--------
vxSetAnsi
vxSetCollate


=====================================================================
vxCtlBrowse
=====================================================================

Declaration
-----------
Declare Function vxCtlBrowse Lib "vxbase.dll" (ByVal ControlHwnd%,
ByVal DbfArea%, ByVal NtxArea%, ByVal EditMode%,
ByVal StartRec&, ByVal MemoHwnd%, ByVal MemoField$) As Integer

Purpose
-------
Place a browse table into a multiline text box control. The browse
table is bounded by the confines of the text box. The browse reacts to
standard events (mouse pointing and clicking, quick key presses, etc.)
in the same fashion as vxBrowse. Communication with the Browse table
is accomplished though the use of button controls (or menu items) on the
main form and the use of vxCtlBrowseMsg.

The main differences between vxBrowse and vxCtlBrowse are:

vxBrowse is a popup window unto itself (even a task), and is controlled
with its own message loop. It may be resized, moved, minimized, etc.
After it is started, communication between the calling program and
vxBrowse is a one way street; vxBrowse can tell the calling program
what the user did but the calling program cannot interrogate anything
that happens during the browse. After the browse window is closed,
vxBrowse reports the user action to the calling program.

vxCtlBrowse is a child window that resides entirely within the
confines of a bounded text box on a main form. Communication works
both ways; the browse window can report certain events through
standard procedures (e.g., key presses and key downs), it can
report its state (what record number is highlighted?), and it can
be controlled by the programmer and by the user (e.g., redraw
thyself starting someplace else). It does not have to go away in
order for the programmer to react.

vxBrowse is perfect for help pick lists and as a primary tool to
view a set of records in tabular format. As a pick list help tool, the
window pops up over top of another window, the user picks something (or not),
and the window goes away - leaving the programmer with the user's choice
(or not). vxBrowse can also be used to initiate and display dynamic one
to many relationships. vxCtlBrowse cannot do this dynamically - only
under programmer control.

vxCtlBrowse is much more flexible in that it can stay around and react
to and be affected by user (and programmer) actions. Its not as good as a
help pick list and its no good at all as a quick and dirty report generator.

vxCtlBrowse can also dynamically display memos in a second text box!
(highlight a record that has a memo and the memo appears in the defined
text box).

Parameters
----------
ControlHwnd% is the window handle of the multiline text box that the browse
is going to inhabit. The window handle is not directly available from Visual
Basic. It must be extracted with vxCtlHwnd (see the example in vxCtlBrowseMsg
below).

DbfArea% is the select area of an open database. If it is not currently
selected, vxCtlBrowse will make it the current selection.

NtxArea% is the select area of an index file attached to DbfArea%. Pass a
0 (zero) if no idex is to be used.

EditMode% is passed as TRUE or FALSE. If TRUE, a mouse doubleclick on a
browse row/column will pop up an edit window with the text of the selected
field ready for edit. Note that the only data validation possible with the
onscreen edit is for type (e.g., numeric fields must contain numbers). If
your data requires more sophisticated validation, never pass a TRUE in this
parameter.
If EditMode% is FALSE, a mouse doubleclick will be converted to an
ENTER key value and may be interrogated in the textbox_keypress event
procedure. Before the key is passed, the record pointer is positioned to
the currently highlighted record so it is automatically available to
vxRecNo() if desired.
See the writeup in vxBrowse under EditMode for information on the relation-
ship between this parameter and vxTableDeclare/vxTableField.

StarRec& is a long integer that contains the browse table starting record
number. If passed as 0 (zero), the display will commence at the top of the
file. If a record subset has been defined with vxTableDeclare, it is the
programmer's responsibility to ensure that the pointer is positioned to the
correct starting record prior to calling vxCtlBrowse.

MemoHwnd% is the window handle of a multiline text box that may contain the
contents of a dynamic memo link. The window handle is not directly available
from Visual Basic. It must be extracted with vxCtlHwnd (see the example in
vxCtlBrowseMsg below). If there is no memo link, pass this parameter as a
0 (zero).

MemoField$ is the name of the memo field that will be dynamically linked
to the browse table. Whenever a record in the browse table receives the
highlight, and that record contains a memo reference in this field, then
the memo will be displayed in the MemoHwnd% text box. Pass this parameter as
a space (" ") if there is no memo link. If a relationship has been set up
and is being displayed by the browse, the memo field must belong to the
parent file. NO ALIAS NAMES ALLOWED.

Returns
-------
TRUE if the browse was successfully set up. FALSE is returned for one of
the following reasons:
(1) no current database.
(2) DbfArea% is invalid.
(3) no more browse windows available (maximum of 16 active at once in all
concurrent vxBase tasks - NOT including any vxBrowse windows).
(4) ControlHwnd% is invalid.
(5) The browse has already been set up in ControlHwnd% (you don't have to
worry about calling the same browse twice into the same window - it simply
returns FALSE).
(6) The file selected with DbfArea% is empty.
(7) Invalid memo field name.
(8) Memo field name is not a memo.
(9) MemoHwnd% is invalid.
(10) Out of memory.

Usage
-----
A wonderful tool for displaying and activating file editing procedures.
Users expect data to be presented in tabular format. That's why phone
books are so successful. Use vxCtlBrowse to provide a gross view of the
data, and then use vxCtlBrowseMsg to react to the user's requests.

Please see the sections entitled "Quick Key", "Vertical Scrolling",
and "Multiuser Considerations" under vxBrowse.

NOTE: The text box that is created to hold the browse must be given the
multiline property. If scroll bars are required to display all of the data
(either vertical, horizontal, or both), vxCtlBrowse will automatically
provide them.

vxCtlBrowse may not be called from a Form_Load procedure. The text box
that is to hold the browse has not been created yet so no window handle
may be passed to vxCtlBrowse. The best place to call it is in the
Form_Paint procedure. Form_Paint of course may be called many times
during the life of the form but vxCtlBrowseMsg will not invoke itself
any more than once for a defined text box control. See the example
in vxCtlBrowseMsg below.

Browse Navigation
-----------------
The browse may be perused vertically with the mouse and the scroll bar,
the Page Up and Page Down keys, the Home and End Keys, and the up and down
arrow keys.

The horizontal aspect may be controlled with the mouse and the scroll
bar, the right and left arrow keys, and Ctrl-Left and Ctrl-Right to
move horizontally a page at a time.

Example
-------
SEE vxCtlBrowseMsg BELOW.

See Also
--------
vxBrowse
vxBrowseSetup
vxCtlBrowseMsg
vxSetRelation
vxTableDeclare
vxTableField
vxTableFieldExt
vxTableReset


=====================================================================
vxCtlBrowseMsg
=====================================================================

Declaration
-----------
Declare Function vxCtlBrowseMsg Lib "vxbase.dll" (ByVal Hwnd As
Integer, ByVal Msg As Integer, Param As Any) As Long

Purpose
-------
Communicate with a vxCtlBrowse text box. Messages and directives
to the browse are passed via this function, usually via a button
or menu item click event. The browse can return requested information
or react to a directive issued by vxCtlBrowseMsg.
The vxCtlBrowse may also send messages back to the KeyPress and
KeyDown event procedures.

Parameters
----------
Hwnd is the window handle of the multiline text box that the browse resides
in. The window handle is not directly available from Visual Basic. It must be
extracted with vxCtlHwnd (see the example below).

Msg is one of the following Global Constants as defined in vxbase.txt:

Global Const VXB_REFRESH = 0
Global Const VXB_FILTERDLG = 1
Global Const VXB_FILTERPRG = 2
Global Const VXB_GETCURRENTREC = 3
Global Const VXB_GETTOPREC = 4
Global Const VXB_STATS = 5
Global Const VXB_CASE = 6
Global Const VXB_SEARCHDLG = 7
Global Const VXB_SEARCHPRG = 8
Global Const VXB_SEARCHAGAIN = 9
Global Const VXB_SEEK = 10
Global Const VXB_CLOSE = 11

Each message is discussed under Param below.

Param is a parameter that accompanies a message to the vxCtlBrowse. Each
message that requires a Param must have that Param passed ByVal. If a
message does not require a Param, it may be passed as 0 (zero).

* -----------------------*
DON'T FORGET THE BYVAL.
* -----------------------*

VXB_REFRESH: redraws the browse window. Param must be passed as a long
integer that contains a display start record number. This message
would be sent after editing, adding, or deleting a record that
affects the visible browse display. If you wish to start the display
at the same position, use VXB_GETTOPREC to set the start record
number passed with this message. If the record number is 0 (zero) or
greater than the number of records in the file (vxNumRecs()), no
refresh takes place. The return value may be ignored.

VXB_FILTERDLG: invokes the same vxBase filter dialog box that is used
by the vxBrowse Filter menu command. The user may enter his own
xBase filter expression. This message should be reserved for
expert users only. Use the next message (VXB_FILTERPRG) after
extracting filter parameters from the user and building the xBase
expression under program control. Param is passed as 0 (zero).
The return value may be ignored.

VXB_FILTERPRG: Sets a filter on the browse table. Param is passed BYVAL
as a complete xbase expression that evaluates as a logical TRUE
or FALSE. Note that deleted records are always filtered out of a
vxCtlBrowse display. This is the preferred method of filter setting
because things like field names and xBase function syntax can be
controlled by the programmer (what user expects an address field to
be named "A1"?). The return value may be ignored.

A filter set on the file with vxFilter() prior to the browse will
be overridden by a filter set by either VXB_FILTERDLG or
VXB_FILTERPRG (even though it is in effect when the browse
commences). The filter will take effect again when the browse
is closed.

A filter may be cancelled by passing Param as ByVal 0& as follows:
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_FILTERPRG, ByVal 0&)

VXB_GETCURRENTREC: Retrieves the physical record number of the record
that is currently highlighted in the browse display. Param is passed
as 0 (zero). A long integer containing the record number is returned.
This message would normally be used in response to a button press
that invoked a record edit procedure. The user clicks the "Edit" button;
the programmer reacts in the EditButton_Click event procedure by first
going to the record using this message, extracting the record contents
and presenting the data in text boxes on the same or another form for
editing.

VXB_GETTOPREC: Retrieves the physical record number of the record that sits
at the top of the browse display. Param is passed as 0 (zero). A long
integer containing the record number of the top record is returned.
After editing, adding, or deleting records, you probably want the
display to restart at the same place that the user left off (to provide
some continuity to the session). See VXB_REFRESH above.

VXB_STATS: Presents a file statistics dialog box - its name, size, number
of records, and a list box containing the field structure of the file.
Param is passed as 0 (zero). The return value may be ignored.

VXB_CASE: The case of the display is toggled. If it started out as VX_UPPER
(see vxBrowseCase), it becomes all lower, and vice versa. Note that
VX_UPPER means as it was entered - not necessarily all upper case.

VXB_SEARCHDLG: Invokes a search dialog box that prompts the user for a
string. If the string exists in the table, the record that contains
the string is highlighted. If the browse was set up with vxTableDeclare,
only columns defined with vxTableField are searched. Field boundaries
are respected. If a the browse is a raw data display, the entire record
is searched for the string. If a match is found that crosses field
boundaries or not, the record is highlighted. Param is passed as 0
(zero). The return value may be ignored.

VXB_SEARCHPRG: Searches for a string passed ByVal in Param. This search
is under programmer control. The same search algorithm as above is
used. The return value may be ignored.

VXB_SEARCHAGAIN: Search for the same string (as passed via VXB_SEARCHDLG
or VXB_SEARCHPRG) again - skipping forward one record first. Param is
passed as 0 (zero). The return value may be ignored.

VXB_SEEK: Perform a softseek on the index (see vxSeekSoft). Param is passed
ByVal as a string. A record is highlighted if there is a partial
match or exact match. If there is no match, but a record exists with a
key higher than the search key, it is highlighted instead. The return
value may be ignored.

VXB_CLOSE: This is a very important message that must be issued to the
vxCtlBrowse window when the form containing the text box is unloaded.
It reclaims memory, clears the data structure that was set up
vxCtlBrowse, and clears the edit box that the browse lived in. You may
issue this message any time (not just when unloading the form) to
start a new browse on a different file, or with a different index, or
whatever. Just remember that there shouldn't be any active vxCtlBrowses
left over when you unload the form (or end the program). Param is
passed as 0 (zero). The return value may be ignored.

Returns
-------
The only two messages that result in a return of any value are
VXB_GETCURRENTREC and VXB_GETTOPREC. These return record numbers as long
integers. Returns from all other messages may be ignored.

Usage
-----
vxCtlBrowseMsg is the only way you have of communicating with a vxCtlBrowse.
vxCtlBrowse also communicates with you through the KeyPress and KeyDown
event procedures attached to the text box.
If the user presses the ENTER key, or doubleclicks on a record when
the EditMode parameter of vxCtlBrowse is FALSE, an value of 13 is passed through
the KeyAScii parameter of the TextBox_KeyPress event. This is usually a signal
that the user wishes to do something with the record that currently has the
highlight (expand it, edit it, etc. - its up to you). YOU MUST SET KEYASCII TO
0 (ZERO) BEFORE THE KEYPRESS EVENT PROCEDURE EXIT AFTER RECEIVING AN ENTER KEY
SO IT DOESN'T GET THROUGH TO THE TEXT BOX.
The ESCAPE key is also passed to the KeyPress event procedure as KeyAscii
value 27.
The TextBox_KeyDown event procedure receives INSERT presses (as KeyCode 45)
and DELETE presses (as KeyCode 46) as well. You may react or not react to these
events as you wish.
The KeyDown event is aso triggered as KEY_MBUTTON (KeyCode value 4) whenever
a record is highlighted in the browse display. You can dynamically display a
record that is highlighted by trapping this event. For example,

Sub BrwBox_KeyDown (keyCode As Integer, Shift As Integer)
If keyCode = KEY_DELETE Then
CommDel_Click
ElseIf keyCode = KEY_INSERT Then
CommAdd_Click
ElseIf keyCode = KEY_MBUTTON Then
ReadData
End If
End Sub

The ReadData procedure would look like this:
Sub ReadData ()
j% = vxGo(vxCtlBrowseMsg(vxCtlHwnd(BrwBox), VXB_GETCURRENTREC, 0))
DbfName.Text = vxFieldTrim("DBF_NAME")
FldNam.Text = vxFieldTrim("FIELD_NAME")
FldDsc.Text = vxFieldTrim("FIELD_DESC")
End Sub

Focus Issues
------------
The browse display receives the focus automatically when it is created.
The focus is also automatically shifted back to the browse after vxCtlBrowseMsg
completes its task. Whenever the focus leaves the browse window, the column
header row is inverted (red becomes cyan, etc.) The user can reset the focus
if it is gone by tabbing to the text box, clicking on it, etc. - all the
normal ways. You can also reset the focus with the SetFocus Method under
program control.

Memos
-----
Dynamic memo links result in the display of a defined memo whenever one
exists that is attached to a highlighted record. You may allow the user to
edit the memo or not - save it or not (with vxReplMemo).

Example
-------
The following example is the actual code used to alpha test the
vxCtlBrowse function. The VB form had the following elements:

BrowseBox: multiline text box.

MemoBox: multiline text box with a vertical scroll bar attached.

Buttons:
ButtonAgain to test VXB_SEARCHAGAIN
ButtonCancFilt to test VXB_FILTERPRG, ByVal 0&
ButtonCase to test VXB_CASE
ButtonCurRec to test VXB_GETCURRENTREC
ButtonExit to unload form and test VXB_CLOSE
ButtonFilter to test VXB_FILTERDLG
ButtonPrgFilt to test VXB_FILTERPRG
ButtonRefresh to test VXB_REFRESH
ButtonSearch to test VXB_SEARCHDLG
ButtonStrSearch to test VXB_SEARCHPRG
ButtonTopRec to Test VXB_GETTOPREC

Note the use of vxCtlHwnd to convert a VB control handle
into a Window Handle (in vxCtlBrowse and vxCtlBrowseMsg calls).

' --------------------------------------------
' the browse must be set up either prior to
' or during the load of the form that contains
' the text box that will hold the browse
' --------------------------------------------
Sub Form_Load ()
vxClientDbf = vxUseDbf("\ab2\abacus\sam\vxuser.dbf")
vxCl1Ntx = vxUseNtx("\ab2\abacus\sam\vxuser.ntx")

Call vxTableDeclare(VX_RED, ByVal 0&, ByVal 0&, 0, 1, 6)
Call vxTableField(1, "Serial", "vxser", VX_FIELD)
Call vxTableField(2, "Name", "vxname", VX_FIELD)
Call vxTableField(3, "Company", "vxcompany", VX_FIELD)
Call vxTableField(4, "Phone", "vxphone", VX_FIELD)
Call vxTableField(5, "City", "vxcity", VX_FIELD)
Call vxTableField(6, "Country", "vxcountry", VX_FIELD)

Call vxBrowseCase(VX_UPPER)
Call vxBrowseSetup(0, 0, 1, 1, "Arial Narrow", 15, VX_SEMIBOLD,
FALSE, 0, 0, 0)
' the fontsize param of 15 comes out as about 8 point type
' on an SVGA at 1024/768 res
End Sub


' call vxCtlBrowse from the form_paint after
' the form has been initialized and displayed
' -------------------------------------------
Sub Form_Paint ()
j% = vxSelectDbf(vxClientDbf)
Call vxFormFrame(VXFORMX.hWnd)
Call vxCtlStyle(BrowseBox, VX_RECESS)
j% = vxCtlBrowse(vxCtlHwnd(BrowseBox), vxClientDbf, vxCl1Ntx,
TRUE, 0, vxCtlHwnd(MemoBox), "vxmemo")
End Sub

' to redraw formframe if resized
' ------------------------------
Sub Form_Resize ()
VXFORMX.Refresh
End Sub

' important to close vxCtlBrowse in form unload
' ---------------------------------------------
Sub Form_Unload (Cancel As Integer)
k& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_CLOSE, 0)
j% = vxSelectDbf(vxClientDbf)
j% = vxClose()
vxWindowDereg (VXFORMX.hWnd)
End Sub


' message testing functions
' invoked when buttons clicked
' ----------------------------
Sub ButtonExit_Click ()
Unload VXFORMX
End Sub

Sub ButtonSearch_Click ()
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_SEARCHDLG, 0)
End Sub

Sub ButtonAgain_Click ()
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_SEARCHAGAIN, 0)
End Sub

Sub ButtonCase_Click ()
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_CASE, 0)
End Sub

Sub ButtonCurRec_Click ()
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETCURRENTREC, 0)
Debug.Print j&
End Sub

Sub ButtonTopRec_Click ()
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_GETTOPREC, 0)
End Sub

Sub ButtonFilter_Click ()
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_FILTERDLG, 0)
End Sub

Sub ButtonSeek_Click ()
SeekKey$ = InputBox$("vxBase License?", "SearchKey", "")
If EmptyString(SeekKey$) Then
Exit Sub
End If
SeekKey$ = UCase$(SeekKey$)
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_SEEK, ByVal SeekKey$)
End Sub

Sub ButtonRefresh_Click ()
SeekRec$ = InputBox$("goto record?", "Refresh", "")
If EmptyString(SeekRec$) Then
Exit Sub
End If
GoRec& = Val(SeekRec$)
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_REFRESH, ByVal GoRec&)
End Sub

Sub ButtonStrSearch_Click ()
SeekStr$ = InputBox$("Search string?", "Search For String", "")
If EmptyString(SeekStr$) Then
Exit Sub
End If
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_SEARCHPRG, ByVal SeekStr$)
End Sub

Sub ButtonPrgFilt_Click ()
Filt$ = "trim(vxcountry)='U.S.A.'"
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_FILTERPRG, ByVal Filt$)
End Sub

Sub ButtonCancFilt_Click ()
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_FILTERPRG, ByVal 0&)
End Sub

' ------------------------------------------------
' KEY EVENTS Passed on to VB
' Enter (13) and escape (27) key presses initiated
' during the browse may be interrogated here.
' ------------------------------------------------
Sub BrowseBox_KeyPress (KeyAscii As Integer)
If KeyAscii = 13 Then
MsgBox "Enter key pressed"
' do your update or expansion routine here
Debug.Print vxRecNo()
KeyAscii = 0
Else
Debug.Print KeyAscii
End If
End Sub

' Insert and Delete keys (45 and 46) will show up here
' as well as a keycode 4 whenever a record is highlighted
' -------------------------------------------------------
Sub BrowseBox_KeyDown (KeyCode As Integer, Shift As Integer)
Debug.Print KeyCode
' do insert and delete funcs here
End Sub


See Also
--------
vxBrowse
vxBrowseSetup
vxCtlBrowse
vxSetRelation
vxTableDeclare
vxTableField
vxTableFieldExt
vxTableReset


=====================================================================
vxCtlFormat
=====================================================================

Visual Basic Declaration
------------------------
Declare Function vxCtlFormat Lib "vxbase.dll" (ByVal TextLen As Integer,
ByVal Picture As Integer, ByVal Decimals As Integer) As Integer

C Function Prototype
--------------------
int FAR PASCAL vxCtlFormat (int, int, int);


Purpose
-------
Control the format of text entry into Visual Basic text boxes
or standard Windows Dialog boxes.

Parameters
----------
TextLen is an integer defining the number of characters that may be entered
into the text box. Maximum length for VX_UPPER/VX_ALPHA fields is 255.
Maximum numeric field length is 19. Maximum date field is 8. If
these lengths are exceeded, vxBase defaults the lengths.

Picture is an integer that describes the type of data that may be entered
into the text box. In Visual Basic these types are defined in your Global
module as follows:

' vxCtlFormat Types
' (includes VX_UPPER = 0 AS DEFINED ABOVE)
' ----------------------------------------
Global Const VX_CHAR = 1
Global Const VX_ALPHA = 2
Global Const VX_NUM = 3
Global Const VX_DATE = 4
Global Const VX_PASSWORD = 5

// In C, they are defined as:
// --------------------------
#define VX_UPPER 0 // already defined as vxBrowseCase type
#define VX_CHAR 1
#define VX_ALPHA 2
#define VX_NUM 3
#define VX_DATE 4
#define VX_PASSWORD 5


VX_UPPER converts all lowercase characters to upper as they are typed.
VX_CHAR accepts any and all characters with no conversion.
VX_ALPHA only accepts alphabetic characters (both upper and lower case)
VX_NUM accepts only numbers. They must also be entered in the correct format
(i.e., the only characters other than numbers that may be entered into a
numeric box are a minus sign (-) in the first position and a decimal
character as defined in the win.ini international section if deciamls
are allowed).
VX_DATE accepts and validates dates in a format as defined by
vxSetDate.
VX_PASSWORD displays all typed characters as "*" but accepts any and
all characters.

Decimals is an integer that defines the number of decimal positions allowed
in a numeric field. The maximum number of decimals allowed is 17.

Returns
-------
TRUE if the format was successful or FALSE if not. FALSE is returned if
the maximum number of controls is exceeded (256) or if we run out of
memory.

Usage
-----
In Visual Basic, use vxCtlFormat in the GotFocus() event procedure for
the text box in which you wish to control the format.

In C, use the function in the WM_INITDIALOG message processing
routine.

The maximum number of active controls that may be formatted
with vxCtlFormat is 256.

IMPORTANT
---------
ALWAYS USE vxWindowDereg TO RELEASE THE MEMORY VXBASE ALLOCATES
TO THE FORMATTING ROUTINE AND TO RESET THE CONTROL PROCEDURE
ADDRESSES in your Visual Basic Form Unload Procedure or when a
C Dialog is ended.
---------------------------------------------------------------

If text is formatted as VX_UPPER, VX_ALPHA, VX_CHAR, or VX_PASSWORD,
characters are converted as they are typed. VX_DATE and VX_NUM formats
only allow numbers and delimiters as typing occurs.

VX_DATE and VX_NUM formats are validated when the control loses the focus.
An error message box is presented if the entered data does not pass
and the focus is reset to the offending control. For example, the number
123.45- is accepted in a numeric field as it is typed but when the
control loses the focus, the user is informed that the sign must
precede the number and focus is reset to the control. If an invalid
date is entered, a date mask as defined by vxSetDate is inserted into
the control after the user has been informed of the error.

PARAMETERS CHARACTERS ENTERED RESULT
---------- ------------------ ------
6,VX_UPPER,0 abC34F ABC34F
6,VX_CHAR,0 abC34F abC34F
8,VX_NUM,2 -123.456 -123.45
23 23.00
23. 23.00
123456.7 23456.70 truncates on left
123.4567 123.45 truncates on right

8,VX_DATE,0 4/1/92 04/01/92 inserts appropriate leading
04/1/92 04/01/92 zeroes

6,VX_PASSWORD,0 abC34F ******


Example
-------
' Visual Basic Numeric format
' ---------------------------
Sub NumField_GotFocus ()
j% = vxCtlFormat(vxFieldSize("numfield"), VX_NUM, 2)
End Sub

// C Example
// ---------

// initialization routine
// **********************
case WM_INITDIALOG:

// format control
hwndDI = GetDlgItem(hdlg, IDD_TYPE);
SetFocus(hwndDI);
vxCtlFormat(3, VX_UPPER, 0);

// after formatting a series of controls (using the
// three code lines above as a template), remember
// to reset the focus to the FIRST control and
// return FALSE because the focus has been set
// ------------------------------------------------
return (FALSE);


See Also
--------
vxCtlLength
vxSetDate
vxWindowDereg


=====================================================================
vxCtlHwnd
=====================================================================

Declaration
-----------
Declare Function vxCtlHwnd Lib "vxbase.dll" (ControlName As Any) As Integer

Purpose
-------
Convert a Visual Basic control handle into a Window handle.

Parameters
----------
ControlName is the name of a Visual Basic control.

Returns
-------
An integer that contains the window handle of the control.

Usage
-----
Must be used to pass a window handle to vxCtlBrowse and vxCtlBrowseMsg
so they can do their duty. May also be used to access Windows API
calls that only work on window handles and not VB control handles.

Restriction
-----------
For Visual Basic users only.

Example
-------
Sub ButtonStrSearch_Click ()
SeekStr$ = InputBox$("Search string?", "Search For String", "")
If EmptyString(SeekStr$) Then
Exit Sub
End If
j& = vxCtlBrowseMsg(vxCtlHwnd(BrowseBox), VXB_SEARCHPRG, ByVal SeekStr$)
End Sub

See Also
--------
vxCtlBrowse
vxCtlBrowseMsg


=====================================================================
vxCtlPenWidth
=====================================================================

Declaration
-----------
Declare Sub vxCtlPenWidth lib "vxbase.dll" (ByVal PenWidth As Integer)

Purpose
-------
Control the depth of recessed or raised controls when using
vxCtlStyle.

Parameters
----------
Penwidth is either 1, 2, or 3. The default value is 2.

Returns
-------
Nothing.

Usage
-----
Primarily to make vxBase styled text boxes look the same as
other third party controls (e.g., 3dWidgets from Sheridan Software).

Example
-------
Call vxInit
Call vxCtlGraySet
Call vxCtlPenWidth(1)

See Also
--------
vxCtlStyle


=====================================================================
vxDbfCurrent
=====================================================================

Declaration
-----------
Declare Function vxDbfCurrent lib "vxbase.dll" () As Integer

Purpose
-------
Get the current database select area.

Parameters
----------
None.

Returns
-------
The current database select area (as reported by vxUseDbf or
vxUseDbfRO when the file was opened). If there is no current
select area active, FALSE (0) is returned.

Usage
-----
Can be used to ensure that the database select area you THINK is
active is really active when you are about to perform critical tasks
(such as vxZap() or even vxClose()).


Example
-------
If vxDbfCurrent() = MasterDbf Then
j% = vxClose()
End If


See Also
--------
vxAreaDbf
vxNtxCurent
vxSelectDbf
vxUseDbf
vxUseDbfRO


=====================================================================
vxErrorTest
=====================================================================

Declaration
-----------
Declare Function vxErrorTest Lib "vxbase.dll"
(ErrorStructure As vxErrorStruc) As Integer

Purpose
-------
Test if an error occurred in a vxBase function. This function
only works if vxSetErrorMethod is set to TRUE. vxSetErrorMethod
and vxErrorTest provide an alternate error handling procedure to
the standard vxBase error routine. If vxSetErrorMethod is FALSE,
vxBase errors are reported through an immediate run time message
box.

Parameters
----------
ErrorStructure is of type vxErrorStruc as defined in the
global module (see Example below).

Returns
-------
TRUE if an error occurred in the previous call to vxBase and FALSE if
no error occurred.

Usage
-----
Visual Basic 1.0 does not provide a method for a DLL to trigger a
Visual Basic Error. As a result, the standard ON ERROR method will not
work to trap errors found by a DLL. Visual Basic 2.0 WILL provide this
facility, at which time we will have another alternate error method to
choose from.

By using vxSetErrorMethod(TRUE) and vxErrorTest(vxError), the programmer
may trap errors and execute an error procedure instead of being caught in
a no win situation (such as a series of field extraction commands that
are issued to a non-selected database which results in a seemingly never-
ending sequence of the same error message box). If an error occurs within
a vxBase function, you may exit to a special vxBase error handling procedure
and, depending on the error reported, either END the program or continue by
returning to the statement following the vxErrorTest.

Errors that occur within high level vxBase functions (vxBrowse, vxMemoEdit,
vxCtlFormat) are NOT trappable with vxTestError. Errors that occur in these
functions cannot be foreseen by the programmer (such as an invalid date entry
into a vxCtlFormat date text box) and must be dealt with at the user level.

The error structure defined as Global var vxError (as type vxErrorStruc)
has the following elements:

vxError.ErrorNum vxBase error number as listed in Appendix A
vxError.ErrorMsg vxBase error message as listed in Appendix A
or in the language selected with vxSetLanguage.
This is a FIXED string and must be RTRIMmed
before use.
vxError.DbfArea the currently selected dbf area (0 if none)
vxError.NtxArea the currently selected ntx area (0 if none)
vxError.DbfName the name of the current dbf (blank if none)
vxError.NtxName the name of the current ntx (blank if none)
vxError.BadParm an extra information field that contains
variable data depending on the type of
error that occurred. For example, if an
invalid field name is passed to vxBase, that
invalid field name will appear here. If there
is no extra info that would have any validity,
the element is blank. If the extra info is longer
than 80 characters (e.g., xbase expressions) it
is truncated on the right.

A call to vxErrorTest resets the internal vxBase error flag. Subsequent
calls to vxErrorTest when no error has occurred will always return FALSE.
Only the LAST error that occurred is available at any given time in vxError
unless you wish to save the returned error structure in different variables.

Example
-------
The error structure, function declaration, and global variable must
be defined in the global module as follows (and in the same order):

Type vxErrorStruc
ErrorNum As Integer
ErrorMsg As String * 80
DbfArea As Integer
NtxArea As Integer
DbfName As String * 80
NtxName As String * 80
BadParm As String * 80
End Type

Declare Function vxErrorTest Lib "vxbase.dll"
(ErrorStructure As vxErrorStruc) As Integer
' (above declaration on ONE line)

Global vxError As vxErrorStruc


' Trapping the error in the FORM code
' -----------------------------------
Call vxSetErrorMethod(TRUE)
jj% = vxUseNtx("\vb\vxbtest\testerr.ntx")
If vxErrorTest(vxError) Then
ProcessError
End If
Call vxSetErrorMethod(FALSE)


' processing the error in a General Procedure
' -------------------------------------------
Sub ProcessError ()

Select Case vxError.ErrorNum
' 620 File Open
Case 620
MsgBox "vxBase TEST: file open error"
END

' 944 Invalid Field Name
Case 944
MsgBox "Bad Field " + vxError.BadParm
END

Case Else
MsgBox vxError.ErrorMsg
End Select

' see Appendix A in the vxBase manual
' for a description of all errors

' identify what you feel are catastrophic
' errors (like a 620 error) and abort
' the program run entirely with an END
' statement

End Sub


See Also
--------
vxSetErrorMethod


=====================================================================
vxFieldTrim
=====================================================================

Declaration
-----------
Declare Function vxFieldTrim lib "vxbase.dll" (ByVal FieldName
As String) As String

Purpose
-------
Extract an xBase field, trim trailing spaces, and convert it to a
Visual Basic string.

Parameters
----------
FieldName is a valid field name from the currently selected
database. FieldName may be qualified with a valid alias name that points
to any open database.

Returns
-------
A Visual Basic String (or ASCIIZ string if vxSetString is 1) that contains
the contents of the defined field.

Usage
-----
Get the contents of a character type field and trim trailing spaces.
Trailing spaces should always be trimmed if the data is going into a text
box for editing. If you use this function, it is not necessary to use
the Visual Basic RTrim$ function to trim the string before placing it
into a text box.
Note that all xBase data is stored in character format, so you can use
this function to extract any field - including numeric, date, and logical

fields (and even a memo block reference if you wish). You could then use
Visual Basic data conversion functions to create the type of data you are
interested in.

NOTE: The maximum length of a field that can be extracted with vxFieldTrim
is 255. If a field is larger than this, use vxRecord to extract the
entire record contents into a defined record type or string.


Example
-------
BuyTypeDesc.Text = vxFieldTrim("b_desc")

See Also
--------
vxField
vxInteger
vxLong
vxRecord
vxReplRecord
vxReplString
vxSetAlias
vxSetString


=====================================================================
vxGetVersion
=====================================================================

Declaration
-----------
Declare Function vxGetVersion lib "vxbase.dll" () As String

Purpose
-------
Get a string containing the vxBase version number.

Parameters
----------
None.

Returns
-------
A Visual Basic String (or ASCIIZ string if vxSetString is 1) that contains
the current vxBase version number.

Usage
-----
It would be nice if you had a text box on your ABOUT form that displayed
this number to aid vxBase tech support.

Example
-------
VerBox.text = "vxBase Version " + vxGetVersion()


=====================================================================
vxLocate
=====================================================================

Declaration
-----------
Declare Function vxLocate lib "vxbase.dll" (ByVal XBaseExpr As String,
ByVal Direction As Integer) As Long

Purpose
-------
Searches for a record from and including the current record position
that satisfies a logical xBase expression.

Parameters
----------
XBaseExpr is a literal string or variable containing a valid xBase
expression. The expression must evaluate as .T. or .F..

Direction is an integer defined as a global constant in vxbase.txt.
VX_FORWARD (Value 0) tells vxLocate to search in a forward direction.
VX_BACKWARD (Value 1) skips backwards during the search.

Returns
-------
A long integer that contains the record number of the found record
OR zero (0) if the search expression was not satisfied.

If found, the record buffer contains the found record. If not found,
the record pointer is repositioned to the record that was active before
the search.

Usage
-----
Useful for searching a database for strings or values that are not
keyed.
vxLocate initiates the search from and including the current record
position. Use vxLocateAgain to restart the same search.

Example
-------
' We have a FIND button on a customer display form.
' When the button is clicked, we set up to solicit
' search parameters from the user and then load
' a modal form to gather the user input.
' -------------------------------------------------
Sub FindButton_Click ()
If RecChange = TRUE Then CustSave_Click

VXFORM3.Enabled = FALSE
CustReturn = 0
SaveRec& = vxRecNo() ' save where we are

j% = vxSelectDbf(vxClientDbf)
j% = vxSelectNtx(vxCl1Ntx) ' index on customer serial
j% = vxTop() ' start search from top

' display locate form as modal
VXFORM5.Show 1

' VXFORM5 will fill in a value in our standard
' Browse return var CustReturn
VXFORM3.Enabled = TRUE

' if rec wasn't found or user chose not
' to select a found rec then CustReturn will be zero
' --------------------------------------------------
If CustReturn = 0 Then
j% = vxGo(SaveRec&)
Exit Sub
Else
CustReturn = BROWSE_EDIT
CustDataLoad
VXFORM1.StatBar.text = "Edit record " + LTrim$(Str$(vxRecNo()))
VXFORM3.CustCompany.SetFocus
End If
End Sub

' -----------------------------------------------------------
' VXFORM5 is a modal form that solicits locate information
' from the user. It puts a value into global var CustReturn
' that we can interrogate when we return from vxform5.
'
' VXFORM5 has the following elements:
' 1. a group box with radio buttons for each field
' that we want the user to be able to search
' a. Option1 designates company name
' b. Option2 designates the client name
'
' 2. a text box (SearchBox) that accepts a string
' that we wish to locate
'
' 3. five buttons:
' a. ButtonStart initiates the search
' b. ButtonAgain looks for another FORWARD
' c. ButtonBack looks for another BACKWARD
' d. ButtonOK accepts the results and returns
' e. ButtonCancel cancels the operation and returns
'
' 4. two text boxes in which we will display the
' found data (CompanyBox and NameBox)
' ---------------------------------------------------------
Dim SearchStr As String ' global var to hold search string

' events below are in logical sequence
' (starting with Form_Load)
' ------------------------------------
Sub Form_Load ()
j% = vxSelectDbf(vxClientDbf)
Option1.Value = 1 ' set default to company

' disable buttons that shouldn't work
' until something has been found
ButtonAgain.Enabled = FALSE
ButtonBack.Enabled = FALSE
ButtonOK.Enabled = FALSE
End Sub

Sub Form_Paint ()
' register the database
j% = vxSelectDbf(vxClientDbf)

' make the form pretty
Call vxFormFrame(VXFORM5.hWnd)
Call vxCtlStyle(Frame1, VX_RAISE)
Call vxCtlStyle(SearchBox, VX_RECESS)
Call vxCtlStyle(CompanyBox, VX_RECESS)
Call vxCtlStyle(NameBox, VX_RECESS)
End Sub

Sub SearchBox_GotFocus ()
' user input convert to uppercase
j% = vxCtlFormat(40, VX_UPPER, 0)
End Sub

' when user clicks the button to initiate the search...
' -----------------------------------------------------
Sub ButtonStart_Click ()
' ensure we have something to search for
If SearchBox.Text = "" Then
MsgBox "Search string required"
Exit Sub
End If

' ensure a button has been selected
OpTotal% = Option1.Value + Option2.Value
If Not OpTotal% Then
MsgBox "Select a field"
Exit Sub
End If

' put single quotes around search string
SearchStr = "'" + RTrim$((SearchBox.Text)) + "'"

' construct xbase expression
If Option1.Value Then SearchStr = SearchStr + " $ upper(vxcompany)"
If Option2.Value Then SearchStr = SearchStr + " $ upper(vxname)"

j% = vxTop() ' always start search at top

' perform the search
CustReturn = vxLocate(SearchStr, VX_FORWARD)

' vxLocate return will be zero if nothing found
' ---------------------------------------------
If CustReturn = 0 Then
MsgBox "Search string not found"
CompanyBox.Text = ""
NameBox.Text = ""
ButtonAgain.Enabled = FALSE
ButtonBack.Enabled = FALSE
ButtonOK.Enabled = FALSE
Else
' if found show results in text box
CompanyBox.Text = vxField("vxcompany")
NameBox.Text = vxField("vxname")

' and enable buttons
ButtonAgain.Enabled = TRUE
ButtonBack.Enabled = TRUE
ButtonOK.Enabled = TRUE
End If
End Sub


' user can look for next occurence (FORWARD) by
' pressing ButtonAgain
' ----------------------------------------------
Sub ButtonAgain_Click ()
CustReturn = vxLocateAgain(VX_FORWARD)
If CustReturn = 0 Then
MsgBox "Search string not found"
CompanyBox.Text = ""
NameBox.Text = ""
ButtonAgain.Enabled = FALSE
ButtonBack.Enabled = FALSE
ButtonOK.Enabled = FALSE
Else
CompanyBox.Text = vxField("vxcompany")
NameBox.Text = vxField("vxname")
ButtonAgain.Enabled = TRUE
ButtonBack.Enabled = TRUE
ButtonOK.Enabled = TRUE
End If
End Sub

' user can look for previous occurence (BACKWARD)
' by pressing ButtonBack
' -----------------------------------------------
Sub ButtonBack_Click ()
CustReturn = vxLocateAgain(VX_BACKWARD)
If CustReturn = 0 Then
MsgBox "Search string not found"
CompanyBox.Text = ""
NameBox.Text = ""
ButtonAgain.Enabled = FALSE
ButtonBack.Enabled = FALSE
ButtonOK.Enabled = FALSE
Else
CompanyBox.Text = vxField("vxcompany")
NameBox.Text = vxField("vxname")
ButtonAgain.Enabled = TRUE
ButtonBack.Enabled = TRUE
ButtonOK.Enabled = TRUE
End If
End Sub

' user cancels search by pressing ButtonCancel
' --------------------------------------------
Sub ButtonCancel_Click ()
CustReturn = 0
Unload VXFORM5
End Sub

' user accepts result of search and sends
' new record number back to caller
' by pressing ButtonOK
' ---------------------------------------
Sub ButtonOK_Click ()
Unload VXFORM5
End Sub


' deregister window and ctlformat
' when unloading form
' -------------------------------
Sub Form_Unload (Cancel As Integer)
vxWindowDereg (VXFORM5.hWnd)
End Sub


See Also
--------
vxLocateAgain


=====================================================================
vxLocateAgain
=====================================================================

Declaration
-----------
Declare Function vxLocateAgain lib "vxbase.dll" (ByVal Direction As
Integer) As Long

Purpose
-------
Searches for a record from and NOT including the current record
position that satisfies a logical xBase expression previously
defined with vxLocateAgain.

Parameters
----------
Direction is an integer defined as a global constant in vxbase.txt.
VX_FORWARD (Value 0) tells vxLocateAgain to search in a forward direction.
VX_BACKWARD (Value 1) skips backwards during the search.

Returns
-------
A long integer that contains the record number of the found record
OR zero (0) if the search expression was not satisfied.

If found, the record buffer contains the found record. If not found,
the record pointer is repositioned to the record that was active before
the search.

Usage
-----
Used to continue a search that was initiated by vxLocate.

Example
-------
See example in vxLocate documentation.

See Also
--------
vxLocate


=====================================================================
vxNtxCurrent
=====================================================================

Declaration
-----------
Declare Function vxNtxCurrent lib "vxbase.dll" () As Integer

Purpose
-------
Get a the current index select area.

Parameters
----------
None.

Returns
-------
An integer pointing to the active index for the currently selected
dbf. This integer is the same one returned by vxUseNtx when the file
was opened.

FALSE (zero) is returned if there is no active index or if any other
error occurs (such as no current dbf selected).

Usage
-----
The programmer can let the user pick an active index from a list of
indexes. In this case, you never know exactly what index is the current
selection. If you have to find out, this is the function to use.

Example
-------
' put current index name in text box
' ----------------------------------
NtxNameBox.text = RTrim$(vxNtxName(vxNtxCurrent()))

See Also
--------
vxAreaNtx
vxNtxExpr
vxNtxName
vxSelectNtx
vxUseNtx


=====================================================================
vxNtxRecNo
=====================================================================

Declaration
-----------
Declare Function vxNtxRecNo lib "vxbase.dll" () As Long

Purpose
-------
Get the ordinal position of the current key in the active index for
the current dbf.

Parameters
----------
None.

Returns
-------
A long integer that describes the ordinal position of the current dbf
record in the active index. FALSE (zero) is returned if an error occurs.
If FALSE, the index pointer MAY be invalid. It is the programmer's
responsibility to trap the error and reposition if necessary.

Usage
-----
Primarily used to position a vertical scroll thumb when building a
scrollable list of dbf records. The physical position of the record in
the database probably bears little relation to its logical position in
the index.

NOTE: This number is calculated by moving through the btree in reverse
sequence from the current position until the first index entry is reached
(maintaining a count all the while). After the current position is
ascertained, the index pointer is moved back to the original position.
If the dbf file contains more than 5,000 records, or if the keys are
inordinately large, this function can consume a great deal of time.

Example
-------
j% = vxSelectDbf(TestDbf)
j% = vxGo(vxNumRecs()/2)

' display dbf record number
' and then ntx record number
debug.print vxRecNo()
debug.print vxNtxRecNo()


See Also
--------
vxRecNo


=====================================================================
vxPrinterDefault
=====================================================================

Declaration
-----------
Declare Function vxPrinterDefault lib "vxbase.dll" () As String

Purpose
-------
Retrieve the Windows default printer string in a format suitable
for setting the default printer with vxPrinterSelect.

Parameters
----------
None.

Returns
-------
A Visual Basic String (or ASCIIZ string if vxSetString is 1) that contains
a string that may be used by vxPrinterSelect to set the default Windows
printer.

The format of the string returned is
PRINTER NAME,DRIVER,PORT:

Usage
-----
Used to display the current default printer, and to re-set the default
printer if it is changed with vxPrinterSelect.

Example
-------
' display the default printer
' ---------------------------
PrinterBox.Text = vxPrinterDefault()

See Also
--------
vxPrinterEnum
vxPrinterSelect
vxSetupPrinter


=====================================================================
vxPrinterEnum
=====================================================================

Declaration
-----------
Declare Function vxPrinterEnum lib "vxbase.dll" (ByVal PIndex As Integer)
As String

Purpose
-------
Enumerate printers as defined in the WIN.INI file and retrieve a string
suitable for setting the default printer with vxPrinterSelect.

Parameters
----------
PIndex is an index number of the printer you wish to enumerate.

Returns
-------
A Visual Basic String (or ASCIIZ string if vxSetString is 1) that contains
a string that may be used by vxPrinterSelect to set the default Windows
printer.

The format of the string returned is
PRINTER NAME,DRIVER,PORT:

If a single space is returned, there are no more printers to be found.

Usage
-----
Would normally be used in a loop to enumerate the printers into a list
box so the user could select the printer he wished to make current.

Example
-------

' ----------------------------------------------------
' the following is taken from the sample app VYFORM1
'
' VYFORM1 contains:
' 1. a listbox named PrinterList
' 2. a button to set the default named SelectButton
' 3. an Exit button named ExitButton
' 4. a text box named PrinterBox to display the
' selected printer
' all of the code for VYFORM1 is shown below
' ----------------------------------------------------

' ------------------------------------
' unload form when exit button clicked
' ------------------------------------
Sub ExitButton_Click ()
Unload VYFORM1
End Sub

' ---------------------------------------
' when form is loaded, enumerate printers
' and put in list box
' ---------------------------------------
Sub Form_Load ()

' display the default printer
' ---------------------------
PrinterBox.Text = vxPrinterDefault()

j% = 1 ' the printer index
PrinterOk% = TRUE
Do
PrinterName$ = vxPrinterEnum(j%)

' all printers enumerated when vxPrinterEnum
' returns a single space
' ------------------------------------------
If PrinterName$ = " " Then
PrinterOk% = FALSE
Else
PrinterList.AddItem PrinterName$
j% = j% + 1
End If
Loop Until Not PrinterOk%
End Sub

' --------------------
' make the form pretty
' --------------------
Sub Form_Paint ()
Call vxFormFrame(VYFORM1.hWnd)
Call vxCtlStyle(PrinterBox, VX_RECESS)
Call vxCtlStyle(PrinterList, VX_RAISE)
End Sub

' ------------------------------------------
' if user resizes form, get rid of old frame
' ------------------------------------------
Sub Form_Resize ()
VYFORM1.Refresh
End Sub

' ----------------------------------
' if user double clicks a selection,
' emulate select button press
' ----------------------------------
Sub PrinterList_DblClick ()
SelectButton_Click
End Sub

' ----------------------------------
' if user selects a printer, display
' it in PrinterBox and also set the
' default printer
' -----------------------------------
Sub SelectButton_Click ()
PrinterBox.Text = PrinterList.Text

' change the default printer
' --------------------------
If vxPrinterSelect((PrinterBox.Text)) Then
MsgBox "Default printer changed!"
Else
MsgBox "Error in Printer Name"
End If
End Sub

See Also
--------
vxPrinterDefault
vxPrinterSelect
vxSetupPrinter


=====================================================================
vxPrinterSelect
=====================================================================

Declaration
-----------
Declare Function vxPrinterSelect lib "vxbase.dll" (ByVal PrinterName
As String) As Integer

Purpose
-------
Select a new Windows default printer.

Parameters
----------
PrinterName is a structured string used to set the default printer.

It is of the form
PRINTERNAME,DRIVERNAME,PORT:
For example,
EPSON LQ-500,EPSON24,LPT1:

A structured string that may be used to select a printer may be
obtained with function vxPrinterEnum.

Returns
-------
TRUE if a new printer has been correctly selected (or if the select
string matches the current default printer already). FALSE is returned
if the string does not match any printer that vxBase enumerates internally
from the [devices] section of the WIN.INI file.

Usage
-----
Allow the user to select a new printer without the need to bring up
the Windows Control Panel.
The printer select string would normally be obtained from the user
through a list box built with the vxPrinterEnum function.

Example
-------
See the example in vxPrinterEnum for a complete routine that lets the
user select a new printer.

See Also
--------
vxPrinterDefault
vxPrinterEnum
vxSetupPrinter


=====================================================================
vxReplDateString
=====================================================================

Declaration
-----------
Declare Sub vxReplDateString lib "vxbase.dll" (ByVal FieldName
As String, ByVal DateString As String)

Purpose
-------
Replace an xBase date field with a string formatted according to
country specific conventions. The default format is "mm/dd/yy"
(VX_AMERICAN).

Parameters
----------
FieldName is a valid date field name from the currently selected
database. FieldName may be qualified with a valid alias name that points
to any open database.

DateString is a string representation of a date in the format
defined by vxSetDate (default VX_AMERICAN mm/dd/yy). This is the same
date style used to control data entry with vxCtlFortmat and used by
vxDateString as a return value.

Returns
-------
Nothing. If the database, date, or field name is invalid, no replacement
occurs.

Usage
-----
Use to replace date fields that have been entered and verified under the
control of vxCtlFormat.

Example
-------
Sub Form_Load ()
MasterDbf = vxUseDbf("myfile.dbf")
vxSetAlias("master", MasterDbf)
vxSetDate(VX_AMERICAN)
DateBox.Text = vxDateString("datefld", VX_AMERICAN)
End Sub

Sub DateBox_GotFocus ()
j% = vxCtlFormat(8, VX_DATE, 0)
End Sub

Sub SaveButton_Click ()
Call vxReplDateString("datefld", (DateBox.Text))
j% = vxWrite()
j% = vxWriteHdr()
End Sub

See Also
--------
vxCtlFormat
vxDateFormat
vxDateString
vxDbfDate
vxReplDate
vxSetAlias
vxSetDate


=====================================================================
vxReplRecord
=====================================================================

Declaration
-----------
Declare Sub vxReplRecord lib "vxbase.dll" (RecStruct As Any)

Purpose
-------
Replace the contents of the internal vxBase record buffer for the
currently selected dbf with a Visual Basic record structure or string.

Parameters
----------
RecStruct is a defined record structure or a string containing
a complete database record.

Returns
-------
Nothing. If the current dbf is invalid, no replacement occurs.

Usage
-----
If using type definitions to describe records and to retrieve
their contents (with vxRecord), this function may be used to
replace the contents of the record buffer.
All xBase records are kept on disk as fixed length strings
containing ASCII data.

WARNING: No data validation of any kind is performed by vxReplRecord.
If using this function, all validation must be performed by the programmer
before the buffer is passed to vxReplRecord. Always remember that all
data is in ASCII format and that the first byte in an xBase record is
the deletion flag byte.

Example
-------
' Record defined in Global Module
' ----------------------------------------
' define types file record structure for
' use in vxform8 and the vxRecord and
' vxReplRecord functions
' ----------------------------------------
Type CatRec
cDelFlag As String * 1
Category As String * 3
CatName As String * 35
End Type
' note that every xbase record structure MUST begin
' with a single character deletion flag
' -------------------------------------------------

Sub ChangeDeleted ()
Dim Crec As CatRec

If vxDeleted() Then
If vxRecord(Crec) Then
CatBox.Text = Crec.Category
CatNameBox.Text = Crec.CatName

' we may also replace an entire
' record by pointing at a defined
' record or string containing the record
' --------------------------------------
Crec.Category = "zzz" ' if deleted, change key to hi values
Call vxReplRecord(Crec)
j% = vxWrite()
j% = vxWriteHdr()
StatBox.Text = "Key changed"
Else
CatBox.Text = ""
CatNameBox.Text = ""
EvalBox.Text = ""
End If
End If

End Sub

See Also
--------
vxField
vxFieldTrim
vxRecord


=====================================================================
vxSeekFast
=====================================================================

Declaration
-----------
Declare Function vxSeekFast Lib "vxbase.dll" (ByVal SearchKey As
String) As Integer

Purpose
-------
Perform significantly faster seeks in a known read-only environment.

Parameters
----------
SearchKey is a literal string or string variable that contains the
key value you are looking for.

Returns
-------
TRUE if the key was found and FALSE if not.

Usage
-----
Use to fill grids, arrays, etc. from a file that you are only going
to be reading. vxUseDbfRO MUST be used to open the database. If the
file is not opened with vxUseDbfRO, vxSeekFast always returns FALSE.
Should only be used in loops where no user interaction is involved.

WARNING!
vxSeekFast performs little error trapping. It is the programmer's
responsibility to know the database environment when using vxSeekFast.

The following internal vxBase checks are disabled when using vxSeekFast:
(1) current database selection is assumed to be correct.
(2) correct index is assumed to be selected and current.
(3) there is no checking for changed dbf or ntx buffers (therefore
if any changed buffers exist, they are not written and will
be LOST. Open the file cleanly as read only and perhaps Lock it
to stop any other users from updating it while it is in use).
(4) No locking on the index is performed while reading.
(5) filters are NOT respected.
(6) vxExact status is NOT respected.
(7) vxFound is NOT set.
(8) vxEof is NOT necessarily TRUE if a seek is unsuccessful (unlike
vxSeek).
(9) If a seek is NOT successful, the contents of the record buffer
are undefined.
(10) Relations set with vxSetRelations are NOT respected by vxSeekFast.
(11) File and record locks placed by other users are NOT respected.

Example
-------
' seek speed test
' ---------------
j% = vxUseDbfRO("\ab2\abacus\sam\cluser.dbf")
j% = vxUseNtx("\ab2\abacus\sam\cluser1.ntx")
j% = vxTop()
Key$ = "ABCDEFGHIJKLMNOPRSTUVWXYZ"
Debug.Print Time$

' following loop does 3000 seeks
For k% = 1 To 120
For m% = 1 To 25
ky$ = Mid$(Key$, m%, 1)
If Not vxSeekFast(ky$) Then
MsgBox "Seek failed"
End If
Next
Next
Debug.Print Time$
j% = vxCloseAll()

See Also
--------
vxDescend
vxSeek
vxSeekSoft
vxSetLocks


=====================================================================
xSetAlias
=====================================================================

Declaration
-----------
Declare Function vxSetAlias lib "vxbase.dll" (ByVal AliasName As String,
ByVal DbfArea As Integer) As Integer

Purpose
-------
Create an alias name for a dbf area in order to qualify field names used
in vxBase database functions. If a fieldname is qualified with an alias, the
database the alias refers to does not have to be the currently selected dbf.

Parameters
----------
AliasName is a string up to 8 characters long that is used as a field
qualifier.
DbfArea is the database select area returned by vxUseDbf when the file is
opened. This select area is automatically selected whenever a field name
that is qualified with an alias is passed to a vxBase function.

Returns
-------
TRUE if the alias name was set up in the array of alias names.
FALSE if the operation was not successful. FALSE is returned for the
following reasons:
(1) DbfArea does not refer to an open database.
(2) AliasName length is zero or greater than 8.
(3) AliasName has already been defined with a different DbfArea.
(4) Maximum number of alias names already defined (96 for all
concurrent vxBase tasks).

Usage
-----
It is recommended that all vxBase functions that take a field name
as a parameter use alias names to qualify the field. In a multitasking
(or multiwindow) environment, reference to a qualified field name will
ALWAYS ensure that the correct database is selected no matter what the
task or window.
Qualified field names allow the use of multiple databases in the
program without requiring a vxSelectDbf prior to accessing the fields
from a dbf that is already open.
Field qualifiers are essential if you use vxSetRelations to combine
two or more databases into one comprehensive table.

Alias names may be used with the following vxBase functions:
vxCharvxFieldSizevxReplDatevxSum
vxCtlLengthvxFieldTrimvxReplDateStringvxTrue
vxDateFormatvxFieldTypevxReplDouble
vxDateStringvxIintegervxReplInteger
vxDecimalsvxIsMemovxReplLogical
vxDoublevxLongvxReplLong
vxEmptyvxMemoEditvxReplMemo
vxFieldvxMemoReadvxReplString

Alias names are NOT used to define join expressions (in vxJoin)
or Browse columns with vxTableField. Browse columns that display
data joined with vxSetRelation are defined with vxTableFieldExt
(for Extended functionality) rather than vxTableField. In vxTableFieldExt
the columnar fields or expressions are qualified by passing the actual
dbf area to the function rather than by using an alias name. This allows
the use of xBase expressions when defining columns whose data resides
in the child files of a vxSetRelation.

xBase style alias names and alias names set with the vxSetAlias
function are supported within a vxBase xBase expression. The alias names
used must be set with vxSetAlias. File alias names are separated from
the field reference by "->" (classical xBase syntax) within an xBase
expression string. When alias names are used within vxBase functions
that refer to field names, a period delimiter is used instead (to
conform to Visual Basic syntax).
For example,
If Not vxEval("master->country = 'Canada'") Then
MsgBox "Country does not exist"
Else
Country$ = vxField("master.country")
End If

An alias name construct within a vxBase function is of the form
"Alias.FieldName". A period delimiter is used between the alias and
the field name.

Example
-------
Sub Form_Load ()
' vxSetRelations and vxSetAlias Example
' -------------------------------------
' We will skip through the Airbuyer file
' which has a many to one relationship with
' both the aircust.dbf file and the airtypes.dbf
' file.

' open child files first
AircustDbf = vxUseDbf("\vb\vxbtest\aircust.dbf")
Aircust1Ntx = vxUseNtx("\vb\vxbtest\aircust1.ntx")

AirtypesDbf = vxUseDbf("\vb\vxbtest\airtypes.dbf")
AirtypesNtx = vxUseNtx("\vb\vxbtest\airtypes.ntx")

' open parent file (has many records)
AirbuyerDbf = vxUseDbf("\vb\vxbtest\airbuyer.dbf")
Airbuy1Ntx = vxUseNtx("\vb\vxbtest\airbuy1.ntx")

' define alias names so we can use field
' qualifiers when extracting data
' --------------------------------------
j% = vxSetAlias("buyer", AirbuyerDbf)
j% = vxSetAlias("customer", AircustDbf)
j% = vxSetAlias("type", AirtypesDbf)

' define relationship to current selection
' the 1st param defines the file we are setting
' up the relationship to (the child file)
' and the second param tells vxbase how to
' construct a key to be used on the current
' index in use by the child file
' -----------------------------------------
ErrCode% = FALSE

' parent file must be the current selection
' when defining the relationship
If Not vxSetRelation(AircustDbf, "b_code") Then
MsgBox "1st relation failed"
ErrCode% = TRUE
Else
If Not vxSetRelation(AirtypesDbf, "b_cat") Then
MsgBox "2nd relation failed"
ErrCode% = TRUE
End If
End If

If ErrCode% Then
Unload VYFORM0
Else
' now when we issue vxTop(), the two related
' file pointers will move to match the values
' in the parent file key fields
j% = vxTop()
End If
VYForm0Display
End Sub

' display procedure uses alias names to extract
' data rather than selecting each database
' ---------------------------------------------
Sub VYForm0Display ()
If Not vxEof() Then
Bcode.text = vxField("buyer.b_code")
Bcat.text = vxField("buyer.b_cat")
Aname.text = vxField("customer.a_name")
Catname.text = vxField("type.catname")
Else
Bcode.text = ""
Bcat.text = ""
Aname.text = ""
Catname.text = ""
End If
End Sub

See Also
--------
vxSetRelation
and all the field functions listed above


=====================================================================
vxSetAnsi
=====================================================================

Declaration
-----------
Declare Sub vxSetAnsi lib "vxbase.dll" (ByVal OnOrOff As Integer)

Purpose
-------

vxSetAnsi(FALSE) properly handles databases that were created
with a DOS based application (such as Clipper). These databases
are OEM databases. Characters with diacritical marks in the
high end of the OEM character collating sequence are NOT the
same as the ANSI characters. It is necessary for vxBase to
translate the characters to ANSI (both Windows and vxBase
native mode) before they can be used in a vxBase application.
They also must be translated back again when they are written.

Parameters
----------
OnOrOff is either TRUE or FALSE. TRUE is the default value.

If TRUE, all data records and index entries are assumed to be in
the ANSI character set. No translation takes place.

If FALSE, data records are converted to ANSI from OEM after being read
from the file. All internal vxBase operations then take place on the
ANSI data. If a record is written, it is converted back to the OEM
character set before being written to disk.
If FALSE, index key entries are NOT converted to ANSI. Instead,
requests to seek result in the key being translated to OEM before the
seek takes place. Similarly, as the index is updated, keys are
translated back to OEM before insertion or updating.

All translation between character sets takes place in the background
and are transparent to the user.

Returns
-------
Nothing.

Usage
-----
vxSetAnsi would be set to FALSE if you were working with a database that
was created with a DOS based application and whose data contains characters
from the high end of the character table (i.e., those characters with
diacritical marks common to languages other than English).

It should also be set to FALSE if the database with the diacritical
characters is going to be used by DOS based applications (e.g., running
a Clipper program on a network concurrently with a vxBase program).

The default value of vxSetAnsi is TRUE (no translation takes place). If the
database was created and is maintained by vxBase (or DataWorks) and is only
going to be used by Windows applications, vxSetAnsi should be TRUE.

If using databases with different native character sets, vxSetAnsi may
be used to toggle translation on and off (as long as the current database
has no relations set up to databases with a different native character set).

THIS IS A SYSTEM WIDE FUNCTION THAT APPLIES TO ALL CONCURENT VXBASE TASKS!

Example
-------
Sub Form_Load ()
Call vxInit
Call vxCtlGraySet
Call vxCtlGraySet
Call vxSetLanguage(VX_GERMAN)
Call vxSetLocks(FALSE)
Call vxSetString(0)
j% = vxCloseAll()

' using OEM databases
' -------------------
Call vxSetAnsi(FALSE)

' create descending collating sequence table
' ------------------------------------------
i% = 255
For j% = 1 To 256
CharMap(j%) = i%
i% = i% - 1
Next j%
Call vxCollate(CharMap(1))

' turn off table usage until required
' -----------------------------------
Call vxSetCollate(FALSE)

End Sub

See Also
--------
vxCollate
vxSetCollate


=====================================================================
vxSetCollate
=====================================================================

Declaration
-----------
Declare Sub vxSetCollate lib "vxbase.dll" (ByVal OnOrOff As Integer)

Purpose
-------
Toggle the use of a defined collating sequence table.

Parameters
----------
OnOrOff is either TRUE or FALSE. When a collating sequence table is
defined with vxCollate, the value is set to TRUE (its default value
is FALSE).

Returns
-------
Nothing.

Usage
-----
Turn an alternate collating sequence table on or off. If no table has
been defined with vxCollate, this function has no effect.

You can build a special collating sequence table that only applies to
a given index and then turn that table on or off depending on whether the
index is in use or not.

THIS IS A SYSTEM WIDE FUNCTION THAT APPLIES TO ALL CONCURENT VXBASE TASKS!

Example
-------
Sub Form_Load ()
Call vxInit
Call vxCtlGraySet
Call vxCtlGraySet
Call vxSetLanguage(VX_GERMAN)
Call vxSetLocks(FALSE)
Call vxSetString(0)
j% = vxCloseAll()

' using OEM databases
' -------------------
Call vxSetAnsi(FALSE)

' create descending collating sequence table
' ------------------------------------------
i% = 255
For j% = 1 To 256
CharMap(j%) = i%
i% = i% - 1
Next j%
Call vxCollate(CharMap(1))



' turn off table usage until required
' -----------------------------------
Call vxSetCollate(FALSE)

End Sub

See Also
--------
vxCollate
vxSetAnsi


=====================================================================
vxSetErrorMethod
=====================================================================

Declaration
-----------
Declare Sub vxSetErrorMethod lib "vxbase.dll" (VBorVX As Integer)

Purpose
-------
Activate or deactivate the alternate vxBase error method.

Parameters
----------
VBorVX set to TRUE turns on the alternate error method. FALSE sets
the error reporting method to the vxBase default (run time errors are
reported via message boxes).
If VBorVX (the alternate error method) is TRUE, vxBase internal errors
MUST be trapped with vxErrorTest.

Returns
-------
Nothing.

Usage
-----
Note: This is a GLOBAL vxBase variable. If TRUE, all error reporting
will be set to the alternate method, and vice versa.

See vxErrorTest for details on using the alternate error method.

Example
-------
' test alternate error method
' ---------------------------
Call vxSetErrorMethod(TRUE)
jj% = vxUseNtx("\vb\vxbtest\testerr.ntx")
If vxErrorTest(vxError) Then
ProcessError
End If
Call vxSetErrorMethod(FALSE)


See Also
--------
vxErrorTest

=====================================================================
vxSetMeters
=====================================================================

Declaration
-----------
Declare Sub vxSetMeters lib "vxbase.dll" (ByVal OnOrOff As Integer)

Purpose
-------
Set analog meter bars on or off for vxReindex, vxPack, and vxTestNtx.

Parameters
----------
OnOrOff passed as TRUE will turn meter bars on, which allows the user
to gauge the progress of the functions listed above. TRUE is the default
value.
If OnOrOff is passed as FALSE, meter bars will NOT be displayed. It is
the programmer's responsibilty to display an hourglass or otherwise
inform the user that something is going on when one of the functions that
use meter bars is called with vxSetMeters(FALSE).

Returns
-------
Nothing.

Usage
-----
Use to stop meter bar windows from appearing - especially in very small
files. They come and go so quickly in small files that they may disconcert the
user (because they can't even be read).
This is a system wide setting that applies to all vxBase concurrent tasks.
If setting FALSE, it is good practice to set the value back to TRUE when the
operation is complete.

Example
-------
Call vxSetMeters(FALSE) ' set meter bar off
j% = vxAreaDbf("\vb\vxbtest\airtypes.dbf")
If j% > 0 Then
MsgBox "airtypes in use!"
Else
AirtypesDbf = vxUseDbf("\vb\vxbtest\airtypes.dbf")
AirtypesNtx = vxUseNtx("\vb\vxbtest\airtypes.ntx")
j% = vxPack(VXFORM1.hWnd)
j% = vxClose()
End If
Call vxSetMeters(TRUE) ' set meter bars back on

See Also
--------
vxPack
vxReindex
vxTestNtx


=====================================================================
vxSetRelation
=====================================================================

Declaration
-----------
Declare Function vxSetRelation Lib "vxbase.dll" (ByVal ToDbfArea
As Integer, ByVal KeyConstruct As String) As Integer

Purpose
-------
Define a relationship between a parent file and a child file
based on a key that may be constructed from parent data into
an index controlled by the child file.

Parameters
----------
ToDbfArea is the database select area of the child file returned
from vxUseDbf when the file was opened.
Note: to clear relations set up to child files without closing
the parent, ToDbfArea may be passed as a zero.

KeyConstruct is an xBase expression (which may be as simple as a
field name) that tells vxBase how to construct a key into the child
file index. The maximum length of the KeyConstruct string is 511
characters. KeyConstruct MUST evaluate as a character string.

Whenever a record pointer is moved in the parent file, a key into
the child file index is constructed and a seek is performed into the
child file. An exact match or a partial match moves the record pointer
in the child file. If the key is not found, the child file record
buffer is cleared, the record pointer is positioned to the last
record + 1, and vxEof() on the child returns TRUE.
If the child has any relations defined and there was no match,
all record buffers in the relational cascade will be cleared and
pointers moved as above.

If clearing a set of relationships (i.e., ToDbfArea is passed as
zero), pass this parameter as 0& (NULL long integer).

Returns
-------
TRUE if the relationship was properly set up. FALSE for any of the
following reasons:
(1) no database selected
(2) ToDbfArea is the current selection
(3) there are already 8 relations set up for this file
(4) ToDbfArea is not open
(5) not enough memory
(6) unable to evaluate KeyConstruct
(7) KeyConstruct does not evaluate as a character string.

Numeric and date indexes are not supported by vxBase.
Indexes on numeric and date fields may be created
by using the xBase STR() and DTOS() functions to
convert numbers and dates to character strings. The
same functions may be used in KeyConstruct to build
keys into the child file.

Usage
-----
The parent file must have a many to one or one to one relationship
to the child file.

The parent file must be the current selection when vxSetRelation
is invoked.

The child file must be open and have an index selected.

Up to eight relations per select area may be defined. Cascading
relationships are supported; cyclical relations are not. You may not
relate a database either directly or indirectly to itself. vxBase
traps direct relationships. Indirect relationships are not trapped
and if defined will result in a system hang (an infinite loop
will be entered because the record reading routine is recursive).

Example
-------
Sub BuyBrowse_Click ()
' example of using vxSetRelation
' and vxTableFieldExt to produce
' a browse table with fields from
' multiple databases included on each row
' ---------------------------------------

' open child files first
AircustDbf = vxUseDbf("\vb\vxbtest\aircust.dbf")
Aircust1Ntx = vxUseNtx("\vb\vxbtest\aircust1.ntx")

AirtypesDbf = vxUseDbf("\vb\vxbtest\airtypes.dbf")
AirtypesNtx = vxUseNtx("\vb\vxbtest\airtypes.ntx")

' open parent file (has many records)
AirbuyerDbf = vxUseDbf("\vb\vxbtest\airbuyer.dbf")
Airbuy1Ntx = vxUseNtx("\vb\vxbtest\airbuy1.ntx")

' define alias names so we can use field
' qualifiers when extracting data
' --------------------------------------
j% = vxSetAlias("buyer", AirbuyerDbf)
j% = vxSetAlias("customer", AircustDbf)
j% = vxSetAlias("type", AirtypesDbf)

' define relationship to current selection
' the 1st param defines the file we setting
' up the relationship to (the child file)
' and the second param tells vxbase how to
' construct a key to be used on the current
' index in use on the child file
' -----------------------------------------
ErrCode% = FALSE
If Not vxSetRelation(AircustDbf, "b_code") Then
MsgBox "1st relation failed"
ErrCode% = TRUE
Else
If Not vxSetRelation(AirtypesDbf, "b_cat") Then
MsgBox "2nd relation failed"
ErrCode% = TRUE
End If
End If

If ErrCode% Then
j% = vxCloseAll()
Exit Sub
Else
' now when we issue vxTop(), the two related
' file pointers will move to match the values
' in the parent file key fields
j% = vxTop()
End If

' define the browse table with the extended
' vxTableFieldExt function
' ------------------------------------------
Call vxTableDeclare(VX_RED, ByVal 0&, ByVal 0&, 0, 1, 6)
Call vxTableFieldExt(1, "Cust", "b_code", VX_FIELD, 0, AirbuyerDbf)
Call vxTableFieldExt(2, "Name", "a_name", VX_FIELD, 0, AircustDbf)
Call vxTableFieldExt(3, "Cat", "b_cat", VX_FIELD, 0, AirbuyerDbf)
Call vxTableFieldExt(4, "Description", "catname", VX_FIELD, 0, AirtypesDbf)
Call vxTableFieldExt(5, "Low", "b_low", VX_FIELD, 0, AirbuyerDbf)
Call vxTableFieldExt(6, "High", "b_high", VX_FIELD, 0, AirbuyerDbf)

BuyerReturn = 0
BuyerRec = vxRecNo()

' Execute the browse routine (onscreen editor ON)
' -----------------------------------------------
Call vxBrowse(VXFORM1.hWnd, AirbuyerDbf, Airbuy1Ntx, TRUE, FALSE, FALSE,
BuyerRec, "Buyer Records", BuyerReturn)

j% = vxCloseAll()
End Sub

See Also
--------
vxSetAlias
vxTableFieldExt


=====================================================================
vxTableFieldExt
=====================================================================

Declaration
-----------
Declare Sub vxTableFieldExt Lib "vxbase.dll" (ByVal ColIndex As Integer,
ByVal ColHead As String, ByVal ColExpr As String,
ByVal ColType as Integer, ByVal ColWidth As Integer,
ByVal DbfArea As Integer)

Purpose
-------
Define the contents of table columns declared by vxTableDeclare for use
with vxBrowse. vxTableFieldExt provides the same functionality as
vxTableField and extended functionality with the addition of the
ColWidth and DbfArea parameters. vxTableFieldExt MUST be used if
defining a browse table that includes data from child files whose
relationship to the parent file has been defined by vxSetRelation.

Parameters
----------
Parameters ColIndex through ColType are as defined in the documentation
for vxTableField.

ColWidth allows the programmer to explicitly specify the width of a
vxBrowse column in number of characters. Passing a zero width results in
vxBrowse using the default calculated width. Numeric fields displayed with
the STR() xBase function use the length as defined in the STR() function
(i.e., specifying a width via the ColWidth parameter is the same as passing
a zero width - the default is used instead).
If the width passed through ColWidth is insufficient to display the
column header, ColWidth is again ignored.
Note that the data displayed in the column will NOT be truncated if the
column is not wide enough. This parameter is provided mainly for the
purpose of fine tuning your browse displays to match the type of data
being displayed.

DbfArea is the database select area returned from vxUseDbf when the file
is opened. This parameter may be the select area of the parent file or
of any child files defined as possessing a relationship to the parent
through vxSetRelation.

Returns
-------
Nothing.

Usage
-----
Must always be used if defining a browse table that contains relational
data.

Alias field qualifiers are NOT allowed in ColExpr. The expression or
field is instead qualified through the DbfArea parameter.

See the vxTableField documentation for a thorough discussion of usage.

Example
-------
' define the browse table with the extended
' vxTableFieldExt function
' ------------------------------------------
Call vxTableDeclare(VX_RED, ByVal 0&, ByVal 0&, 0, 1, 6)
Call vxTableFieldExt(1, "Cust", "b_code", VX_FIELD, 0, AirbuyerDbf)
Call vxTableFieldExt(2, "Name", "a_name", VX_FIELD, 0, AircustDbf)
Call vxTableFieldExt(3, "Cat", "b_cat", VX_FIELD, 0, AirbuyerDbf)
Call vxTableFieldExt(4, "Description", "catname", VX_FIELD, 0, AirtypesDbf)
Call vxTableFieldExt(5, "Low", "b_low", VX_FIELD, 0, AirbuyerDbf)
Call vxTableFieldExt(6, "High", "b_high", VX_FIELD, 0, AirbuyerDbf)

BuyerReturn = 0
BuyerRec = vxRecNo()

' Execute the browse routine (onscreen editor ON)
' -----------------------------------------------
Call vxBrowse(VXFORM1.hWnd, AirbuyerDbf, Airbuy1Ntx, TRUE, FALSE, FALSE,
BuyerRec, "Buyer Records", BuyerReturn)

j% = vxCloseAll()

See Also
--------
vxBrowse
vxJoin
vxTableDeclare
vxTableField
vxTableReset


Terry Orletsky
vxBase (512523 Alberta Ltd)
#200, 10310 - 176 Street
Edmonton, Alberta, Canada
T5S 1L3
Phone (403) 489-5994
Fax (403) 486-4335
BBS (403) 483-5687 2400 BAUD 8N1
Compuserve I.D. 70524,3723



 December 21, 2017  Add comments

Leave a Reply