Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How to clear keyboard buffer?

1,267 views
Skip to first unread message

Scott Coffey

unread,
Sep 16, 2011, 10:06:01 AM9/16/11
to

Clipper 5.3/Blinker 7.0/Windows XP SP3

I'm having a problem with getting the keyboard buffer cleared.

The application uses the Blinker SWPRUNCMD feature to call an FTP
program that transmits data to a handheld device. Prior to calling
the FTP routine, the Clipper program throws up a screen asking the
user to place the device in the cradle. If the user forgets to do
this, the screen will be displayed for about 15 seconds before issuing
a communication failure message.

The problem is, users have a tendency to pound on the keyboard if
something doesn't happen right away. So pressing the enter key
multiple times will load up the keyboard buffer with the enter key
presses and the next "wait" command doesn't wait because it reads the
enter key that was pressed while the prior screen was displayed. So I
need to make sure the keyboard buffer is flushed before issuing the
'wait' command. I've tried several techniques... the most obvious
being 'clear typeahead', but nothing I've tried works. Here's the
portion of the code that's not working:

******************************************************************

clear screen
@ 1, 1 to 22, 78 DOUBLE
@ 10, 10 say 'You have received an update to the scanner.' color "R+"
@ 11, 10 say 'Please turn the scanner on and place it in the cradle.'
color "R+"
@ 12, 10 say 'Once it is in the cradle, press any key to continue.'
color "R+"
set console off
wait
set console on

swpruncmd( 'calls the FTP program' )

*
* Clear keyboard buffer in case user was pounding on the keyboard
*

clear typeahead

*
* Check for errors
*

if file( "C:\POS\DATA\badtrans.bad" ) = .t.
clear screen
@ 1, 1 to 22, 78 DOUBLE
@ 10, 10 say 'Communication error...'
@ 11, 10 say 'Check your connections.'
@ 13, 10 say 'Press any key to continue...'
set console off
wait
set console on
return
endif

******************************************************************

If the user presses the enter key more then once, the 'wait' doesn't
wait and the user never sees the error message.

I asked a similar question a couple of years ago. At that time,
Norman Perelson offered the following:

******************************************************************
Hi Scott,

The KEYBOARD command may be useful.

To clear the keyboard buffer of everything except the last key, use:

KEYBOARD CHR(LASTKEY())

And to clear the keyboard buffer completely, and set the LASTKEY()
status to a safe value, for example ".", use:

KEYBOARD "."
INKEY()
******************************************************************

but I couldn't find a variation of that suggestion that works.

So, how do I go about truly clearing the keyboard buffer?
--
ScottCoffey at Scott dash(-) Coffey dot net

Claudio Voskian

unread,
Sep 16, 2011, 3:47:56 PM9/16/11
to
Scott

Try this (don't know if it will work for you):

while inkey(0.01) # 0 // or inkey(), without delay
enddo

This will end when no keys exist in the keyboard buffer.

Regards,
-- ---
Lic. Claudio VOSKIAN
Phone/Fax: (+54 11) 4988-0114
Mobile: (+54 911) 4435-4789
Aol/Msn/Skype/Y!: cvoskian - icq#: 18122595

"Scott Coffey" escribió en el mensaje de
noticias:i2l6779itj98fceuu...@4ax.com...

frank van nuffel

unread,
Sep 18, 2011, 1:52:46 AM9/18/11
to
Hi Scott,

"Scott Coffey" schreef in bericht
news:i2l6779itj98fceuu...@4ax.com...
>
> Clipper 5.3/Blinker 7.0/Windows XP SP3
>
> I'm having a problem with getting the keyboard buffer cleared.
[snip]

> ******************************************************************
[snip]
> wait
> set console on
set typeahead to 0
>
> swpruncmd( 'calls the FTP program' )
>
> if file( "C:\POS\DATA\badtrans.bad" ) = .t.
> clear screen
> @ 1, 1 to 22, 78 DOUBLE
> @ 10, 10 say 'Communication error...'
> @ 11, 10 say 'Check your connections.'
> @ 13, 10 say 'Press any key to continue...'
set typeahead to 16
> set console off
> wait
> set console on
> return
> endif
>
> ******************************************************************

haven't tried so, and perhaps there's a way of getting the keyboardsize
before setting to 0, so as to restore that value instead of 16

pls let me know how it goes :-)

Best regards,

frank



Klas Engwall

unread,
Sep 18, 2011, 7:00:24 PM9/18/11
to
Hi Frank,

> haven't tried so, and perhaps there's a way of getting the keyboardsize
> before setting to 0, so as to restore that value instead of 16

It is not documented in the Norton Guide (5.2 or 5.3) but

#define _SET_TYPEAHEAD 14

exists in set.ch. In the entry for the SET TYPEAHEAD command the size is
documented as being minimum 16, but when I test it with

? set( _SET_TYPEAHEAD )

it prints 15. Interesting :-)

Regards,
Klas

Scott Coffey

