Clearing Keyboard Buffer

V

vbguy2008

Hi,

I am coding a Windows Form Application in VB.NET 2008. I would like
to clear the keyboard buffer or at least empty all outstanding key
presses queued up for my application at certain points in my program.

I looked at System.Console.Read, but that doesn't seems appropriate.
I also looked into EnableWindow Lib "user32". I ran into a problem
where I could disable the form, but was unable to enable the form.
The code is:

Private Declare Function EnableWindow Lib "user32" (ByVal hwnd As
Long, _
ByVal fenable As Long) As Long
Public Declare Function GetActiveWindow Lib "user32" () As
System.IntPtr

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As _ System.EventArgs) Handles Button1.Click
Dim hWnd As IntPtr = GetActiveWindow()
Call EnableWindow(hWnd, False)
Call EnableWindow(hWnd, True)
End Sub

The reason that I want to clear the keyboard buffer is that I am
handling keyboard input in the form's Key_Up event. In response to
certain events, I use the SoundPlayer's PlaySync command. While the
sound is playing, I don't want to respond to any additional key
presses. Currently, the user can press keys while the sound is
playing and after the sound is done playing Key_Up fires.

I tried searching the newsgroups and Google and could not find a good
solution. Perhaps I am using the wrong keywords.

I appreciate any advice you can offer.

Thanks!!

--Noah
 
H

Herfried K. Wagner [MVP]

The reason that I want to clear the keyboard buffer is that I am
handling keyboard input in the form's Key_Up event. In response to
certain events, I use the SoundPlayer's PlaySync command. While the
sound is playing, I don't want to respond to any additional key
presses. Currently, the user can press keys while the sound is
playing and after the sound is done playing Key_Up fires.

\\\
Me.Enabled = False
<Play sound>
Me.Enabled = True
///
 
V

vbguy2008

Thank you for the suggestion. I tried it out and when the form is
reenabled the Key_Up event still fires for each key that was pressed
while the sound played.

Me.Enabled = False
<Play sound> <Key #1 Pressed>
<Sound continues> <Key #2 Pressed>
Me.Enabled = True
Key_Up fires with Key #1
Key_Up fires with Key #2

I would like to ignore/flush/clear all the key presses made while the
sound plays.

--Noah
 
K

kimiraikkonen

You may use if not, here is demonstrated with "ALT" whatever you can
change whatsoever:

if not keys.alt = true then
'play sound
end if

Hope this helps.
 
A

Armin Zingler

Hi,

I am coding a Windows Form Application in VB.NET 2008. I would like
to clear the keyboard buffer or at least empty all outstanding key
presses queued up for my application at certain points in my
program.

I looked at System.Console.Read, but that doesn't seems appropriate.
I also looked into EnableWindow Lib "user32". I ran into a problem
where I could disable the form, but was unable to enable the form.
The code is:

Private Declare Function EnableWindow Lib "user32" (ByVal hwnd As
Long, _
ByVal fenable As Long) As Long

The line above is not VB.Net code (probably VB6). See Herfried's answer for
an easier solution.

I appreciate any advice you can offer.

My personal opinion: I wouldn't clear the keyboard buffer. Instead, I'd
disable the Form, play the sound in another thread, then enable the Form
after the sound has finished. This keeps the main (UI) thread responsive
and, due to the disabled Form, all key strokes go to nowhere.


Armin
 
V

vbguy2008

Armin and Herfried, I apologize if I am misunderstanding you. I
simplified down your suggestion to this. I have the Form's KeyPreview
property set to true and the following:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Me.Enabled = False
System.Threading.Thread.Sleep(3000) 'Gives me time to type
Me.Enabled = True
End Sub

Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As
System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
Debug.Print("Key Pressed")
End Sub

I click Button1 and then type 1234. After the three seconds expire,
KeyPress fires 4 times with the values 1,2,3, and 4.

Perhaps I am misunderstanding your solution.

--Noah
 
A

Armin Zingler

