Search Home Members Contacts
About Us
Products
Downloads
Community
Support
Pages: [1]
  Print  
Author Topic: TV_KEYDATA buffered input scancodes to text (source)  (Read 1035 times)
Zaknafein
Customers
Community Member
*****
Posts: 2673


WWW
« on: January 24, 2006, 03:53:01 PM »

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 Tongue). 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... Smiley

Code:
   /// <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?
Logged

zaknafein.
>> the instruction limit : my blog & samples repository! <<
astralvoid
Customers
Community Member
*****
Posts: 50


« Reply #1 on: January 25, 2006, 03:12:51 PM »

Although I wish that there was a way to do it without all of the unmanaged code, I think that it may be very useful in specific circumstances...

Regardless, I don't think a Wiki can hurt anything.  
 Smiley
Logged
Zaknafein
Customers
Community Member
*****
Posts: 2673


WWW
« Reply #2 on: January 25, 2006, 03:26:45 PM »

Ya, well the Managed equivalent would not use the InputEngine, like BYTE-Smasher's WM_CHAR trapping, and I hate to have to use a form.

Alright on the wiki, when I find the time Smiley
Logged

zaknafein.
>> the instruction limit : my blog & samples repository! <<
Disa
Community Member
*
Posts: 36


« Reply #3 on: July 06, 2007, 06:25:08 AM »

How it is possible to make definition of a language allocation?
For me normally works only with an English allocation as me to add an opportunity of input of the text on other language allocations
Logged
Venus
Community Member
*
Posts: 22


« Reply #4 on: March 31, 2008, 01:23:51 PM »

I know this post is a little old but I found it extremely useful. Just wanted to say I think it should be added to the Wiki. And thank Zak for posting it.
Logged

Venus
This is why I take so long to program
http://www.spectraledge.com/LexLoomis
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.3 | SMF © 2006-2007, Simple Machines LLC
Seo4Smf v0.2 © Webmaster's Talks