locked
How to listen to keyboard inputs RRS feed

  • Question

  • Hi;

    Guys, I'm developing a windows application for a library and I'm having a problem. The problem is that I want to use a bar-code scanner to read the serial numbers of the books. So I want to create a method that runs on the background and listens to the bar-code scanner input. And then as soon as I scan a book, I wanna populate the corresponding TextBox controls and variable.

    So my question is: Is there a way to listen to the keyboard key strokes, because the bar-code scanner sends its input through the usual keyboard stream. I'm using VB with .NET 3.5 to write the application.

    Please help me, and thanks in advance!

    Abdul

    Wednesday, May 23, 2012 4:44 AM

Answers

  • You can handle KeyDown, KeyUp and KeyPress events or you could use external API hooks to handle keys you like.

    In a similar kind of an problem I've used following code to handle only number key strokes because the serial number of the cards that I used to read were only numbers.

    So the class that sets hook and listens either provided keys or just keys to added to it is following without any production quality stuff. The code is in C#, but it should be pretty easy to convert to VB with some help from Google, if you don't know how to handle external API.

        /// <summary>
        /// A class that manages a global low level keyboard hook
        /// </summary>
        internal class KeyboardHook : IDisposable
        {
            #region Api
    
            private struct keyboardHookStruct
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
    
            const int WH_KEYBOARD_LL = 13;
            const int WM_KEYDOWN = 0x100;
            const int WM_KEYUP = 0x101;
            const int WM_SYSKEYDOWN = 0x104;
            const int WM_SYSKEYUP = 0x105;
    
            /// <summary>
            /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
            /// </summary>
            /// <param name="idHook">The id of the event you want to hook</param>
            /// <param name="callback">The callback.</param>
            /// <param name="hInstance">The handle you want to attach the event to, can be null</param>
            /// <param name="threadId">The thread you want to attach the event to, can be null</param>
            /// <returns>a handle to the desired hook</returns>
            [DllImport("user32.dll")]
            static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookCallback callback, IntPtr hInstance, uint threadId);
    
            /// <summary>
            /// Unhooks the windows hook.
            /// </summary>
            /// <param name="hInstance">The hook handle that was returned from SetWindowsHookEx</param>
            /// <returns>True if successful, false otherwise</returns>
            [DllImport("user32.dll")]
            static extern bool UnhookWindowsHookEx(IntPtr hInstance);
    
            /// <summary>
            /// Calls the next hook.
            /// </summary>
            /// <param name="idHook">The hook id</param>
            /// <param name="nCode">The hook code</param>
            /// <param name="wParam">The wparam.</param>
            /// <param name="lParam">The lparam.</param>
            /// <returns></returns>
            [DllImport("user32.dll", SetLastError = true)]
            static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);
    
            /// <summary>
            /// Loads the library.
            /// </summary>
            /// <param name="lpFileName">Name of the library</param>
            /// <returns>A handle to the library</returns>
            [DllImport("kernel32.dll")]
            static extern IntPtr LoadLibrary(string lpFileName);
    
            #endregion
    
            #region Fields & Properties
    
            /// <summary>
            /// defines the callback type for the hook
            /// </summary>
            private delegate int keyboardHookCallback(int code, int wParam, ref keyboardHookStruct lParam);
    
            /// <summary>
            /// The collections of keys to watch for
            /// </summary>
            private List<Keys> hookedKeys = new List<Keys>();
    
            /// <summary>
            /// Handle to the hook, need this to unhook and call the next hook
            /// </summary>
            private IntPtr hHook = IntPtr.Zero;
    
            /// <summary>
            /// The callback method reference
            /// </summary>
            private keyboardHookCallback khp;
    
            /// <summary>
            /// Key press supression
            /// </summary>
            private bool supressKeyPress = false;
    
            /// <summary>
            /// Gets or sets whether or not to hook all keys.
            /// </summary>
            public bool HookAllKeys { get; set; }
    
            /// <summary>
            /// is disposed or not
            /// </summary>
            private bool disposed;
    
            #endregion
    
            #region Events
    
            /// <summary>
            /// Occurs when one of the hooked keys is pressed
            /// </summary>
            public event KeyEventHandler KeyDown;
            /// <summary>
            /// Occurs when one of the hooked keys is released
            /// </summary>
            public event KeyEventHandler KeyUp;
    
            #endregion
    
            #region Constructor
    
            public KeyboardHook(bool supressKeyPress)
            {
                this.disposed = false;
                this.supressKeyPress = supressKeyPress;
                this.HookAllKeys = false;
                khp = new keyboardHookCallback(OnHookCallback);
            }
    
            ~KeyboardHook()
            {
                Dispose();
            }
    
            #endregion
    
            #region Public Methods
    
            /// <summary>
            /// Add hooked key
            /// </summary>
            public void AddHookedKey(Keys key)
            {
                ThrowIfDisposed();
    
                if (!hookedKeys.Contains(key))
                {
                    hookedKeys.Add(key);
                }
            }
    
            /// <summary>
            /// Remove hooked key
            /// </summary>
            public void RemoveHookedKey(Keys key)
            {
                ThrowIfDisposed();
    
                if (hookedKeys.Contains(key))
                {
                    hookedKeys.Remove(key);
                }
            }
    
            /// <summary>
            /// Hook
            /// </summary>
            public void Hook()
            {
                ThrowIfDisposed();
    
                IntPtr hInstance = LoadLibrary("User32");
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, khp, /*IntPtr.Zero*/ hInstance, 0);
            }
    
            /// <summary>
            /// Unhook
            /// </summary>
            public void Unhook()
            {
                ThrowIfDisposed();
    
                UnhookWindowsHookEx(hHook);
            }
    
            /// <summary>
            /// The callback for the keyboard hook
            /// </summary>
            private int OnHookCallback(int code, int wParam, ref keyboardHookStruct lParam)
            {
                if (code >= 0)
                {
                    Keys key = (Keys)lParam.vkCode;
    
                    if (HookAllKeys || hookedKeys.Contains(key))
                    {
                        KeyEventArgs kea = new KeyEventArgs(key);
    
                        if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                        {
                            OnKeyDown(kea);
                        }
                        else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                        {
                            OnKeyUp(kea);
                        }
    
                        if (kea.Handled && supressKeyPress)
                        {
                            return 1;
                        }
                    }
                }
    
                int ret = CallNextHookEx(hHook, code, wParam, ref lParam);
    
                int error = Marshal.GetLastWin32Error();
    
                return ret;
            }
    
            /// <summary>
            /// Raises the KeyDown event.
            /// </summary>
            private void OnKeyDown(KeyEventArgs e)
            {
                if (KeyDown != null)
                    KeyDown(this, e);
            }
    
            /// <summary>
            /// Raises the KeyUp event.
            /// </summary>
            private void OnKeyUp(KeyEventArgs e)
            {
                if (KeyUp != null)
                    KeyUp(this, e);
            }
    
            #endregion
    
            #region Disposable
    
            public void Dispose()
            {
                if (!this.disposed)
                {
                    this.Unhook();
                    this.khp = null;
                    this.hHook = IntPtr.Zero;
                    this.hookedKeys.Clear();
                    this.hookedKeys = null;
                    this.disposed = true;
                }
            }
    
            private void ThrowIfDisposed()
            {
                if (disposed)
                    throw new ObjectDisposedException(GetType().FullName);
            }
    
            #endregion
        }

    And here is sample form that contains only one read only text box to get the pressed keys.

        public partial class Form1 : Form
        {
            private KeyboardHook keyboardhook;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // true to suppress key press = textBox1_KeyUp will not be called if event KeyUp event is handled
                this.keyboardhook = new KeyboardHook(true);
    
                // add keys to listen or set HookAllKeys to true to listen all
                this.keyboardhook.AddHookedKey(Keys.D1);
                this.keyboardhook.AddHookedKey(Keys.D2);
                this.keyboardhook.AddHookedKey(Keys.D3);
                this.keyboardhook.AddHookedKey(Keys.D4);
                this.keyboardhook.AddHookedKey(Keys.D5);
                this.keyboardhook.AddHookedKey(Keys.D6);
                this.keyboardhook.AddHookedKey(Keys.D7);
                this.keyboardhook.AddHookedKey(Keys.D8);
                this.keyboardhook.AddHookedKey(Keys.D9);
                this.keyboardhook.AddHookedKey(Keys.D0);
    
                // set event handler and hook
                this.keyboardhook.KeyUp += new KeyEventHandler(keyboardhook_KeyUp);
                this.keyboardhook.Hook();
            }
    
            // handle the keyboard hook event
            void keyboardhook_KeyUp(object sender, KeyEventArgs e)
            {
                // just write key code and mark as handled
                textBox1.Text = e.KeyCode.ToString();
                e.Handled = true;
            }
    
            private void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                // dispose keyboard hook
                this.keyboardhook.KeyUp -= keyboardhook_KeyUp;
                this.keyboardhook.Dispose();
            }
    
            private void textBox1_KeyUp(object sender, KeyEventArgs e)
            {
                // this is run if you set false to KeyboardHook constructor to prevent key press supress
                // or if any other than D0, D1, D2, D3, D4, D5, D6, D7, D8, D9 is pressed
                MessageBox.Show("TextBox key up event handler.");
            }
        }

    • Proposed as answer by Mike Feng Thursday, May 24, 2012 8:56 AM
    • Marked as answer by Mike Feng Thursday, May 31, 2012 11:49 AM
    Wednesday, May 23, 2012 5:44 AM
  •  Read How to trap Keystrokes in controls (Form in your case)

    Mark Answered, if it solves your question
    Rohit Arora

    • Proposed as answer by Mike Feng Thursday, May 24, 2012 8:57 AM
    • Marked as answer by Mike Feng Thursday, May 31, 2012 11:49 AM
    Wednesday, May 23, 2012 6:56 AM
  • Hi Abdul,

    Sample is given here. Please check, it can help you:

    http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C

    http://support.microsoft.com/kb/320584


    Regards, http://shwetamannjain.blogspot.com or https://shwetalodha.wordpress.com/

    Wednesday, May 23, 2012 1:46 PM
  • Hi Abdul,

    There is one more interesting post:

    http://social.msdn.microsoft.com/Forums/en/winforms/thread/855a5de0-6cb7-44aa-983b-cecb52ca29e8


    Regards, http://shwetamannjain.blogspot.com or https://shwetalodha.wordpress.com/

    Wednesday, May 23, 2012 1:50 PM

