Question

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.

Était-ce utile?

La solution

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top