Search code examples
multithreadingkeypresskeydown

VB.net Multithreaded keypresses


I have a working 3D object viewer in VB.net (I know that VB.net is not the best language to use for this but still)

So if I press the W key the box moves up. If I press the D key it moves to the right. But I wanna do the simultaneously. And to do so I figured that I could give each key its own thread.

So the is the code I wound upwith.

Dim thread1 As System.Threading.Thread
Dim thread2 As System.Threading.Thread

Private Sub MoveUp_Keydown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles GlControl1.KeyDown
    If e.KeyCode = Keys.W Then
        If NumericUpDown1.Value < 100 Then
            NumericUpDown1.Value = NumericUpDown1.Value + 1
            Me.Refresh()
        End If
    End If
End Sub

Private Sub MoveUp1_Keydown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles GlControl1.KeyDown
    If e.KeyCode = Keys.W Then
        thread1 = New System.Threading.Thread(AddressOf MoveUp_Keydown)
    End If
End Sub

But the error I am getting is

error BC30518: Overload resolution failed because no accessible 'New' can be called with these arguments

I have tried to google this but the problem is that nobody uses the threading for a keypress resulting in different solutions.

Thanks for any help


Solution

  • You can do it without a Timer, but still using the GetKeyState() API:

    Public Class Form1
    
        <Runtime.InteropServices.DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Unicode)> _
        Private Shared Function GetKeyState(ByVal nVirtKey As Integer) As Short
        End Function
    
        Private Sub Form1_KeyDown(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
            If IsKeyDown(Keys.W) Then
                If NumericUpDown1.Value < 100 Then
                    NumericUpDown1.Value = NumericUpDown1.Value + 1
                    Me.Refresh()
                End If
            End If
    
            If IsKeyDown(Keys.D) Then
                If NumericUpDown2.Value < 100 Then
                    NumericUpDown2.Value = NumericUpDown2.Value + 1
                    Me.Refresh()
                End If
            End If
    
            ' ...etc...
        End Sub
    
        Private Function IsKeyDown(ByVal key As Keys) As Boolean
            Return GetKeyState(key) < 0
        End Function
    
    End Class
    

    The KeyDown() event will fire when any key is being held down, and you simply check each key you're interested in with GetKeyState(). There is no need for multiple threads...and I'm not even sure how that would work with form events. I don't know what you wanted to do with the "D" key, so I just put in NumericUpDown2 so you could see each block can do a different thing. You might not want to call Me.Refresh until the very bottom of the KeyDown() event so it only gets called once.