How do I convert a keycode to a keychar in .NET?
9 Answers
I solved this using a library class from user32.dll. I would prefer a Framework class, but couldn't find one so this worked for me.
Imports System.Runtime.InteropServices Public Class KeyCodeToAscii <DllImport("User32.dll")> _ Public Shared Function ToAscii(ByVal uVirtKey As Integer, _ ByVal uScanCode As Integer, _ ByVal lpbKeyState As Byte(), _ ByVal lpChar As Byte(), _ ByVal uFlags As Integer) _ As Integer End Function <DllImport("User32.dll")> _ Public Shared Function GetKeyboardState(ByVal pbKeyState As Byte()) _ As Integer End Function Public Shared Function GetAsciiCharacter(ByVal uVirtKey As Integer) _ As Char Dim lpKeyState As Byte() = New Byte(255) {} GetKeyboardState(lpKeyState) Dim lpChar As Byte() = New Byte(1) {} If ToAscii(uVirtKey, 0, lpKeyState, lpChar, 0) = 1 Then Return Convert.ToChar((lpChar(0))) Else Return New Char() End If End Function End Class 1 Comment
I found this snippet to be rather helpful in detecting a keypress from the enter key:
Private Sub StartValue_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles StartValue.KeyPress If ChrW(13).ToString = e.KeyChar And StartValue.Text = "" Then StartValue.Text = "0" End If End Sub I found this to be a decent solution to having people trying to submit a null value in a textbox. This just forces a 0, but it uses the "detect enter being pressed" to run.
Comments
Try this:
Char.ConvertFromUtf32(e.KeyValue) 1 Comment
Convert.ToChar(Keys.Enter);
1 Comment
I can't seem to reply to DaveH, but if you do as he says, it works fine!
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Long) As Integer Public sub harry() For i = 1 to 255 If Chr(i) = Convert.ToChar(Keys.Enter) Then Label1.Text &= " [Enter] " ElseIf Chr(i) = Convert.ToChar(Keys.Delete) Then Label1.Text &= " [Delete] " End If Next i End Sub 1 Comment
In VBA or Vb6:
Accessing from a KeyPress on a Button or other element sending a KeyCode:
Private Sub Command1_KeyDown(KeyCode As Integer, Shift As Integer) Label1.Caption = """" & KeyCodeToUnicodeString(CLng(KeyCode)) & """" End Sub In a module copy this code:
Option Explicit 'VB6 Private Declare Function ToUnicode Lib "user32" (ByVal wVirtKey As Long, ByVal wScanCode As Long, lpKeyState As Byte, ByVal pwszBuff As String, ByVal cchBuff As Long, ByVal wFlags As Long) As Long Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long ''VBA '#If VBA7 And Win64 Then ' 'VBA7 And Win64 ' Private Declare PtrSafe Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long ' 'must be tested, maybe Long has to be replaced by Integer for 64 bit: ' Private Declare PtrSafe Function ToUnicode Lib "user32" (ByVal wVirtKey As Long, ByVal wScanCode As Long, lpKeyState As Byte, ByVal pwszBuff As String, ByVal cchBuff As Long, ByVal wFlags As Long) As Long '#Else ' 'VBA 32 bit ' Private Declare Function GetKeyboardState Lib "user32" (pbKeyState As Byte) As Long ' Private Declare Function ToUnicode Lib "user32" (ByVal wVirtKey As Long, ByVal wScanCode As Long, lpKeyState As Byte, ByVal pwszBuff As String, ByVal cchBuff As Long, ByVal wFlags As Long) As Long '#End If 'Returns the text of the KeyCode pressed depending of the Keyboard language 'Does not work on Win98 (returns "") but works well on winXP and onwards Public Function KeyCodeToUnicodeString(KeyCode As Long) As String On Error GoTo KeyCodeToUnicodeString_End Dim ret As Long Dim keyBoardState(0 To 255) As Byte Dim buffer As String * 256 ret = GetKeyboardState(keyBoardState(0)) Dim i As Long 'Special: This portion of code is important for the function to work properly after compilation. 'Why I do not know, but if removed, the next call to ret = ToUnicode will make a OutOfMemory Error 'because the keyBoardState array is not yet in a correct state. 'Tried Sleep or Byte b = keyBoardState(i) within the loop, 'but the only way to make it work properlyIN vb6 is coded here. 'If used in VBA, this part of code may be removed Dim s As String For i = 0 To 255 s = s & CStr(keyBoardState(i)) & "-" Next i 'end of special portion of code If ret <> 0 Then ret = ToUnicode(KeyCode, 0, keyBoardState(0), buffer, Len(buffer), 0) buffer = StrConv(buffer, vbFromUnicode) If ret <> 0 Then On Error Resume Next KeyCodeToUnicodeString = Left(buffer, InStr(buffer, vbNullChar) - 1) Else KeyCodeToUnicodeString = "" End If End If KeyCodeToUnicodeString_End: End Function 1 Comment
Here an example from my side :)
#region Just for fun :D private string _lastKeys = ""; private readonly Dictionary<string, string[]> _keyChecker = _ new Dictionary<string, string[]> { // Key code to press, msgbox header, msgbox text {"iddqd", new[] {"Cheater! :-)", "Godmode activated!"}}, {"idkfa", new[] {"Cheater! :-)", "All Weapons unlocked!"}}, {"aAa", new[] {"Testing", "Test!"}}, {"aaa", new[] {"function", "close"}} }; private void KeyChecker(KeyPressEventArgs e) { _lastKeys += e.KeyChar; foreach (var key in _keyChecker.Keys) if (_lastKeys.EndsWith(key)) if (_keyChecker[key][0] != "function") MessageBox.Show(_keyChecker[key][1], _keyChecker[key][0]); else KeyCheckerFunction(_keyChecker[key][1]); while (_lastKeys.Length > 100) _lastKeys = _lastKeys.Substring(1); } private void KeyCheckerFunction(string func) { switch (func) { case "close": Close(); break; } } private void FormMain_KeyPress(object sender, KeyPressEventArgs e) { KeyChecker(e); } #endregion Just for fun :D 1 Comment
String.fromCharCode(event.keyCode)