In VB, I usually put my code for when keys are pressed in the KeyDown
and KeyUp
subs. However, I would prefer it if this code could be put in the Timer_Tick
.
So I implemented the method shown below in the code where the program creates a List (Of Keys)
upon starting, and then the KeyDown
and KeyUp
subs adds or removes the Keys
from the List
.
To debug, the program draws a string of all of the Keys
in the Paint
sub which is refreshed every frame.
This method of handling key presses works fine mostly, except for the following problems I've encountered:
keysPressed(i).ToString
doesn't draw ,
or any non-letter characters as I would expect it to. Instead, it draws Oemcomma
. Is there a way to fix this? (I know it's not important for now as it's just a debugging feature, but I would still like to know how to get around this for the future)
The modifier keys are a nuisance for me. After being pressed, the KeyUp
sub isn't called once released (I suspect this is because they modify themselves) and some keys aren't detected at all (like fn
).
In addition, if I were to press and hold A
, then press Shift
and then release A
, then KeyUp
for A
isn't called (as it has been modified) which means that Keys.A
is not removed from my list. I would like KeyUp
for A
to be called whether or not A
has been modified.
Is there a way to tell VB to ignore all modifier keys in the KeyDown
and KeyUp
subs? (here I mean ignore as in ignore all modifications, despite still being able to detect the modifier key being pressed)
When I press a load of buttons (over 10), then it seems that they are not all detected at once (only 6 or so appear in the list). Is there a way to avoid this bug, or is this a limitation of using VB?
In fact, occasionally, when I press a few more buttons whilst holding another one, the one I was holding seems to be 'cancelled out' by being removed from the list until I release. (There are quite a few bugs which appear when I press a lot of keys).
When I press multiple keys down at the same time, what exactly happens? Is KeyDown
called multiple times for each key, or is it actually possible for a KeyDown
to represent multiple keys? In which case, what exactly would happen in my program?
Public Class Form1
Dim keysPressed As New List(Of Keys)
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If Not keysPressed.Contains(e.KeyData) Then keysPressed.Add(e.KeyData)
If e.KeyData = Keys.Escape Then End
End Sub
Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
keysPressed.Remove(e.KeyData)
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles screenTimer.Tick
Refresh()
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
For i = 0 To keysPressed.Count - 1
e.Graphics.DrawString(keysPressed(i).ToString, New System.Drawing.Font("Arial", 10), Brushes.Black, 10 * i, 540)
Next
End Sub
End Class
No, code it yourself. It's great the way it is for your purposes functionality-wise, and debugging wise, I prefer it that way, so maybe you should take my advice and not fight it. Consider looking at a trace of all the keystrokes and seeing , mixed in with a bunch of otherwise sensible seeming key names. Imagine Ctrl+, and etc. (when making this code you really need to debug or console trace every event)
So rip apart the keydata by taking out the modifiers. There isn't a way to change the way the keydatas come to you. It's inconvenient for some purposes, but useful for some others.
It's your keyboard's fault. In general you can't press many keys at once. It has nothing to do with VB or .net
Precisely what you expect happens; one keydown can only represent one key. If you can even find a way to store information about more than one key inside the KeyEventArgs, then you're a magician
Despite not using winforms events, the code here does what you're attempting: https://github.com/TASVideos/BizHawk/tree/master/BizHawk.Client.EmuHawk/Input ; It receives key events in bunches, but processing them is more or less the same as if they came from winforms. But believe it or not, we actually have to go to effort to reconstruct the way winforms delivers them with the modifiers combined with the keystrokes (see point #2)--not because of compatibility with old winforms code, but because that's the way we prefer it.