当我尝试将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
答案 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