Hey, I've been trying to implement Textbox-like input with TVInputEngine, and I made a class (actually it's the EventArgs of an event... but the context is too complex to just paste it all

). If this can help anyone... It's C# 2.0 code.
The constructor takes exactly what GetKeyBuffer returns, and the _text field contains all the buffered input in a string. The cool thing is that it takes capital letters and accents and symbols and everything, as long as it fits in a single keystroke!
Other scancode checks for all the arrows and the delete key could be added... But for me that did the trick. Maybe there's a better way to handle those than to put booleans...
Credits to Hypnotron for linking me to the GameDev article about the
ScancodeToASCII function...

/// <summary>
/// The information class for text handling (buffered input)
/// </summary>
public class TextEventInfo {
string _text;
bool _return, _backspace;
static IntPtr _keyboardLayout;
static byte[] _state;
#region Externs
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll")]
static extern IntPtr GetKeyboardLayout(uint idThread);
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll")]
static extern bool GetKeyboardState(byte[] lpKeyState);
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll")]
static extern uint MapVirtualKeyEx(uint uCode, uint uMapType, IntPtr dwhkl);
[System.Security.SuppressUnmanagedCodeSecurity]
[DllImport("user32.dll")]
static extern int ToAsciiEx(uint uVirtKey, uint uScanCode, byte[] lpKeyState, ushort[] lpChar, uint uFlags, IntPtr dwhkl);
#endregion
public TextEventInfo(TV_KEYDATA[] pressedKeys, int number) {
StaticInitialization();
_text = "";
// -- Interpretate the keys
for (int i=0; i<number; i++) {
if (pressedKeys[i].Pressed == 1) {
// Differentiate backspace and return from the rest
CONST_TV_KEY scancode = (CONST_TV_KEY)pressedKeys[i].Key;
if (scancode == CONST_TV_KEY.TV_KEY_RETURN) {
_return = true;
} else if (scancode == CONST_TV_KEY.TV_KEY_BACKSPACE) {
_backspace = true;
} else {
// Transfer to ASCII
char c = ScanToASCII(scancode);
if (c != (char)0)
_text += c;
}
}
}
}
public string BufferedText { get { return _text; } }
public bool IsEmpty { get { return _text.Equals("") && !_return && !_backspace; } }
public bool BackspacePressed { get { return _backspace; } }
public bool ReturnPressed { get { return _return; } }
static void StaticInitialization() {
if (_keyboardLayout == IntPtr.Zero) {
_keyboardLayout = GetKeyboardLayout((uint)0);
}
if (_state == null) {
_state = new byte[256];
}
}
static char ScanToASCII(CONST_TV_KEY scancode) {
if (!GetKeyboardState(_state))
return (char)0;
uint virtualKey = MapVirtualKeyEx((uint)scancode, (uint)1, _keyboardLayout);
ushort[] result = new ushort[2];
ToAsciiEx(virtualKey, (uint)scancode, _state, result, (uint)0, _keyboardLayout);
return (char)result[0];
}
}
Edit : Should I post that in the wiki, or is it too obvious/not useful enough?