unread,
Sep 20, 2011, 8:37:03 AM9/20/11
to
I tried both yours and Claudio's suggestions Frank and neither one
worked. Since I assumed that my original code *should* have worked,
and because your suggestions looked like they also should work, I
started looking at what might be going wrong here. I'll put the code
from my original post up again for reference. This time I'll also
include the actual code executed by the 'swpruncmd' command:

************************************************************************

clear screen
@ 1, 1 to 22, 78 DOUBLE
@ 10, 10 say 'You have received an update to the scanner.' color "R+"
@ 11, 10 say 'Please turn the scanner on and place it in the cradle.'
color "R+"
@ 12, 10 say 'Once it is in the cradle, press any key to continue.'
color "R+"
set console off
wait
set console on

swpruncmd( 'C:\PROGRA~1\IPSWITCH\WS_FTP~1\FTPSCRPT C:\POS\DLPGM.SCP' )

*
* Clear keyboard buffer in case user was pounding on the keyboard
*

clear typeahead

*
* Check for errors
*

if file( "C:\POS\DATA\badtrans.bad" ) = .t.
clear screen
@ 1, 1 to 22, 78 DOUBLE
@ 10, 10 say 'Communication error...'
@ 11, 10 say 'Check your connections.'
@ 13, 10 say 'Press any key to continue...'
set console off
wait
set console on
return
endif

***************************************************************************

The 'swpruncmd' command is calling a WS_FTP Pro batch script. So
while the "place the scanner in the cradle" message is displayed on
the screen (and while the user is theoretically pounding on the
keyboard) that application is running. My guess is that the WS_FTP
Pro application is possibly buffering the extra keystrokes and so when
Clipper tries to empty the keyboard buffer, it doesn't see anything to
empty, even though there are keystrokes buffered there.

I tried a couple of things and eventually stumbled onto something that
works. I added the following code just before the "clear typeahead"
instruction:

***************************************************************************

nCUTOFF = seconds() + 1
do while .t.
nELAPSED = seconds()
nREMAIN = nCUTOFF - nELAPSED
if nELAPSED > nCUTOFF
exit
endif
enddo

***************************************************************************

And now the "clear typeahead" works perfectly after the one second
wait. I have no idea why, and that pisses me off. :) If any Clipper
gurus out there could shed some light, I would be grateful.

Stephen Quinn

unread,
Sep 20, 2011, 9:02:11 AM9/20/11
to
Scott

> The 'swpruncmd' command is calling a WS_FTP Pro batch script. So
> while the "place the scanner in the cradle" message is displayed on
> the screen (and while the user is theoretically pounding on the
> keyboard) that application is running.

Then clearly your
> clear typeahead
is in the wrong position in the code.

Place it AFTER the swpruncmd()
ie when the FTP program ends and returns control back to your app.

IMO the DO WHILE inkey() loop posted in a previous message is a better
option

CYA
Steve


dlzc

unread,
Sep 20, 2011, 10:29:11 AM9/20/11
to
Dear Stephen Quinn:

On Sep 20, 6:02 am, "Stephen Quinn" <stevej...@bigpondSPAM.net.au>
wrote:
> Scott
>
> > The 'swpruncmd' command is calling a WS_FTP Pro
> > batch script.  So while the "place the scanner
> > in the cradle" message is displayed on the screen
> > (and while the user is theoretically pounding on
> > the keyboard) that application is running.
>
> Then clearly your
>     > clear typeahead
> is in the wrong position in the code.
>
> Place it AFTER the swpruncmd()
>     ie when the FTP program ends and returns control
> back to your app.

It is exactly there, as shown two times. Windoze does not push
keystrokes ignored by the other command interpreter session for some
time.

> IMO the DO WHILE inkey() loop posted in a previous
> message is a better option

It also did not work any better.

You should be able to duplicate this easily. Have one block of code
RUN another one. The other one is a 15 second timer, that ignores the
keyboard. When it runs, hammer the keyboard with lots of random
characters. Then when you return to the calling program, your
keystrokes show up some time later.

Scott, what OS+version is this occurring on?

David A. Smith

dlzc

unread,
Sep 20, 2011, 10:36:41 AM9/20/11
to
Dear Scott Coffey:

On Sep 20, 5:37 am, Scott Coffey <n...@noemail.com.invalid> wrote:
...


> And now the "clear typeahead" works perfectly
> after the one second wait.  I have no idea why,
> and that pisses me off.  :)

Let me offer that a similar loop...

FOR nLoop = 1 TO 10
if inkey(0.1) <> 0
EXIT
ENDIF
NEXT
CLEAR TYPEAHEAD

I'd just figure it was Windoze way of not losing data input to another
command session (just like it has its own environment, it will have
its own keyboard buffer), and figuring you needed it, and transfer of
the characters is a background task.

Is anything different if you RUN the program instead? (other than not
having optimizations to give the program enough memory.)

David A. Smith

Scott Coffey

unread,
Sep 20, 2011, 10:36:41 AM9/20/11
to

Hi Steve,

If you look at the original post, that's exactly where the 'clear
typeahead' was placed... as the next instruction following the
'swpruncmd' command. And it failed miserably.