Armin and Herfried, I apologize if I am misunderstanding you. I
simplified down your suggestion to this. I have the Form's
KeyPreview property set to true and the following:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e
As System.EventArgs) Handles Button1.Click
Me.Enabled = False
System.Threading.Thread.Sleep(3000) 'Gives me time to type
Me.Enabled = True
End Sub

Private Sub Form1_KeyPress(ByVal sender As Object, ByVal e As
System.Windows.Forms.KeyPressEventArgs) Handles Me.KeyPress
Debug.Print("Key Pressed")
End Sub

I click Button1 and then type 1234. After the three seconds expire,
KeyPress fires 4 times with the values 1,2,3, and 4.

Perhaps I am misunderstanding your solution.

--Noah

You missed the point "play the sound in another thread". You did not create
another thread.


Armin
 
A

Armin Zingler

Armin Zingler said:
You missed the point "play the sound in another thread". You did not
create another thread.

Quick example:

Private Sub Button1_Click( _
ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles Button1.Click

Dim t As New Threading.Thread(AddressOf TStart)

Me.Enabled = False
t.Start()
End Sub

Private Sub Form1_KeyPress( _
ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyPressEventArgs) _
Handles Me.KeyPress

Debug.Print("Key Pressed")
End Sub

Sub TStart()
System.Threading.Thread.Sleep(3000) 'Gives me time to type
Me.BeginInvoke(New MethodInvoker(AddressOf Done))
End Sub

Sub Done()
Me.Enabled = True
End Sub




Armin
 
V

vbguy2008

Thanks! Your solution does work. However, the UI grey's out. Is
there a nice workaround for that? I can understand why VB, by
default, greys it out, but for this project I don't want the UI to
change when the music is played.

Thanks again for all your help,

--Noah
 
A

Armin Zingler

Thanks! Your solution does work. However, the UI grey's out. Is
there a nice workaround for that? I can understand why VB, by
default, greys it out, but for this project I don't want the UI to
change when the music is played.

I understand your concern, however, IMO, the user should see that he can't
do any input, so the visual (grey) feedback is sort of correct.

Yet, if you need it... Call API function PeekMessage after the music has
played. Pass PM_REMOVE for argument wRemoveMsg. You don't have to disable
the window then. I haven't tested it.



Armin
 
V

vbguy2008

Hi Armin,

Thank you again for all your help. I feel like I am very close to
solving the problem. However, I have the following code and am having
trouble determining the exit condition(s) for the flush function.

Public Structure Point
Public x As Integer
Public y As Integer
End Structure

Private Const PM_REMOVE = &H1

Public Declare Function PeekMessage Lib "user32" Alias
"PeekMessageA" (ByRef lpMsg As MSG, ByVal hwnd As IntPtr, ByVal
wMsgFilterMin As Integer, ByVal wMsgFilterMax As Integer, ByVal
wRemoveMsg As Integer) As Boolean

Public Structure MSG
Public hwnd As IntPtr
Public message As Integer
Public wParam As IntPtr
Public lparam As IntPtr
Public time As Integer
Public point As Point
End Structure

Public Sub Flush()
Dim msgToss As MSG
Do While PeekMessage(msgToss, Me.Handle, 0, 0, PM_REMOVE) =
True
Debug.Print(msgToss.message)
Loop
End Sub

I can call into flush sometimes and it returns properly (it flushes or
or two messages) . However, other times PeekMessage always returns
true and msgToss.message = 15 forever.

Perhaps I have miscoded the functions above. I am relatively new at
using VB.NET APIs so I greatly appreciate your help.

Thank you,

--Noah

P.S. I agree that graying out the UI would generally make sense.
However given the program's UI/structure, it would result in the form
flashing constantly at the end-user which would be headache inducing.
 
V

vbguy2008

Thanks everyone for your help...

Do While PeekMessage(msgToss, Me.Handle, WM_KEYFIRST, WM_KEYLAST,
PM_REMOVE) <> 0&
Loop

This works!

--Noah
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Top