如何正确地将ascii整数转换为相应的按键?

时间:2017-03-24 16:31:45

标签: vb.net ascii

当我尝试将ASCII整数转换为具有多个字符的键时,我总是得到不正确的结果。 A - > z / 0 - > 9正常工作,但任何具有多个字符的按键总是会产生不正确的结果,例如F1 - > F12 / Numlock 0 - > Numlock 9 / home key等。

示例,F3的ASCII代码为114,但当我将114转换为字符时,它始终会输出R而不是F3

这与我的尝试类似:

(在这个例子中似乎没用,但这并不是我将如何使用它)

Dim bind = "114" '(F3) depending on user input
Dim c As Char = bind 'Convert the ASCII integer(bind) to character(c)
TextBox1.text = c 'which in this case outputs as "r"

如何解决此问题,以便将114 / any other key that has more than one character输出为F3 / their correct value

修改,更新示例:

此代码适用于需要在应用程序外部工作的用户定义快捷方式,因此我使用GetAsyncKeyState来确定按下了哪个ASCII整数,然后使用该ASCII整数进行绑定,但我还需要将该整数转换为字符(在本例中为F3),以便用户知道哪个keybind当前处于活动状态。

    Do
        ExitLoop = False

        For i = 0 To 255
            result = 0
            result = GetAsyncKeyState(i)
            If result = -32767 Then

                Dim c As Char = Chr(i)      ' Convert ASCII integer to char.
                Bind1.Text = c
                Shortcut1 = i
                ExitLoop = True

            End If
        Next i

    Loop While ExitLoop = False

1 个答案:

答案 0 :(得分:1)

标题有点误导,因为它不是解决问题的正确方法。您有GetAsyncKeyState,它根据Virtual-Key Code告诉您索引传递的密钥的状态。返回的值告诉我们当前是否按下了该键。从MSDN页面,

  

如果设置了最高有效位,则键为关闭,如果设置了最低有效位,则在上一次调用GetAsyncKeyState之后按下该键。

由于返回值是UInt16,并且我们想要查看最高有效位是否为1,我们将And结果为0xFFFF(在VB中,& HFFFF)。

下面的程序将报告当前按下的所有键,并将它们放在一条消息中,并将该消息放在表单的标题栏中。创建一个新的WinForms项目,并粘贴此代码。您可能需要从设计器后面的代码中删除Dispose。函数GetVKeyPressed具有有限数量的受支持密钥,但您可以根据虚拟密钥代码页面创建所需的案例。

Public Class Form1
    Implements IDisposable

    Declare Function GetAsyncKeyState Lib "User32" (ByVal vKey As Integer) As UInt16

    Private timer As New System.Threading.Timer(AddressOf timerCallback, Nothing, -1, -1)

    Private Function GetVKeyPressed(vKey As Integer) As String
        ' see https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx
        Select Case vKey
            Case &H30 To &H39 ' 0 to 9
                Return Chr(vKey).ToString()
            Case &H41 To &H5A ' A to Z
                Return Chr(vKey).ToString()
            Case &H70 To &H87
                Return "F" & (vKey - &H70 + 1)
            Case &H1
                Return "LMB"
            Case &H2
                Return "RMB"
            Case Else
                Return "Key not supported yet!"
        End Select
    End Function

    Private Sub timerCallback(state As Object)
        Dim results As New Dictionary(Of Integer, UInt16)()
        For i = 0 To 255
            results.Add(i, GetAsyncKeyState(i))
        Next i
        Dim pressedKeys = String.Join(", ", results.
            Where(Function(kvp) kvp.Value And &HFFFF).
            Select(Function(kvp) GetVKeyPressed(kvp.Key)))
        Try
            Me.Invoke(Sub() Me.Text = pressedKeys)
        Catch ex As ObjectDisposedException
        End Try
        timer.Change(100, -1)
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
        timer.Change(100, -1)
    End Sub

    Private Sub Form1_FormClosed(sender As Object, e As FormClosedEventArgs) Handles Me.FormClosed
        timer.Change(-1, -1)
    End Sub

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
                timer.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

End Class