Out of curiosity though, why do you prefer the inkey() loop over
'clear typeahead'? In my mind, 'clear typeahead' is the most obvious
and readable code, since what we're trying to achieve is to clear the
keyboard buffer.

frank van nuffel

unread,
Sep 20, 2011, 2:01:10 PM9/20/11
to
Scott, take a look at Tom Groeger's Clipper Internals Norton Guide

http://www.tomsoft.de/download/clipper/Internal.exe

There's a section about garbarge collection when using inkey()
Prbly it is related

Best regards,

Frank

"Scott Coffey" schreef in bericht
news:ja1h7750ljs3l83nq...@4ax.com...

> nCUTOFF = seconds() + 1
> do while .t.
> nELAPSED = seconds()
> nREMAIN = nCUTOFF - nELAPSED
> if nELAPSED > nCUTOFF
> exit
> endif
> enddo
>

Scott Coffey

unread,
Sep 20, 2011, 3:38:08 PM9/20/11
to
Hi David,

Check the first line of my initial post. :)

Scott Coffey

unread,
Sep 20, 2011, 3:40:52 PM9/20/11
to
On Tue, 20 Sep 2011 20:01:10 +0200, "frank van nuffel"
<_o_ceans(no_underscores)@telenet.be> wrote:

>Scott, take a look at Tom Groeger's Clipper Internals Norton Guide
>
>http://www.tomsoft.de/download/clipper/Internal.exe
>
>There's a section about garbarge collection when using inkey()
>Prbly it is related
>
>Best regards,
>
>Frank
>

I wasn't aware of that guide Frank. Thanks for link!

Scott Coffey

unread,
Sep 20, 2011, 3:58:56 PM9/20/11
to
No, the RUN command yields the same results.

Why do you suppose having a 1 second wait in the program magically
causes the 'clear typeahead' command to work? I understand what
you're saying about the keystrokes being saved from another "session",
(I had come to the same conclusion myself) but what I don't understand
is why adding the 1 second wait makes a difference.

dlzc

unread,
Sep 20, 2011, 4:35:45 PM9/20/11
to
Dear Scott Coffey:

On Sep 20, 12:58 pm, Scott Coffey <n...@noemail.com.invalid> wrote:
> On Tue, 20 Sep 2011 07:36:41 -0700 (PDT), dlzc <dl...@cox.net> wrote:
> >On Sep 20, 5:37 am, Scott Coffey <n...@noemail.com.invalid> wrote:
> >...
> >> And now the "clear typeahead" works perfectly
> >> after the one second wait. I have no idea why,
> >> and that pisses me off. :)
>
> >Let me offer that a similar loop...
>
> >FOR nLoop = 1 TO 10
> >   if inkey(0.1) <> 0
> >      EXIT
> >      ENDIF
> >   NEXT
> >CLEAR TYPEAHEAD
>
> >I'd just figure it was Windoze way of not losing data
> >input to another command session (just like it has its
> >own environment, it will have its own keyboard buffer),
> >and figuring you needed it, and transfer of the
> >characters is a background task.
>
> >Is anything different if you RUN the program instead?
> >(other than not having optimizations to give the
> >program enough memory.)
>
> No, the RUN command yields the same results.  

Well that is good news.

The child process may never open STDIN... If you run a batch file,
you may simply write a program that clears the keyboard, then
terminates...

> Why do you suppose having a 1 second wait

... is it fully 1 second, or is that "always" ... "long enough"?

> in the program magically causes the 'clear
> typeahead' command to work?  I understand what
> you're saying about the keystrokes being saved
> from another "session", (I had come to the same
> conclusion myself)

... I like the way you think.

> but what I don't understand is why adding the
> 1 second wait makes a difference.  

I figure it is garbage collection, a background task. The OS
"eventually" finds these keystrokes, and feels it has to put them
somewhere. I doubt it is "one second", but simply "sometime after
child process termination, and before the end of the world."

David A. Smith

Stephen Quinn

unread,
Sep 20, 2011, 7:05:15 PM9/20/11
to
Scott

> If you look at the original post, that's exactly where the 'clear
> typeahead' was placed... as the next instruction following the
> 'swpruncmd' command. And it failed miserably.

Apologies - I associated the blocks of code incorrectly.

Something else you might try is putting he command after the 'wait'
statements as well.
Nothing says you only have to use it in one location<g>

CYA
Steve


Scott Coffey

unread,
Sep 21, 2011, 7:41:14 AM9/21/11
to
On Tue, 20 Sep 2011 13:35:45 -0700 (PDT), dlzc <dl...@cox.net> wrote:


>
>I figure it is garbage collection, a background task. The OS
>"eventually" finds these keystrokes, and feels it has to put them
>somewhere. I doubt it is "one second", but simply "sometime after
>child process termination, and before the end of the world."

That makes as much sense as anything.

Since I'm programming for a condition that shouldn't be too common (a
failed communication session with a handheld device coupled with an
impatient user pounding on the keyboard) and my brief testing shows
that it works, I'm not going to lose any sleep over it.
0 new messages