フレームごとに計算をするゲームのプログラムなんかだと、イベント発生時以外にキーボードの状態を取得したいと思うでしょう。
そこで通常ならDirectInputを使うのでしょうが、あえて使わないで解決してみようと書いたコードがこれ。今回はVB2005です。
Imports System.Windows.Forms
Module KeysState
Dim keysState As New Dictionary(Of Keys, List(Of Boolean))
''' <summary>
''' 毎フレーム呼び出す
''' </summary>
Public Sub UpDate()
For Each key As Keys In keysState.Keys
keysState(key).RemoveAt(1)
keysState(key).Add(keysState(key)(0))
Next
End Sub
''' <summary>
''' キーが押し始められたかを取得
''' </summary>
''' <param name="key">押し始められたかどうかを取得するキー</param>
''' <returns>押し始められていたらTrue、押し始められていなければFalse</returns>
Public Function IsPush(ByVal key As Keys) As Boolean
Return keysState.ContainsKey(key) AndAlso Not keysState(key)(1) AndAlso keysState(key)(2)
End Function
''' <summary>
''' キーが押されているか取得
''' </summary>
''' <param name="key">押されているかどうかを取得するキー</param>
''' <returns>押されていたらTrue、押されていなければFalse</returns>
Public Function IsPress(ByVal key As Keys) As Boolean
Return keysState(key)(0)
End Function
''' <summary>
''' キーが離されたかを取得
''' </summary>
''' <param name="key">離されたかどうかを取得するキー</param>
''' <returns>離されたらTrue、離されていなければFalse</returns>
Public Function IsUp(ByVal key As Keys) As Boolean
Return keysState.ContainsKey(key) AndAlso keysState(key)(1) AndAlso Not keysState(key)(2)
End Function
''' <summary>
''' 対象のコントロールのKeyDownイベントハンドラに追加する
''' </summary>
Public Sub KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
If keysState.ContainsKey(e.KeyCode) Then
keysState(e.KeyCode)(0) = True
Else
keysState.Add(e.KeyCode, New List(Of Boolean)(New Boolean() {True, False, False}))
End If
End Sub
''' <summary>
''' 対象のコントロールのKeyUpイベントハンドラに追加する
''' </summary>
Public Sub KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs)
If keysState.ContainsKey(e.KeyCode) Then
keysState(e.KeyCode)(0) = False
Else
keysState.Add(e.KeyCode, New List(Of Boolean)(New Boolean() {False, False, False}))
End If
End Sub
End Module