All replies

  • You can handle KeyDown, KeyUp and KeyPress events or you could use external API hooks to handle keys you like.

    In a similar kind of an problem I've used following code to handle only number key strokes because the serial number of the cards that I used to read were only numbers.

    So the class that sets hook and listens either provided keys or just keys to added to it is following without any production quality stuff. The code is in C#, but it should be pretty easy to convert to VB with some help from Google, if you don't know how to handle external API.

        /// <summary>
        /// A class that manages a global low level keyboard hook
        /// </summary>
        internal class KeyboardHook : IDisposable
        {
            #region Api
    
            private struct keyboardHookStruct
            {
                public int vkCode;
                public int scanCode;
                public int flags;
                public int time;
                public int dwExtraInfo;
            }
    
            const int WH_KEYBOARD_LL = 13;
            const int WM_KEYDOWN = 0x100;
            const int WM_KEYUP = 0x101;
            const int WM_SYSKEYDOWN = 0x104;
            const int WM_SYSKEYUP = 0x105;
    
            /// <summary>
            /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
            /// </summary>
            /// <param name="idHook">The id of the event you want to hook</param>
            /// <param name="callback">The callback.</param>
            /// <param name="hInstance">The handle you want to attach the event to, can be null</param>
            /// <param name="threadId">The thread you want to attach the event to, can be null</param>
            /// <returns>a handle to the desired hook</returns>
            [DllImport("user32.dll")]
            static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookCallback callback, IntPtr hInstance, uint threadId);
    
            /// <summary>
            /// Unhooks the windows hook.
            /// </summary>
            /// <param name="hInstance">The hook handle that was returned from SetWindowsHookEx</param>
            /// <returns>True if successful, false otherwise</returns>
            [DllImport("user32.dll")]
            static extern bool UnhookWindowsHookEx(IntPtr hInstance);
    
            /// <summary>
            /// Calls the next hook.
            /// </summary>
            /// <param name="idHook">The hook id</param>
            /// <param name="nCode">The hook code</param>
            /// <param name="wParam">The wparam.</param>
            /// <param name="lParam">The lparam.</param>
            /// <returns></returns>
            [DllImport("user32.dll", SetLastError = true)]
            static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref keyboardHookStruct lParam);
    
            /// <summary>
            /// Loads the library.
            /// </summary>
            /// <param name="lpFileName">Name of the library</param>
            /// <returns>A handle to the library</returns>
            [DllImport("kernel32.dll")]
            static extern IntPtr LoadLibrary(string lpFileName);
    
            #endregion
    
            #region Fields & Properties
    
            /// <summary>
            /// defines the callback type for the hook
            /// </summary>
            private delegate int keyboardHookCallback(int code, int wParam, ref keyboardHookStruct lParam);
    
            /// <summary>
            /// The collections of keys to watch for
            /// </summary>
            private List<Keys> hookedKeys = new List<Keys>();
    
            /// <summary>
            /// Handle to the hook, need this to unhook and call the next hook
            /// </summary>
            private IntPtr hHook = IntPtr.Zero;
    
            /// <summary>
            /// The callback method reference
            /// </summary>
            private keyboardHookCallback khp;
    
            /// <summary>
            /// Key press supression
            /// </summary>
            private bool supressKeyPress = false;
    
            /// <summary>
            /// Gets or sets whether or not to hook all keys.
            /// </summary>
            public bool HookAllKeys { get; set; }
    
            /// <summary>
            /// is disposed or not
            /// </summary>
            private bool disposed;
    
            #endregion
    
            #region Events
    
            /// <summary>
            /// Occurs when one of the hooked keys is pressed
            /// </summary>
            public event KeyEventHandler KeyDown;
            /// <summary>
            /// Occurs when one of the hooked keys is released
            /// </summary>
            public event KeyEventHandler KeyUp;
    
            #endregion
    
            #region Constructor
    
            public KeyboardHook(bool supressKeyPress)
            {
                this.disposed = false;
                this.supressKeyPress = supressKeyPress;
                this.HookAllKeys = false;
                khp = new keyboardHookCallback(OnHookCallback);
            }
    
            ~KeyboardHook()
            {
                Dispose();
            }
    
            #endregion
    
            #region Public Methods
    
            /// <summary>
            /// Add hooked key
            /// </summary>
            public void AddHookedKey(Keys key)
            {
                ThrowIfDisposed();
    
                if (!hookedKeys.Contains(key))
                {
                    hookedKeys.Add(key);
                }
            }
    
            /// <summary>
            /// Remove hooked key
            /// </summary>
            public void RemoveHookedKey(Keys key)
            {
                ThrowIfDisposed();
    
                if (hookedKeys.Contains(key))
                {
                    hookedKeys.Remove(key);
                }
            }
    
            /// <summary>
            /// Hook
            /// </summary>
            public void Hook()
            {
                ThrowIfDisposed();
    
                IntPtr hInstance = LoadLibrary("User32");
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL, khp, /*IntPtr.Zero*/ hInstance, 0);
            }
    
            /// <summary>
            /// Unhook
            /// </summary>
            public void Unhook()
            {
                ThrowIfDisposed();
    
                UnhookWindowsHookEx(hHook);
            }
    
            /// <summary>
            /// The callback for the keyboard hook
            /// </summary>
            private int OnHookCallback(int code, int wParam, ref keyboardHookStruct lParam)
            {
                if (code >= 0)
                {
                    Keys key = (Keys)lParam.vkCode;
    
                    if (HookAllKeys || hookedKeys.Contains(key))
                    {
                        KeyEventArgs kea = new KeyEventArgs(key);
    
                        if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (KeyDown != null))
                        {
                            OnKeyDown(kea);
                        }
                        else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (KeyUp != null))
                        {
                            OnKeyUp(kea);
                        }
    
                        if (kea.Handled && supressKeyPress)
                        {
                            return 1;
                        }
                    }
                }
    
                int ret = CallNextHookEx(hHook, code, wParam, ref lParam);
    
                int error = Marshal.GetLastWin32Error();
    
                return ret;
            }
    
            /// <summary>
            /// Raises the KeyDown event.
            /// </summary>
            private void OnKeyDown(KeyEventArgs e)
            {
                if (KeyDown != null)
                    KeyDown(this, e);
            }
    
            /// <summary>
            /// Raises the KeyUp event.
            /// </summary>
            private void OnKeyUp(KeyEventArgs e)
            {
                if (KeyUp != null)
                    KeyUp(this, e);
            }
    
            #endregion
    
            #region Disposable
    
            public void Dispose()
            {
                if (!this.disposed)
                {
                    this.Unhook();
                    this.khp = null;
                    this.hHook = IntPtr.Zero;
                    this.hookedKeys.Clear();
                    this.hookedKeys = null;
                    this.disposed = true;
                }
            }
    
            private void ThrowIfDisposed()
            {
                if (disposed)
                    throw new ObjectDisposedException(GetType().FullName);
            }
    
            #endregion
        }

    And here is sample form that contains only one read only text box to get the pressed keys.

        public partial class Form1 : Form
        {
            private KeyboardHook keyboardhook;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                // true to suppress key press = textBox1_KeyUp will not be called if event KeyUp event is handled
                this.keyboardhook = new KeyboardHook(true);
    
                // add keys to listen or set HookAllKeys to true to listen all
                this.keyboardhook.AddHookedKey(Keys.D1);
                this.keyboardhook.AddHookedKey(Keys.D2);
                this.keyboardhook.AddHookedKey(Keys.D3);
                this.keyboardhook.AddHookedKey(Keys.D4);
                this.keyboardhook.AddHookedKey(Keys.D5);
                this.keyboardhook.AddHookedKey(Keys.D6);
                this.keyboardhook.AddHookedKey(Keys.D7);
                this.keyboardhook.AddHookedKey(Keys.D8);
                this.keyboardhook.AddHookedKey(Keys.D9);
                this.keyboardhook.AddHookedKey(Keys.D0);
    
                // set event handler and hook
                this.keyboardhook.KeyUp += new KeyEventHandler(keyboardhook_KeyUp);
                this.keyboardhook.Hook();
            }
    
            // handle the keyboard hook event
            void keyboardhook_KeyUp(object sender, KeyEventArgs e)
            {
                // just write key code and mark as handled
                textBox1.Text = e.KeyCode.ToString();
                e.Handled = true;
            }
    
            private void Form1_FormClosed(object sender, FormClosedEventArgs e)
            {
                // dispose keyboard hook
                this.keyboardhook.KeyUp -= keyboardhook_KeyUp;
                this.keyboardhook.Dispose();
            }
    
            private void textBox1_KeyUp(object sender, KeyEventArgs e)
            {
                // this is run if you set false to KeyboardHook constructor to prevent key press supress
                // or if any other than D0, D1, D2, D3, D4, D5, D6, D7, D8, D9 is pressed
                MessageBox.Show("TextBox key up event handler.");
            }
        }

    • Proposed as answer by Mike Feng Thursday, May 24, 2012 8:56 AM
    • Marked as answer by Mike Feng Thursday, May 31, 2012 11:49 AM
    Wednesday, May 23, 2012 5:44 AM
  •  Read How to trap Keystrokes in controls (Form in your case)

    Mark Answered, if it solves your question
    Rohit Arora

    • Proposed as answer by Mike Feng Thursday, May 24, 2012 8:57 AM
    • Marked as answer by Mike Feng Thursday, May 31, 2012 11:49 AM
    Wednesday, May 23, 2012 6:56 AM
  • Hi Abdul,

    Sample is given here. Please check, it can help you:

    http://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C

    http://support.microsoft.com/kb/320584


    Regards, http://shwetamannjain.blogspot.com or https://shwetalodha.wordpress.com/

    Wednesday, May 23, 2012 1:46 PM
  • Hi Abdul,

    There is one more interesting post:

    http://social.msdn.microsoft.com/Forums/en/winforms/thread/855a5de0-6cb7-44aa-983b-cecb52ca29e8


    Regards, http://shwetamannjain.blogspot.com or https://shwetalodha.wordpress.com/

    Wednesday, May 23, 2012 1:50 PM