Hacker’s Guide to Visual FoxPro
An irreverent look at how Visual FoxPro really works. Tells you the inside scoop on every command, function, property, event and method of Visual FoxPro.
CHRSAW()
, INKEY()
, LASTKEY()
These functions are all concerned with the keyboard buffer. CHRSAW()
and INKEY()
let you check if there’s anything there, while LASTKEY()
tells you what used to be there.
lKeyPressed = CHRSAW( [ nSeconds ] )
nKeyValue = INKEY( [ nSeconds ] [ , ] [ cFlags ] )
Parameter |
Value |
Meaning |
nSeconds |
Numeric |
How long should we wait for a keystroke or click? |
cFlags |
"M" |
Pay attention to the left mouse button, too. |
"E" |
Expand keyboard macro and return a keystroke from it. |
|
"H" |
Hide the cursor while we wait. |
|
"S" |
Show the cursor while we wait. |
|
lKeyPressed |
.T. |
There's something in the keyboard buffer. |
.F. |
There's nothing in the keyboard buffer. |
|
nKeyValue |
0 |
There's nothing in the keyboard buffer. |
151 |
The user clicked the left mouse button. |
|
Other numbers |
The code for the key pressed by the user. See Help. |
CHRSAW()
and INKEY()
are two variations on the same theme. They look at the keyboard buffer, and wait for a specified length of time to see what happens. CHRSAW()
is the nonintrusive one—it just tells you whether any keystrokes appeared in the buffer in that time. INKEY()
actually grabs the first keystroke, clears it from the buffer and gives you a code for it. They both quit waiting as soon as they see a keystroke.
CHRSAW()
is handy when you want to know if the user did anything at all. Use INKEY()
if you want to know what the user did or if you need to eat a keystroke. (See the discussion of LASTKEY()
below for a work-around that uses INKEY()
to eat a keystroke.)
INKEY()
is also mouse-sensitive, if you want it to be. Before we had Visual FoxPro’s DblClick event, INKEY()
was an important part of detecting double-clicks. INKEY()
’s mouse-detecting parameter is a little unusual, as the syntax above shows. Either a timeout value or a character flag can be passed to the function. Only in the case of passing both is a comma required.
The “E” flag, added in VFP 5, makes it easier to deal with the possibility that the keystroke pressed is actually shorthand for something longer. If the keystroke in the buffer has a macro defined, including the “E” tells INKEY()
to return successive keys from the macro rather than just the original keystroke.
CHRSAW()
is sensitive to SET TYPEAHEAD
. If you turn off type-ahead, the function can’t see the incoming keystrokes.
With events like KeyPress, Click and DblClick around, we don’t expect to be using these functions much anymore.
IF NOT CHRSAW(5) && wait 5 seconds
WAIT WINDOW "C'mon, buddy, DO something!"
ENDIF
nCode = LASTKEY()
LASTKEY()
tells you the code for the key most recently processed. Beware—checking LASTKEY()
doesn’t change its value. The old value stays there until another keystroke is processed. If you’re checking LASTKEY()
for certain keystrokes to, say, terminate an activity, you’ll want to stuff it with a new value once you’ve checked it. (Use KEYBOARD and INKEY()
to stuff LASTKEY()
with any value you want.)
One place to use LASTKEY()
is in dealing with users bailing out. As in FoxPro 2.x, a Valid routine can’t look ahead to see what user action triggered the Valid. If the user clicks a Cancel button, we don’t usually want to validate the field he was on before that. In our apps, Cancel buttons have their Cancel Property
set to .T., so the user can press Esc or click on them. Clicking a button with its Cancel Property
set to .T. stuffs LASTKEY()
with 27 (just as if the user had actually pressed Esc). So the Valid routine can check for LASTKEY()
=27 and bail out. See the example.
* This is the beginning of a Valid method. It lets you bail
* out when the user chooses the Cancel button.
* We'll also stuff the keyboard with something innocuous so
* we don't trigger canceling of another Valid by accident.
IF LASTKEY()=27
KEYBOARD CHR(255)
=INKEY() && eat the character we just keyboarded
RETURN .T.
ENDIF
* now perform the actual validation
Cancel Property, Click, DblClick, KeyPreview, KeyPress, Set TypeAhead