This article is reprinted from the October 1990 edition of
TechNotes/dBASE IV.  Due to the limitations of this media, certain
graphic elements such as screen shots, illustrations and some tables
have been omitted.  Where possible, reference to such items has been
deleted.  As a result, continuity may be compromised.  

TechNotes is a monthly publication from the Ashton-Tate Software
Support Center.  For subscription information, call 800-545-9364.

Get the Point()
Dan Madoni
It seems the more digging I do into the dBASE IV language, the more
convinced I become that it is practically limitless.  dBASE IV allows
a lot of room for creativity as well as functionality. 

From the creative side comes the idea that I am presenting in this
article.  It stems from a belief that the look and feel of an
interface is just as important as the functionality of the program. 
It involves the use of a mouse in dBASE IV and for the intermediate to
advanced programmer, it's surprisingly simple using the concepts of 
moving and tracking a mouse pointer on-screen via the use of a UDF
called Point(). 

Some Prerequisites

Allow me to recommend some extra software in order to get this to work
as conceived which would be used, of course,  in addition to your
existing mouse driver.

CPanel.com

This is a TSR that is needed to decrease the sensitivity of the
mouse.  If the mouse is too sensitive, you'll find it hard to
accurately position the mouse character on screen.   

If you have an alternative way to decrease the sensitivity of the
mouse, by all means use it, especially if it doesn't use great amounts
of RAM.  A problem with CPanel is that it takes up quite a bit of
memory and unless you follow the guidelines in the Batch Files section
below, there is a chance that dBASE IV will not operate with CPanel
invoked. 

NOTE

CPanel.com is found with the Microsoft Mouse software.   The name of
the utility that fine-tunes your particular mouse may be different. 

QM.com

This is a mouse definition file for QEdit, and is available on the
Ashton-Tate BBS.  Point() was designed around this definition.

Batch Files

Create the following two batch files for enabling and disabling the
above two TSRs.  In my experience, I have found the possibility of TSR
problems with dBASE IV to be greatly reduced if the TSRs are enabled
via SetMouse before entering dBASE IV and disabled with KilMouse
outside of dBASE IV after the application has been executed. 

SetMouse.bat

                QM OFF
                CPANEL OFF
                QM
                CPANEL
KilMouse.bat

                QM OFF
                CPANEL OFF

Sometime after CPANEL is loaded, decrease the sensitivity from the
default of 50 down to 10.  CPanel is activated by holding down the key
combination Ctrl-Alt while clicking the mouse.

Tracking the Mouse 

This is a function that is implemented after drawing a screen full of
icons to point to.  For example, say you have a  screen which displays
three boxes.  One box is labeled "ADD", one is labeled "CHANGE", and
the last is labeled "DELETE" as in the following code:

SET COLOR TO BG+/B
CLEAR
@ 5,5  TO 7,14
@ 5,16 TO 7,25
@ 5,27 TO 7,36
SET COLOR TO W+/B
@ 6,7  SAY "ADD"
@ 6,18 SAY "CHANGE"
@ 6,29 SAY "DELETE"
Now let's say you want to choose one of the above options by pointing
at it with a mouse.  Beneath the code shown above, you would add a
line like this:

USRPOS = POINT(8,1,20,40,"BLUE")

The parameters 8,1 and 20,40 are limits to the mouse movement.  In
other words, the mouse character hits an imaginary wall when it runs
into the limits set by these two sets of parameters.  "BLUE" means
that the mouse character is to appear against a blue background, (the
mouse character is always green.) 

Once the function is invoked, the mouse character will appear as an
arrowhead pointing in the direction it was last moved.  It is
navigated by using the mouse (assuming the TSRs mentioned above were
loaded,) or by using the arrow keys.  The function is deactivated
using Escape (Right Button), Enter(Left Button), or pressing the
spacebar (both buttons).  Point() returns one of the following: 

If Enter is pressed, a character string representing the position of
the mouse character at the time Enter is pressed, (that is " 913" if
the mouse  character was @ 9,13.)   If  Escape is pressed, the string
"ESCAPE" is returned.  If the spacebar is pressed,  the string "SPACE"
is returned.

Given the above example of coding, you would use the following CASE
routine to determine how to act on the mouse action: 

DO CASE
                CASE SUBSTR(usrpos,1,2) = " 8"
                        postest = VAL(SUBSTR(usrpos,3,2)
                        DO CASE
                                CASE postest >= 5 .And. postest <= 14 
                                        DO AddPrg       && an Add Records
Routine
                                CASE postest >= 16 .And. postest <= 25
                                        DO ChgPrg               && a Change
Record Routine
                                CASE postest >= 27 .And. postest <= 36
                                        DO DelPrg               && a Delete
Record Routine
                        ENDCASE
                CASE usrpos = "ESCAPE"
                        RETURN
                CASE usrpos = "SPACE"
                        DO PickList
ENDCASE

According to the CASE routine, if the mouse character is at row 8 and
the column position falls within the range of 5 and 14, then AddPrg is
to be executed since this range of positions on row 8 indicates that
the mouse was pointed at the ADD box.  The same is true for ChgPrg and
DelPrg for their respective positions. 

A procedure called PickList is executed if the user hits the spacebar
or clicks both buttons.  If the user presses the Escape key or clicks
the right button, the CASE routine RETURNs to the calling program.    

Some Nifty Ideas

The easiest way to use mouse support in an application with Point() is
the method described previously.  It is easy to use if you know ahead
of time what the value of the mouse position needs to be in order to
perform a certain procedure. 

I have come up with some neat tricks for using Point().  In one
application, I designed a two-column scrollable picklist.  The list
scrolls downward if the mouse position is at the bottom limit of the
list and upward if the mouse position is at the top position of the
list.  As the list scrolls, the value of each item and its position is
stored to an array.  Upon exiting Point() by pressing Enter, a CASE
routine is performed to test the value of the mouse position against
the array values to determine which value is being pointed to. 

In the same application, SET CLOCK is set ON and it appears in the
upper right-hand corner.  Point() is used to detect whether or not the
mouse character is pointed at the clock when the Enter key is
pressed.  If it is, the Date is displayed in a popup window in the
middle of the screen. 

Using Point() with the mouse TSRs and some creativity can really spice
up your interface in addition to making your application more
user-friendly.  I find it to be a nifty vehicle for tapping the power
of dBASE IV.  The function appears on the facing page. 

FUNCTION
Point                                                                 
                PARAMETERS
mlimita,mlimitb,mlimitc,mlimitd,mbkgd                               
                ampos =
mlimita                                                                
                bmpos =
mlimitb                                                                
                nowpoint =
16                                                                  
                mbkgd =
UPPER(mbkgd)                                                           
                
                DO
CASE                                                                        
                        CASE mbkgd =
'RED'                                                          
                                SET COLOR TO
G+/R                                                        
                        CASE mbkgd =
'BLUE'                                                         
                                SET COLOR TO
G+/B                                                        
                        CASE mbkgd =
'CYAN'                                                         
                                SET COLOR TO
G+/BG                                                       
                        CASE mbkgd =
'MAGENTA'                                                      
                                SET COLOR TO
G+/RB                                                       
                
OTHERWISE                                                                   
                                SET COLOR TO
G+/N                                                        
                ENDCASE                                                                        
                
                DO WHILE
.T.                                                                   
                        SAVE SCREEN TO
mousescr                                                     
                        @ ampos,bmpos SAY
CHR(nowpoint)                                             

                        mwaiting =
INKEY(0)                                                         
                        RESTORE SCREEN FROM
mousescr                                                
                        DO
CASE                                                                     
                                CASE mwaiting =
4                                                        
                                        nowpoint =
16                                                         
                                        bmpos = bmpos + 1
                                        bmpos = IIF(bmpos > mlimitd, bmpos -
1, bmpos)                                                     
                                CASE mwaiting =
19                                                       
                                        nowpoint =
17                                                         
                                        bmpos = bmpos - 1
                                        bmpos = IIF(bmpos < mlimitb, bmpos +
1,
bmpos)                                                                                
                                CASE mwaiting =
5                                                        
                                        nowpoint =
30                                                         
                                        ampos = ampos - 1
                                        ampos = IIF(ampos < mlimita, ampos +
1,
ampos)                                                                                                                                 
                                CASE mwaiting =
24                                                       
                                        nowpoint =
31                                                         
                                        ampos = ampos + 1
                                        ampos = IIF(ampos > mlimitc, ampos -
1,
ampos)                                                                                                                                     
                                CASE STR(mwaiting,3) $ "111 13 27
32"                                    
                                
EXIT                                                                  
                
ENDCASE                                                                     
                ENDDO                                                                          
                
                DO
CASE                                                                        
                        CASE mwaiting =
13                                                           
                                RETURN STR(ampos,2) +
STR(bmpos,2)                                       
                        CASE mwaiting =
27                                                           
                                RETURN
'ESCAPE'                                                          
                
OTHERWISE                                                                   
                                RETURN
'SPACE'                                                           
                ENDCASE
RETURN .T.              
