It's a bit tricky, but how do I record the amount of time a key was pressed? My objective is to record the keys I pressed and the amount of time I pressed those keys, then be able to programatically use that recording whenever I want.
-
You'll need to supply more info. Inside a form? system wide? inside a control? What resources you've researched this with. What code you've tried and where it failed. – tinstaafl Jun 16 '13 at 20:00
1 Answers
Your question is not too specific and thus there are many alternatives fitting there. If what you want is a rough introduction to the way in which this problem should be addressed, here you have some help:
Public Class Form1
Dim allStartTimes(50) As Date
Dim allElapsedTimes(50) As TimeSpan
Dim allKeys(50) As Keys
Dim curIndex As Integer = 0
Dim totKeys As Integer = 50
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Dim count As Integer = 0
Do
count = count + 1
If (e.KeyCode = allKeys(count)) Then
If (curIndex <> count) Then
If (curIndex > 0) Then
allElapsedTimes(curIndex) = Now.Subtract(allStartTimes(curIndex))
End If
allStartTimes(count) = Now
curIndex = count
Exit Do
End If
End If
Loop While (count < totKeys)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
allKeys(1) = Windows.Forms.Keys.A
allKeys(2) = Windows.Forms.Keys.B
'.....
End Sub
End Class
This code shows the basic algorithm and one alternative to get the keys: KeyDown/KeyUp events for a given object (in this case it is the main form; bear in mind that only works when the main form is selected). I haven't included the KeyUp part because of requiring some work to synchronise both events and to get it working properly (what you should be doing). This code does not store the time when the given key stops being pressed, but when a different one is pressed.
One alternative to events are hooks. They work everywhere (don't need to select a specific object) but also have their drawbacks. Here you have a working code:
Public Class Form1
Private Const WM_HOTKEY As Integer = &H312
Private Declare Function RegisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer, ByVal fsModifier As Integer, ByVal vk As Integer) As Integer
Private Declare Function UnregisterHotKey Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal id As Integer) As Boolean
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
RegisterHotKey(Me.Handle, 0, Nothing, Keys.A)
RegisterHotKey(Me.Handle, 0, Nothing, Keys.B)
'.....
End Sub
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
If (m.Msg = WM_HOTKEY AndAlso m.WParam = CType(0, IntPtr)) Then
If (m.LParam = CType(4259840, IntPtr)) Then
'A
ElseIf (m.LParam = CType(4325376, IntPtr)) Then
'B
End If
'.....
End If
MyBase.WndProc(m)
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
UnregisterHotKey(Me.Handle, 0)
End Sub
End Class
List of parameters for all the keys to run the hook above. The shown A & B integer values represent just a quick solution for illustrative purposes.
Even there are further alternatives like relying on WPF: an example of a C# implementation.
These are the basic ideas. If you want a proper and reliable code you would have to do some research and testing to account for all the possible eventualities.

- 1
- 1

- 12,354
- 4
- 26
- 37