Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : TOOLKI.ZIP
Filename : DOCS

Output of file : DOCS contained in archive : TOOLKI.ZIP
Hit zoom window!
Documentation for TOOLS.PRG
Brian Jepson
ALSO find files:
TOOLS.PRG - source code
TOOLS.FXP - FoxPro `compiled' code
REGISTER.FPT - memo fields for REGISTER


If you don't have FoxPro, this might not be of much use to you. If you're interested in what you see here, though, for a small price ($10), we could make available a demo oriented towards programmers which demonstrate the syntax and execution of these files. The price you are paying will cover our production costs as well as the cost of the FoxPro run-time package which will come with it.
This is strictly for programmers only. You will not enjoy this if you aren't a programmer. What's a programmer? You might be one. It's entirely possible. Maybe it's safe to say that you are one if you enjoy this.

The Oat Bran Challenge:
You will notice that some of the documentation mentions features that I would have liked to put in the program, but couldn't- for reasons of priority, mostly. If you feel up to it, add these features yourself. Feel free to fix bugs or add any features that you feel are appropriate. But for Gawd's sake, let me know of any changes you make so I can keep up with them! If you cannot contact us through COMPUSERVE (70020,760), do so at the following address or phone number:

Memorial Union Systems Office
50 Lower College Road
Kingston, RI 02881
(401) 792-4019

Here goes...
Parsing Functions:


FIRST(), BUTFIRST() and TAIL() perform similar functions. When is a list containing at least one member, FIRST() will return the first member of that list; BUTFIRST() will return all members but the first of that list; and TAIL() will return the last member of that list. The AT() and RAT() functions let us speedily locate the first and last space found in the list.
ITEM() requires two parameters. should be the name of a list, and should be the number of the list member you wish to obtain. ITEM() then returns that member. By performing a BUTFIRST() on the list, we cycle through the list for -1 iterations. At this point, we have a list which begins with the atom we wish to seek. Now, it's a matter of applying FIRST() to that list to get the desired atom.
ATOMS() returns the number of members in a list, where is a list. This operation performs BUTFIRST() over and over on the list and returns the number of BUTFIRST() it was able to perform before BUTFIRST() returned the empty set.

Other Functions:


DEPTH() permits you to determine the depth of a memory variable array, provided that it is organized such that non-empty array elements are low numbered and contiguous and that the empty elements are high numbered and contiguous. The name of the array is passed in and the size to which it was DIMENSIONed is passed in . DEPTH() then returns the number of elements which are not empty. The process is similar to ATOMS() in that DEPTH() cycles through the array until it finds an empty array element. This function is almost exclusively used by ODOMETER(). Since the array ODOMETER accesses is public, the jurisdiction of ODOMETER() can often be trampled upon using this function.


MILITARY() takes a string variable which conforms to a picture definition "99:99XX" such as " 4:45pm", "10:30am" and returns a four-digit military or 24-hour format time. The conversion algorithm explains itself. Take a look at the source code!

Odometer functions:
Technical notes for this function are really beyond the scope of this documentation. Fortunately, the source code is quite well documented. So, READ IT!


: The name of an array.
: Row at which the odometer will be displayed.
: Column at which the odometer will be displayed.
: Maximum number of entries in the named array.
: Desired length of an array element.

This use of odometer sets up the odometer on the screen. An odometer is a method of allowing the input screen to modify large arrays without having to have the whole array on the screen. By rolling up or down through the array, the user can selectively modify array elements. The function call returns a numeric variable containing the handle number.


: Handle of odometer to roll.

Rolling up or down moves the odometer pointer and display to the next or previous element in the array. If an attempt is made to pass the maximum depth or lowest element, an alarm is sounded.


: Handle of odometer to add entry to.

Adds a new element to the array and allows the user to edit the element.


: Handle of odometer to create menu from.

All elements in the array are combined into a popup menu. This is useful for seeing all the elements at once and/or selecting one from the list. After an item is selected from the menu, the odometer pointer is updated to that element and the display is updated accordingly.


: Handle of odometer to edit.

Allows the user to edit whichever array element is currently displayed.


: Handle of odometer to close.

Closes the specified odometer and performs all necessary housekeeping tasks. It is IMPERATIVE that any opened odometer be closed.


: Handle of odometer to delete an element from.

Deletes the currently displayed element.


: Handle of the odometer to refresh.

In case anything has happened to the screen display, this command will redraw the odometer display.

ODOMETER() notes...

ODOMETER() uses work area I to open a database called odometer.

ODOMETER() procedures:

menu Processes request for a menu and makes it.
refreshHandle Processes request for a refresh and calls refreshOd.
setOd Processes setup request and sets up an odometer.
refreshOd Refreshes the current array element.
roll Processes requests to roll up or down.
edit Processes request to edit.
add Processes add request.
del Processes delete request.
close Closes odometer and deletes dbf entries.
fieldEdit Edits current array element.
fieldSay Puts current array element into odometer window.
getHandle Locates handle within the dbf and retrieves handle data.

Some other functions and procedures...

ALERT(, , , , , [])

: The icon form that the alert takes. May be one of the following:
"dialogue", "wait", "unhappy", "happy", or "question"

These icons are in TOOLS.PRG in a procedure called ikon. More may be added as the programmer sees fit. All that a programmer needs to do is add another case statement containing the necessary graphic description. At some point, icon data will be incorporated into the foxuser resource file.

: These are the three menu pads that accompany the alert box. If any of these are set to the value "null", they will not display. In this manner, the programmer can limit the number of menu bars which are used.

: The programmer may specify up to three lines of text which are part of the alert. These are displayed to the right of the icon and above the menu pads.

ALERT() creates a window on the screen. In the window is displayed an icon, up to three lines of communication to the end user, and up to three pads of a menu to allow a user choice. The menu choice is returned as an integer- 1, 2, or 3 depending on which pad was selected. The value returned corresponds to the position of the pad. So if the first one is null, and the second and third are defined, selecting the first pad visible to the end user(i.e. the second) returns a value of two.

response = ALERT("dialogue", "Continue", "null", "Cancel", "Action?")

The functioning of this is very straightforward. See the source code for details.

do EXPLODE with , , , , ,

: Starting x coordinate for window position.
: Starting y coordinate for window position.
: Ending x coordinate for window position.
: Ending y coordinate for window position.
: Ending height of window.
: Ending width of window.

The EXPLODE procedure creates an exploding box on the screen which begins as a very small window and increases until it has moved to the desired location and expanded to its desired size. Fancy, but not horribly useful as it is one more thing which the end user must sit tapping fingers for...

do TEDIT with

: List expression.

The list expression is composed of at least three atoms. The first is the NAME of a variable which is a string containing a title message. We will assume that there is a variable teditTitle, such that

teditTitle = "A tedit title message"

The second atom of the list expression should be either "center", "left", or "right". These refer to the justification within the window that the @...SAY/GET will take. Following this, the next atom should be the name of a variable containing a prompt string. Let's assume that there is a variable teditPrompt, such that

teditPrompt = "ì"

In the list expression, teditPrompt is followed by "|", the pipe symbol, and the NAME of the variable we wish to edit. Let's assume the name of that variable is "anyVariable" and that it is initialized to have a length of 5. This variable may already have a value, and it will appear in the @...SAY/GET. Following this, another pipe symbol should be inserted, followed by a picture string for the @...SAY/GET. TEDIT does not yet support picture strings containing spaces. This is due to the fact that the programmer has a lot more important stuff to deal with. Let's make the picture string "#,###".

If all this data were in a tedit command statement, it would look like this:

do TEDIT with "teditTitle center teditPrompt|anyVariable|#,###"

There may be any number of "teditPrompt|anyVariable|pictureString" clusters. This results in a vertical stacking of @...SAY/GETS. Theoretically, you can have as many of these as you want, but they might run off the bottom of the screen. TEDIT makes heavy use of macro substitution within variables, but this doesn't seem to slow down the program as much as one would expect.


: Row at which to display the @...SAY/GET.
: Column at which to display the @...SAY/GET.

GETTIME(), with its subfunction TIMETEST, prompts for the user to input an am/pm format time, validating it through the above mentioned subfunction. This is just a basic @...SAY/GET routine, but one that could be used enough; it warrants being in my toolchest. MILITARY() is extemely nice in converting GETTIME() data to 24-hour format.

TICK(, , )

Variables which must predate TICK():


: Row at which popup is produced.
: Column at which popup is produced.
: String equal in length to number of elements in mPrompts.

mPrompts[] is an array containing the prompts which will appear on the popup menu. The popup items are designed in such a way that when one is selected, the popup is redefined to have a check mark before the item. When that item is again selected, the check mark is removed. Each character in corresponds to a prompt in mPrompts[], so the programmer can process responses to selections in this manner. TICK() returns the value of , so supposing a name "spizzleGorp" for , a function call for TICK() should look like this in order for it to be useful:

spizzleGorp = TICK(10, 12, spizzleGorp)

Otherwise, is not changed after the user makes a selection. TICK() is useful for processing selections in which more than one item may be desired by the user.

INRANGE(, , , )

: Starting and ending time of first range.
: Starting and ending time of second range.

Returns .T. if the two time ranges overlap. All times should be in 24-hour format. MILITARY() (see above) will translate am/pm format to 24-hour if needed. Merely performs a mammoth BETWEEN() operation on all concerned parties.


Needs global variable:

Brings forward a dialogue which lets the end user select from available printers. Unfortunately, there is no facility at this time for determining available printers, so the data must be hard-coded into the software. In order to detect available printers, some external command must be employed.


Defines menus and windows for use with CHOOSER.


Based upon the chosen printer, cycles through font and style options for the printer in question. Not fully developed. Look at it, see what YOU think...


On a NOVELL network, as neatly as possible creates a window containing the names of all users currently on the network. Even when I try to pipe data away from the screen, this stupid "Writing data to output file..." message is generated.


: Program title.

Flashy intro for program execution. EXPLODEs a window and puts the program title at the top of the screen.


Activates the system menu and performs action based on the selection. System information and "desk accessories" should be put here. Here's what's in it so far:

Opens a dbf called REGISTER, which contains information about who the Oat Bran Product is registered to, and some data about the program. Puts the about data on screen in a window.

Brings up the help window, what else?

See "do CHOOSER" above.

See "do USERLIST" above.

do SHRINK with , , , , ,

: Starting x coordinate for window position.
: Starting y coordinate for window position.
: Ending x coordinate for window position.
: Ending y coordinate for window position.
: Ending height of window.
: Ending width of window.

The opposite of EXPLODE (see above). Puts a bunch of shrinking windows on screen. Maybe we should have called it "IMPLODE."

do DIVQ with ,

: A block of text.
: Desired length for lines that the text is divided into.

There might be one program left which uses this. DIVQ divides a block of text into up to two lines, displaying them in the upper left corner of the active window or screen. Don't use it; it's not very reliable when it comes to big words. I abandoned it, and I'm phasing it out as quickly as I can get a round tuit.


Someday, we're going to make an Oat Bran Control Panel, and this will serve a useful function. Right now, it's called when the user clicks where they're not supposed to. It flashes black across the top of the screen, like that other computer does when the beep volume is turned off.

YO(, , , , )

: Icon form (see ALERT())
: Time in seconds that this message should stay on screen.
: First line of message text.
: Second line of message text.
: Third line of message text.

YO() puts an ALERT()-like window on the screen, but without user responses. It waits for seconds or until the user presses a key. A little better than using the WAIT command.

Card functions...
Take a look at the source code, try to understand it.

CARD("setup ")

: The name of a database which describes the card which the programmer wishes to have active.

This function call to card sets up the card on the screen. A card is a group of buttons. Buttons are similar to menus, except that they may be more easily deactivated, they are more flexibly defined, and double-clicks are more easily processed. The defining database contains the following fields:

ROW Row at which the button will be displayed.
COLUMN Column at which the button will be displayed.
BUTTON Name of the button to display

CARD() verifies that the specified database is indeed a valid one. It then goes on to display the buttons on the screen. Control is then returned to the calling program.

CARD("check [disabled]")

This call asks card to check the buttons onscreen for a click or a double-click. The value returned is the number of the button clicked. If it was a double-click, then the value returned is the number of the button clicked multiplied by -1. Double clicks may be ignored by employing the ABS() function. Including the "disabled" option will check even disabled buttons.

CARD("disable ")
CARD("enable ")

: Number of button to disable or enable.

Enables or disables a button for checking. Disabled buttons appear in gray.


Releases global variables initialized by CARD().


Refreshes the CARD() display. Useful when some external command has filled the screen with garbage. Useful even if one of the programmer's glitches has filled the screen with garbage. If you want to be sloppy, assign an on key label as such:

on key label alt+r x = CARD("refresh")

IF you want to be sloppy. The best thing to do is not to screw up the display in the first place. But sometimes, when ESCAPEing from a program, the screen turns into spaghetti. So go ahead; BE SLOPPY!


doCard Looks for the database, then calls checkDataBase.
checkDataBase Examines the chosen database to determine whether
or not it is a proper configuration database. Then
it calls prepare and refresh.
prepare Initializes button variables.
check Processes mouse clicks.
refresh (re)Draws the buttons.
disable Processes requests to disable.
enable Processes requests to enable.
flash Flashes a button after it's been clicked on.
sayAButton Determines which color to display a button in.


  3 Responses to “Category : Dbase (Clipper, FoxBase, etc) Languages Source Code
Archive   : TOOLKI.ZIP
Filename : DOCS

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: