Dec 102017
 
Clipr S87 programers' LIBrary w/pop-up applic.
File GRUMP.ZIP from The Programmer’s Corner in
Category Dbase Source Code
Clipr S87 programers’ LIBrary w/pop-up applic.
File Name File Size Zip Size Zip Type
FORM 1790 268 deflated
GRUMP.LIB 45056 17003 deflated
README 30682 9482 deflated

Download File GRUMP.ZIP Here

Contents of the README file


THE GRUMPFISH LIBRARY FOR CLIPPER* PROGRAMMERS
Copyright 1988 Greg Lief


Greetings, Clipper programmer! The Grumpfish Library contains a number
of high quality, extremely useful applications and functions that you
can integrate into your Clipper programs with an absolute minimum of
effort. In general, to use a Grumpfish application or function, you
merely use the command to call the function in your source code, then
link your application with GRUMP.LIB. Only the required code will be
included from the library file, thus eliminating unnecessary overhead.

IMPORTANT: The Grumpfish Library is written entirely in Clipper using
the Summer '87 version. If you are using an earlier version of
Clipper, some of the Grumpfish functions may not link properly because
they utilize some of the new Clipper functions. However, if you are a
registered Clipper owner and have not yet updated to Summer '87, what
are you waiting for? The speed advantages alone are worth it!


COPYRIGHT NOTICE

The Grumpfish Library is protected by U.S. Copyright law. Because of
its shareware status, you are allowed and encouraged to make copies to
give to other people. However, it may not be dissembled or resold
(either modified or unmodified) without the express written permission
of the author.


SHAREWARE REGISTRATION

1. BENEFITS

The Grumpfish Library for Clipper programmers is a "Shareware" product.
You are encouraged to freely distribute copies of the entire Grumpfish
Library package, which consists of either:

(1) the archived file (GRUMP.ARC), or

(2) the library file (GRUMP.LIB), two documentation files (README
and README.COM), and order form (FORM).

If you find the Grumpfish Library useful in your Clipper programming
endeavors, you are highly encouraged to buy a registered copy for the
reasons listed below.

There are two levels of registration, Landlubber and Captain, which
entitle you to the following great benefits:

LANDLUBBER ($30)

1. The most current version of the Grumpfish Library, with your
personal registration number on this screen.

2. Run-time royalty-free license. In other words, you will be free to
integrate any or all functions of the Grumpfish Library into your
own Clipper applications without having to pay any royalty or fee
for doing so.

3. Notification of future versions of the Grumpfish Library. I expect
to be releasing new versions at least every several months, which
will both add new features and update existing ones.

4. A $10 commission each time someone registers from one of your copies.

CAPTAIN ($60)

All Landlubber's benefits listed above, plus

5. The source code for all functions and applications in the Grumpfish
Library, written entirely in Clipper (Summer '87). The code is
well-documented, and is invaluable as a learning tool for beginning
and intermediate programmers. More advanced programmers will be
able to customize the applications and functions as desired.

Bear in mind, gentle programmer, that this does NOT entitle you to
re-sell Grumpfish functions in any other form! This would
constitute a serious violation of the U.S. copyright on this
program (see above for the full story).

2. HOW TO REGISTER

a. At the DOS prompt, type "COPY FORM PRN" to print the registration
form.

b. Mail the completed form (or a reasonable facsimile) with your
check for $30 or $60:

Greg Lief
P. O. Box 17761
Salem, Oregon 97305


STARTING OUT

For convenience's sake, copy GRUMP.LIB to the same subdirectory where
CLIPPER.LIB and EXTEND.LIB are located.


USING THE GRUMPFISH LIBRARY

To use any of the Grumpfish applications or functions, you must first
link in the Grumpfish library (GRUMP.LIB). In addition, you will need
to link in Clipper's Extend library (EXTEND.LIB), because all of the
Grumpfish functions make use of functions in this library.

The following are examples of what you would enter at the DOS prompt
for the three most commonly used linkers ( represents the
name of your main .obj file):

For PLINK86** linker: PLINK86 FI LIB GRUMP,EXTEND,CLIPPER

For the DOS*** linker: LINK ,,,GRUMP + EXTEND + CLIPPER

For Borland's TLINK****: TLINK ,,,GRUMP EXTEND CLIPPER

Note that if your libraries are not located in the same subdirectory
where linking is being performed, you will have to add the drive
and/or path to prevent the linker from choking!


POP-UP APPLICATIONS

1. CALCULATOR

a. Description and Usage:

This is a useful calculator that includes all the basic operators:
addition (+), subtraction (-), multiplication (*), and division (/).
But it also has some other goodies, including exponentation (^) and a
full-featured memory. Plus, whenever you press an operator ('+', '-',
'*', '/', or '^'), the previous number is shown above the display
window. This is handy for when you are processing a list of numbers
and forget where you were.

Active Keys:

'+' -- addition '-' -- subtraction

'*' -- multiplication '/' -- division

'^' -- exponentation 'C' -- clear current number

'E' -- clear entry (does not clear previously entered number in
pending operation)

'=' or Enter -- process operation Esc -- exit Calculator

b. Memory Functions:

To access memory functions, press "M", then one of the flashing
function keys. The function keys are:

'R' -- recall number stored in memory

'C' -- clear memory (reset to zero)

'+' -- add current number to number stored in memory

'-' -- subtract add current number from number stored in memory

'*' -- multiply number stored in memory by current number

'/' -- divide number stored in memory by current memory

The maximum value that can be stored in the calculator is
99,999,999,999.9999.

c. Using the Calculator in your Clipper application:

There are two ways that you can make use of the calculator. The first
method is to use the SET KEY command to establish a "hot-key" so that
the user can pop up the calculator anywhere within the program. The
following lines added at the top of your program configures the F9 key
to serve as the hot key for the pop-up calculator:

EXTERNAL popcalc && define external symbol for linker
calckey = -5 && hot key will be function key F6
SET KEY calckey TO popcalc

If you want to use a different key as the hot key, please refer to your
Clipper manual for a list of INKEY() values.

The second method is to call the calculator directly. The following is
a sample menu including the calculator as a menu option:

@ 05,05 PROMPT "Data Entry"
@ 06,05 PROMPT "Reports"
@ 07,05 PROMPT "Calculator"
@ 08,05 PROMPT "Exit to Operating System"
MENU TO selection

DO CASE
CASE selection = 1
DO dataentry
CASE selection = 2
DO reports
CASE selection = 3
DO popcalc
CASE selection = 4
QUIT
ENDCASE

Although the second method may appeal to some of you, I highly
recommend using SET KEY so as to permit the user access to the
calculator from anywhere within the program.


2. PHONE DIRECTORY

a. Description:

This application allows the user to maintain a phone database with
names, addresses, and phone numbers of business and personal contacts.
It utilizes two files, PHONE.DBF and PHONE.NTX. You do not need to
create these files; the application automatically generates them if it
cannot find them in the specified subdirectory.

The user interface is a browse-style window (utilizing the Grumpfish
Browse function -- see below for more details). The user can view,
add, edit, and delete records from the phone database. You can
instruct the application to search a specific subdirectory for the
database file by initializing a memory variable named 'phonedir' with
the value of the desired directory (example: "C:\PHONE"). If
'phonedir' is not defined in your program, the current directory will
be used.

Active Keys:

A -- add a record to the database

E -- edit highlighted record

D -- delete highlighted record

Arrow keys -- scroll through the database

Esc -- exit the phone directory

F2 -- view/edit address information for the highlighted record

Pressing F2 allows the user to view and/or edit address information for
the highlighted person. A box containing that information will appear
in the middle of the screen. The user can enter information in these
fields as desired. They can then press Ctrl-W to save their edits, or
Esc to exit without saving. Either way, they will be returned to the
browse window.

b. Using the Phone Directory in your Clipper applications:

As with the calculator, there are two methods to choose from. The
first is to use SET KEY to establish a hot-key so that the user can pop
up the phone directory anywhere within the program. The following
lines added at the top of your program configures the F7 key to serve
as the hot key, and instructs the program to look for the phone
database in the subdirectory "C:\PHONE":

EXTERNAL popphone && define external symbol for linker
phonekey = -6 && hot key will be function key F7
phonedir = 'C:\PHONE' && search directory for phone.dbf
SET KEY phonekey TO popdate

If you want to use a different hot key for the phone directory, please
refer to your Clipper manual for a list of INKEY() values.

The second method is to call the phone directory directly. Refer to
the Calculator discussion for a sample menu. Once again, I highly
recommend using the SET KEY method.


3. CALENDAR

a. Description and Usage:

This is a pop-up calendar that displays the current month and the first
two weeks of the next month. The current day will blink. Press any
key to exit the calendar.

b. Using the Calendar in your Clipper applications:

As with the other applications, there are two ways to utilize the
calendar. The first is to use SET KEY to establish a hot-key so that
the user can pop up the calendar anywhere within the program. The
following lines added at the top of your program configures the F9 key
to serve as the hot key for the calendar:

EXTERNAL popdate && define external symbol for linker
datekey = -7 && hot key will be function key F8
SET KEY datekey TO popdate

If you want to use a different hot key for the calendar, please refer
to your Clipper manual for a list of INKEY() values.

The second method is to call the calendar directly. Refer to the
Calculator discussion for a sample menu. However, I recommend using
SET KEY.


4. MASTERMIND*****

a. Description and Usage:

Mastermind is a diversion when the user's brain needs a good workout!
It is based on the logic board game by Pressman Corporation.

The computer selects four colored pegs and arranges them in a specific
sequence. The player's objective is to determine both the color and
position of the four pegs by making educated guesses and analyzing the
clues that the computer dispenses after each guess. These clues are:
one black marker for every peg that matches in both color and location;
and one white marker for every peg that is correct in color but not
location. An average game will take from eight to ten guesses. To
choose a color, the user moves the highlight bar to the desired color
and presses Enter. The user must choose colors from left to right. If
the user wants to quit in the middle of a game, they may do so by
pressing Esc instead of selecting a color. The program keeps track of
the guesses & clues on the right side of the screen so that the player
can refer back to them.

b. Using Mastermind in your Clipper applications:

As with the other applications, there are two ways to utilize
Mastermind. The first is to use SET KEY to establish a hot-key so that
the user can pop up Mastermind from anywhere within the program. The
following lines added at the top of your program configures the F10 key
to serve as the hot key for Mastermind:

EXTERNAL popmm && define external symbol for linker
mmkey = -8 && hot key will be function key F9
SET KEY mmkey TO popmm

If you want to use a different hot key for Mastermind, please refer to
your Clipper manual for a list of INKEY() values.

The second method is to call Mastermind directly. Refer to the
Calculator discussion for a sample menu. However, SET KEY is highly
recommended.


5. PUZZLE

a. Description and Usage:

Puzzle is the four by four square puzzle you had when you were a kid.
Fifteen of the squares are filled with the numbers 1-15, and it is up
to the player to arrange these in order like so:


1 2 3 4

5 6 7 8

9 10 11 12

13 14 15


To move, the player types in the number of the piece they wish to move.
The program will not allow them to cheat!

b. Using the Puzzle in your Clipper applications:

As with the other applications, there are two ways to utilize the
puzzle. The first is to use SET KEY to establish a hot-key so that
the user can pop it up from anywhere within the program. The
following lines added at the top of your program configures the F10 key
to serve as the hot key for the puzzle:

EXTERNAL poppuz && define external symbol for linker
puzkey = -9 && hot key will be F10
SET KEY puzkey TO poppuz

If you want to use a different hot key for the puzzle, please refer to
your Clipper manual for a list of INKEY() values.

The second method is to call the puzzle directly. Refer to the
Calculator discussion for a sample menu. However, SET KEY is highly
recommended.


6. HELP SCREENS

Context-specific pop-up help screens add enormous user-friendliness to
any program. With the Grumpfish Library, it is a breeze to create your
own. Simply add the following line of code at the top of your program:

EXTERNAL help && declare symbol for linker

Next, recompile and link your program, because the actual creation of
the help screens takes place interactively from within your program.
Then run the program.

You may create a help screen for any wait state. Wait state commands
include ACCEPT, INPUT, MENU TO, MEMOEDIT(), READ, and WAIT. When you
are at a wait state where you wish to have a help screen, press F1. If
this is the first time you have called the HELP function, the program
will take a few seconds to initialize the HELP database. Three files
will be created: HELP.dbf, HELP.dbt, and HELP.ntx. These files should
not be deleted!

Assuming that you have not already created a help screen for this
particular wait state, you will get a help screen with the message:

No help text defined...
Press F2 to create, any other key to return

Press F2 to create the help screen text, then type it in exactly as you
wish it to appear. Once you are satisfied with the text, press Ctrl-W
to save it. The next time you (or another user) presses F1 at this
point in the program, they will be treated to your help screen!

Suppose that you have created a help screen and decide later that you
wish to edit its text. There is a hidden function that will allow you
to do so. Press F1 to pop up the help screen, then press Alt-E (for
Edit). You are then free to edit it as you see fit. Press Ctrl-W to
save your edits. This function is hidden because of the probability
that most of your programs will be used by others, and we wouldn't want
to give them too much freedom, now would we?


7. USING MULTIPLE POP-UP APPLICATIONS

If you would like to integrate more than one of these pop-up
applications into your program, use the following code at the top of
your program:

EXTERNAL help,popcalc,popphone,popdate,popmm,poppuz
calckey = -5 && F6 = hot key for calculator
phonekey = -6 && F7 = hot key for phone directory
phonedir = 'C:\PHONE' && search directory for phone.dbf
datekey = -7 && F8 = hot key for calendar
mmkey = -8 && F9 = hot key for Mastermind
puzkey = -9 && F10= hot key for puzzle
SET KEY calckey TO popcalc
SET KEY phonekey TO popphone
SET KEY datekey TO popdate
SET KEY mmkey TO popmm
SET KEY puzkey TO poppuz



FUNCTIONS

1. YES_NO()

This function displays a box with your message in it, and pauses
program execution until the user presses either 'Y' or 'N'. It returns
a logical value: true if the user pressed 'Y', or false if the user
pressed 'N'. The syntax is:

YES_NO([,])

where and are the messages you wish to have
displayed. is optional.

Sample use of YES_NO:

kill_it = YES_NO('WARNING: Record will be deleted','Shall I continue')
IF kill_it
DELETE
SKIP -1
ENDIF

Note that the function automatically adds "? (Y/N)" to your last
message. For example, in the sample above, the following would be
displayed:

WARNING: Record will be deleted
Shall I continue? (Y/N)


2. ERR_MSG()

This function displays a box with your error message in it, along with
several choice beeps, and pauses program execution until the user
presses any key. It does not return a value. The syntax is:

ERR_MSG()

where is the message you wish to display (not too
insulting, please!).

Sample use of ERR_MSG:

SEEK mVAR
IF .not. found()
ERR_MSG('That record was not found')
ENDIF


3. CENTER()

You will probably make frequent use of this function. It centers
character strings, either on the screen or the printer, at the row you
specify. Syntax is:

CENTER(,)

where is the character string or expression to be centered,
and is a numeric expression representing the row on which to
center the string.

Sample usage of CENTER:

CENTER(0,'Wacky Widgets, Inc.')
CENTER(1,'Change Order Data Input Screen'


4. WAITON() and WAITOFF()

This function is useful to keep the user of your application apprised
of time-consuming operations, such as printing a report, instead of
letting them stare at a blank screen and wonder what (if anything) is
going on.

First, call WAITON(), which displays a box with your message in it.
The syntax is:

WAITON([])

where is the message you wish to display. Note that if you
do not pass a message, WAITON() will assume that you are about to print
a report and will display the message "Now printing... please wait".

When the operation is complete, use WAITOFF() to refresh the screen.
The syntax is:

WAITOFF()

This will restore the screen to its original state.

Sample usage of WAITON and WAITOFF:

USE Sales
WAITON('Rebuilding index files... please wait')
INDEX ON lname TO Customer
INDEX ON date TO Saledate
INDEX ON inv_code TO Item
WAITOFF()


5. EXBOX()

Exploding boxes add enormous pizzaz to your color applications. The
syntax is as follows:

EXBOX(,,,,,)

is an integer numeric representing the top row of the box.

is an integer numeric representing the leftmost column of the box.

is an integer numeric representing the bottom row of the box.

is an integer numeric representing the rightmost box column.

is an integer numeric between 1 and 5, and represents the
type of box desired. The choices are:

Box Type Box String Used

1
2
3
4
5 (no border)

The box string forms the box in the same fashion as with Clipper's
"@...BOX" command. The box is drawn using this string starting from
the left hand corner and proceeding clockwise. If you need more
information on this, please refer to your Clipper manual.

is an integer numeric between 1 and 100, and is used to delay
the 'explosion'. The larger the delay, the longer the box drawing
operation will take. I recommend using values between 1 and 10, but
you should experiment with this.

Sample usage:

EXBOX(11,28,13,51,2,5)
@ 12,30 SAY 'Enter your ID:'
@ 12,46 GET mID PICTURE 'XXXX'
READ

When using a monochrome monitor, an exploding box will not have any
noticeable effect.


6. SETFILT()

This function allows you to simulate SQL (structured query language)
by establishing a query condition (or filter) for selectively printing
or displaying records. The syntax is hardly complex:

SETFILT()

SETFILT() returns a logical value. The return value is true (.T.) if
there are records found in the current database matching your query
condition, false (.F.) if there are not.

SETFILT() will display all of the field names of the current database
file. First, you move the highlight bar to the desired field and
presses Enter to add it to the query condition. You then select the
desired operator (equal to, less than, greater than, less than or equal
to, greater than or equal to, not equal to), and then the desired value
for that field. [For subsequent additions to the query condition, you
will be asked to select a logical (Boolean) operator (AND/OR)]. Bear in
mind that AND has precedence over OR when evaluating the query
expression. For example:

DATE=CTOD('05/01/81') .and. COST=50.00 .or. ITEM='widget'

will display all records with either (1) a date of 05/01/81 and a cost
of 50.00, or (2) item 'widget'. If you need more clarificationon
logical (Boolean) operators, please refer to your Clipper manual for
enlightenment.

As you add items to the query condition, it will be updated on the
screen so you can keep track of where you are.

When you are finished establishing your query condition, press Esc to
return to the calling program.

Sample Usage:

USE Sales
IF setfilt()
DISPLAY ALL
SET FILTER TO
ENDIF
RETURN


7. MEMEDIT()

This permits easy editing of memo fields. The syntax is:

MEMEDIT(,[,,,][,])

is a character string representing the name of the memo field
to be edited.

Optional parameters , , , are all numeric expressions
representing the box coordinates (top, left, bottom, right,
respectively). Default box coordinates are 5,10,19,69.

Optional parameter is a character string to be centered at the
top of your box.

The active keys during MEMEDIT are exactly the same as those in the
Clipper function MEMOEDIT(). Please refer to your manual for more
specifics.

Sample Usage:

USE Letters
MEMEDIT('text',10,20,15,59,'<< Edit Letter >>')
RETURN


8. MENUH()

This function allows you to easily paint a horizontal light-bar menu
on the screen. The syntax is:

MENUH(,,,[,,)

is a numeric expression representing the row at which to display
the light-bar menu.

is a numeric expression representing the starting column for the
light-bar menu.

is a numeric representing the desired spacing between menu
entries.

is a character string containing all of the prompts for the
menu. These prompts must be separated by dollar signs.

Optional parameter is a character string containing any
desired messages corresponding to the prompts. Like the prompts, the
messages must be separated by dollar signs. NOTE: You must SET MESSAGE
in your program before calling MENUH(), or your messages will not be
displayed!

Optional parameter is a character string used to set the menu
color. If this parameter is not passed, white on black will be used
for the unselected options and inverse will be used for the light bar.

MENUH() returns a numeric value representing the selected menu option.
For example, if the user pressed 'D' in the sample below the return
value would be 1.

Sample usage:

sel=MENUH(23,5,4,'Data Entry$Reports$Previous Menu$','','+w/b,+w/n')
DO CASE
CASE sel = 1
DO data
CASE sel = 2
DO reports
OTHERWISE
RETURN
ENDCASE


9. MENUV()

This function will paint a vertical bounce-bar menu on the screen.
First, you must define an array containing the desired menu options
(and corresponding messages, if desired). If you wish to have
messages, you must separate the menu option from the message with a
dollar sign. Also, be sure to SET MESSAGE before calling MENUV().

The syntax for this function is:

MENUV([,,<box type>,<box color>,<title color>])<br /><br /> <array> is a character string representing the name of the array that<br /> contains the menu options.<br /><br /> Optional parameter <title> is a character string representing the menu<br /> title.<br /><br /> Optional parameter <box type> is an integer between 1 and 12<br /> corresponding to the type of box you wish to use. Box types 1-4 are<br /> listed below:<br /><br /> Box Type Box String Used<br /><br /> 1 <br /> 2 <br /> 3 <br /> 4 <br /><br /> Boxes 5-8 and 9-12 are identical to boxes 1-4, except that 5-8 will<br /> have an additional drop shadow (simulating a three-dimensional effect)<br /> and 9-12 will have two drop shadows for super-duper 3-D.<br /><br /> Optional parameter <box color> is a character string containing the<br /> color to use for the box. The default color is white on black for<br /> unselected options and inverse (black on white) for the bounce bar.<br /><br /> Optional parameter <title color> is a character string containing the<br /> color to use for the menu title. The default is white on black.<br /><br /> MENUV() returns a numeric value representing the selected menu option.<br /> For example, if the user pressed 'Q' in the sample below the return<br /> value would be 4.<br /><br /> Sample usage:<br /><br /> DECLARE mainmenu[4]<br /> mainmenu[1]='Maintain Data$Add and edit information'<br /> mainmenu[2]='Output Reports$Share your information'<br /> mainmenu[3]='Utilities$Select printer, reindex files'<br /> mainmenu[4]='Quit$Exit to DOS'<br /> sel=MENUV(mainmenu,'Main Menu',11,'+w/rb,+w/n','+w/b')<br /> DO CASE<br /> CASE sel = 1<br /> DO maintdata<br /> CASE sel = 2<br /> DO reports<br /> CASE sel = 3<br /> DO utility<br /> OTHERWISE<br /> RETURN<br /> ENDCASE<br /><br /><br />10. DATEST()<br /><br /> If you want to print an empty date field or expression in a report<br /> without printing the slashes (' / / '), use DATEST() instead of<br /> DTOC() like so:<br /><br /> DATEST(<date>)<br /><br /> where <date> is the date field or expression you wish to print.<br /><br /><br />FUTURE IMPROVEMENTS<br /><br />Word Processing/Notepad, Memo Editor, Label Printer, Printer Set-up String<br />Manager, Function Key Manager, Database File Manager, more UDFs --- and any<br />ideas that you might have and want to send me!<br /><br /> Greg Lief<br /> P. O. Box 17761<br /> Salem, Oregon 97305<br /><br />LEGAL NICETIES<br /><br />*CLIPPER is a registered trademark of Nantucket Corporation.<br /><br />**PLINK86 is a registered trademark of Phoenix Technologies.<br /><br />***DOS is a registered trademark of Microsoft Corporation.<br /><br />****TLINK (Turbo Link) is a registered trademark of Borland International.<br /><br />*****MASTERMIND is a registered trademark of Pressman Corporation.<br /></div></div><br><br> <div id='jp-relatedposts' class='jp-relatedposts' > <h3 class="jp-relatedposts-headline"><em>Related</em></h3> </div> </div><!--/entry --> </div><!-- .entry-container --> <footer class="post-footer postdata fix"> </footer><!-- .post-footer --> <div class='postdata line'> <span class='line-date'><span class='icon'> </span>December 10, 2017</span> <span class="comments"><span class="icon"> </span><a href="#respond">Add comments</a></span> </div> <section id="comments"> <div id="respond" class="comment-respond"> <h3 id="reply-title" class="comment-reply-title">Leave a Reply <small><a rel="nofollow" id="cancel-comment-reply-link" href="/list/DBASE/GRUMP.ZIP/INFO/#respond" style="display:none;">Cancel reply</a></small> </h3> <form id="commentform" class="comment-form"> <iframe title="Comment Form" src="https://jetpack.wordpress.com/jetpack-comment/?blogid=30175801&postid=6241&comment_registration=0&require_name_email=1&stc_enabled=1&stb_enabled=1&show_avatars=1&avatar_default=mystery&greeting=Leave+a+Reply&greeting_reply=Leave+a+Reply+to+%25s&color_scheme=light&lang=en_US&jetpack_version=6.8&show_cookie_consent=10&has_cookie_consent=0&sig=5c9c2eaea5190a9e4e157d59cbaa0c2ec3431735#parent=https%3A%2F%2Fwww.pcorner.com%2Flist%2FDBASE%2FGRUMP.ZIP%2FINFO%2F" style="width:100%; height: 430px; border:0;" name="jetpack_remote_comment" class="jetpack_remote_comment" id="jetpack_remote_comment" sandbox="allow-same-origin allow-top-navigation allow-scripts allow-forms allow-popups"></iframe> <!--[if !IE]><!--> <script> document.addEventListener('DOMContentLoaded', function () { var commentForms = document.getElementsByClassName('jetpack_remote_comment'); for (var i = 0; i < commentForms.length; i++) { commentForms[i].allowTransparency = false; commentForms[i].scrolling = 'no'; } }); </script> <!--<![endif]--> </form> </div> <input type="hidden" name="comment_parent" id="comment_parent" value="" /> </section> <!-- #comments --> </article><!--/post --> <nav class='post-nav fix'> <table> <tr> <td class='previous'><a href="https://www.pcorner.com/list/DBASE/RPT52.ZIP/INFO/" rel="prev"><span class="icon"> </span> DBASE – RPT52.ZIP</a></td> <td class='next'><a href="https://www.pcorner.com/list/DBASE/DB3SGEN.ZIP/INFO/" rel="next"><span class="icon"> </span> DBASE – DB3SGEN.ZIP</a></td> </tr> </table> </nav> </div><!-- content --> </div><!-- main col --> <div id='sidebar-shell-1' class='sidebar-shell sidebar-shell-right'> <div class="dbx-group right boxed warea" id="sidebar"> <!--widget start --><aside id="paypal_donations-2" class="dbx-box suf-widget widget_paypal_donations"><div class="dbx-content"><h3 class="dbx-handle plain">Donate</h3><p>Please help defray the cost of running this free service.</p> <!-- Begin PayPal Donations by https://www.tipsandtricks-hq.com/paypal-donations-widgets-plugin --> <form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <div class="paypal-donations"> <input type="hidden" name="cmd" value="_donations" /> <input type="hidden" name="bn" value="TipsandTricks_SP" /> <input type="hidden" name="business" value="gjsmith66@pcorner.com" /> <input type="hidden" name="rm" value="0" /> <input type="hidden" name="currency_code" value="USD" /> <input type="image" style="cursor: pointer;" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" name="submit" alt="PayPal - The safer, easier way to pay online." /> <img alt="" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1" /> </div> </form> <!-- End PayPal Donations --></div></aside><!--widget end --><!--widget start --><aside id="text-7" class="dbx-box suf-widget widget_text"><div class="dbx-content"> <div class="textwidget"><script type="text/javascript"> amzn_assoc_placement = "adunit0"; amzn_assoc_enable_interest_ads = "true"; amzn_assoc_tracking_id = "zca-20"; amzn_assoc_ad_mode = "auto"; amzn_assoc_ad_type = "smart"; amzn_assoc_marketplace = "amazon"; amzn_assoc_region = "US"; amzn_assoc_linkid = "ea8faac85a6c9ee94ab5174bccaeb487"; amzn_assoc_emphasize_categories = "13900871"; amzn_assoc_fallback_mode = {"type":"search","value":"DOS Windows"}; amzn_assoc_default_category = "All"; </script> <script src="//z-na.amazon-adsystem.com/widgets/onejs?MarketPlace=US"></script> <script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:inline-block;width:160px;height:600px" data-ad-client="ca-pub-8001169946558833" data-ad-slot="3404908173"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div></aside><!--widget end --></div><!--/sidebar --> </div> </div><!-- /container --> </div><!--/wrapper --> <footer> <div id='page-footer'> <div class='col-control'> <div id="cred"> <table> <tr> <td class="cred-left">© 2018 <a href='http://www.pcorner.com'>The Programmer's Corner</a> by Personalized Computer Systems </td> <td class="cred-center"><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script> <ins class="adsbygoogle" style="display:inline-block;width:728px;height:90px" data-ad-client="ca-pub-8001169946558833" data-ad-slot="6568049104"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </td> <td class="cred-right"></td> </tr> </table> </div> </div> </div> </footer> <!-- 95 queries, 11MB in 0.290 seconds. --> <!-- location footer --> <script type='text/javascript'> //<![CDATA[ jQuery(document).ready(function($) { $('html').MagicLiquidizerTable({ whichelement: 'table', breakpoint: '780', headerSelector: 'thead td, thead th, tr th', bodyRowSelector: 'tbody tr, tr', table: '1' }) }) //]]> </script> <!-- tracker added by Ultimate Google Analytics plugin v1.6.0: http://www.oratransplant.nl/uga --> <script type="text/javascript"> var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www."); document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E")); </script> <script type="text/javascript"> var pageTracker = _gat._getTracker("UA-10500370-7"); pageTracker._initData(); pageTracker._trackPageview(); </script> <div style="display:none"> </div> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/comment-reply.min.js?ver=4.9.9'></script> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/jquery/ui/core.min.js?ver=1.11.4'></script> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/jquery/ui/datepicker.min.js?ver=1.11.4'></script> <script type='text/javascript'> jQuery(document).ready(function(jQuery){jQuery.datepicker.setDefaults({"closeText":"Close","currentText":"Today","monthNames":["January","February","March","April","May","June","July","August","September","October","November","December"],"monthNamesShort":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"nextText":"Next","prevText":"Previous","dayNames":["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],"dayNamesShort":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],"dayNamesMin":["S","M","T","W","T","F","S"],"dateFormat":"MM d, yy","firstDay":1,"isRTL":false});}); </script> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/jquery/ui/widget.min.js?ver=1.11.4'></script> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/jquery/ui/progressbar.min.js?ver=1.11.4'></script> <script type='text/javascript' src='https://s0.wp.com/wp-content/js/devicepx-jetpack.js?ver=201851'></script> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/jquery/ui/mouse.min.js?ver=1.11.4'></script> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/jquery/ui/sortable.min.js?ver=1.11.4'></script> <script type='text/javascript' src='https://secure.gravatar.com/js/gprofiles.js?ver=2018Decaa'></script> <script type='text/javascript'> /* <![CDATA[ */ var WPGroHo = {"my_hash":""}; /* ]]> */ </script> <script type='text/javascript' src='https://www.pcorner.com/wp-content/plugins/jetpack/modules/wpgroho.js?ver=4.9.9'></script> <script type='text/javascript' src='https://www.pcorner.com/wp-content/plugins/jetpack/_inc/build/likes/queuehandler.min.js?ver=6.8'></script> <script type='text/javascript' src='https://www.pcorner.com/wp-includes/js/wp-embed.min.js?ver=4.9.9'></script> <script async="async" type='text/javascript' src='https://www.pcorner.com/wp-content/plugins/akismet/_inc/form.js?ver=4.1'></script> <!--[if IE]> <script type="text/javascript"> if ( 0 === window.location.hash.indexOf( '#comment-' ) ) { // window.location.reload() doesn't respect the Hash in IE window.location.hash = window.location.hash; } </script> <![endif]--> <script type="text/javascript"> (function () { var comm_par_el = document.getElementById( 'comment_parent' ), comm_par = ( comm_par_el && comm_par_el.value ) ? comm_par_el.value : '', frame = document.getElementById( 'jetpack_remote_comment' ), tellFrameNewParent; tellFrameNewParent = function () { if ( comm_par ) { frame.src = "https://jetpack.wordpress.com/jetpack-comment/?blogid=30175801&postid=6241&comment_registration=0&require_name_email=1&stc_enabled=1&stb_enabled=1&show_avatars=1&avatar_default=mystery&greeting=Leave+a+Reply&greeting_reply=Leave+a+Reply+to+%25s&color_scheme=light&lang=en_US&jetpack_version=6.8&show_cookie_consent=10&has_cookie_consent=0&sig=5c9c2eaea5190a9e4e157d59cbaa0c2ec3431735#parent=https%3A%2F%2Fwww.pcorner.com%2Flist%2FDBASE%2FGRUMP.ZIP%2FINFO%2F" + '&replytocom=' + parseInt( comm_par, 10 ).toString(); } else { frame.src = "https://jetpack.wordpress.com/jetpack-comment/?blogid=30175801&postid=6241&comment_registration=0&require_name_email=1&stc_enabled=1&stb_enabled=1&show_avatars=1&avatar_default=mystery&greeting=Leave+a+Reply&greeting_reply=Leave+a+Reply+to+%25s&color_scheme=light&lang=en_US&jetpack_version=6.8&show_cookie_consent=10&has_cookie_consent=0&sig=5c9c2eaea5190a9e4e157d59cbaa0c2ec3431735#parent=https%3A%2F%2Fwww.pcorner.com%2Flist%2FDBASE%2FGRUMP.ZIP%2FINFO%2F"; } }; if ( 'undefined' !== typeof addComment ) { addComment._Jetpack_moveForm = addComment.moveForm; addComment.moveForm = function ( commId, parentId, respondId, postId ) { var returnValue = addComment._Jetpack_moveForm( commId, parentId, respondId, postId ), cancelClick, cancel; if ( false === returnValue ) { cancel = document.getElementById( 'cancel-comment-reply-link' ); cancelClick = cancel.onclick; cancel.onclick = function () { var cancelReturn = cancelClick.call( this ); if ( false !== cancelReturn ) { return cancelReturn; } if ( ! comm_par ) { return cancelReturn; } comm_par = 0; tellFrameNewParent(); return cancelReturn; }; } if ( comm_par == parentId ) { return returnValue; } comm_par = parentId; tellFrameNewParent(); return returnValue; }; } // Do the post message bit after the dom has loaded. document.addEventListener( 'DOMContentLoaded', function () { var iframe_url = "https:\/\/jetpack.wordpress.com"; if ( window.postMessage ) { if ( document.addEventListener ) { window.addEventListener( 'message', function ( event ) { var origin = event.origin.replace( /^http:\/\//i, 'https://' ); if ( iframe_url.replace( /^http:\/\//i, 'https://' ) !== origin ) { return; } jQuery( frame ).height( event.data ); }); } else if ( document.attachEvent ) { window.attachEvent( 'message', function ( event ) { var origin = event.origin.replace( /^http:\/\//i, 'https://' ); if ( iframe_url.replace( /^http:\/\//i, 'https://' ) !== origin ) { return; } jQuery( frame ).height( event.data ); }); } } }) })(); </script> <script type='text/javascript' src='https://stats.wp.com/e-201851.js' async='async' defer='defer'></script> <script type='text/javascript'> _stq = window._stq || []; _stq.push([ 'view', {v:'ext',j:'1:6.8',blog:'30175801',post:'6241',tz:'0',srv:'www.pcorner.com'} ]); _stq.push([ 'clickTrackerInit', '30175801', '6241' ]); </script> </body> </html>