Willy
Willy

Reputation: 10638

Simulate sending keys

I am trying to simulate a keyboard by sending keys using keybd_event as described below.

Initially from my window load event I create a background worker and start it. This background worker, among other things, subscribe to a form keypress event if a simulation parameter is active.

I have ensured that this parameter is active so I subscribe to the winform keypress event correctly.

Also in the form I have a button to start the simulation of the keyboard. When this button is clicked "btnSimulateKeyboard_Click", I send a string that then is converted to an array of bytes and finally each byte is sent using keybd_event within a loop.

My problem is that form keypress event is never fired. Why? Isn't it the correct way to simulate sending keys?

namespace My.Apps.WinForms.Test
{
    public partial class MyForm: Form
    {
        #region Constructor
        public MyForm()
        {
          InitializeComponent();
        } 
        #endregion

        private void MyForm_Load(object sender, EventArgs e)
        {
            // Some stuff

            _worker = new BackgroundWorker();
            _worker.DoWork += new DoWorkEventHandler(_worker _DoWork);
            _worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(_worker _RunWorkerCompleted);
            _worker.ProgressChanged += new ProgressChangedEventHandler(_worker t_ProgressChanged);
            _worker.WorkerReportsProgress = true;
            _worker.RunWorkerAsync();
        }

        private void _worker_DoWork(object sender, DoWorkEventArgs e)
        {
            // Some stuff
            // Load parameters

            if (simulateKeyboard)
            {
               this.InitKb();
            }

            // Some stuff
        }

        private void InitKb()
        {
            this.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.MyForm_KeyPress);
        }

        private void MyForm_KeyPress(object sender, KeyPressEventArgs e)
        {
            // Check key pressed
        }    

        private void btnSimulateKeyboard_Click(object sender, EventArgs e)
        {
            SimulateKeyboardTest.SendString("abcdefg");
        }       
    }
}

Keyboard simulation class:

namespace My.Apps.WinForms.Test
{
    public static class SimulateKeyboardTest
    {
        #region DLLs Import
        [DllImport("user32.dll", SetLastError = true)]
        static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
        #endregion

        #region Constants

        public const int KEYEVENTF_EXTENDEDKEY = 0x0001;      // Key down flag
        public const int KEYEVENTF_KEYUP = 0x0002;            // Key up flag

        #endregion

        #region Public Static Methods

        /// <summary>
        ///   Sends a string.
        /// </summary>
        /// <param name="strChars">String to send.</param>
        public static void SendString(string strChars)
        {
            byte[] bytChars = Encoding.ASCII.GetBytes(strChars);
            for (int i = 0; i < bytChars.Length; i++)
            { 
                KeyPress(bytChars[i]);
                KeyUp(bytChars[i]);
            }
        }

        /// <summary>
        ///   Simulate a key press
        /// </summary>
        public static void KeyPress(byte keyCode)
        {
            keybd_event(keyCode, 0, KEYEVENTF_EXTENDEDKEY, 0);
        }

        /// <summary>
        ///   Simulate a key release 
        /// </summary>
        public static void KeyUp(byte keyCode)
        {
            keybd_event(keyCode, 0, KEYEVENTF_KEYUP, 0);
        }

        #endregion
    }
}

Upvotes: 0

Views: 1357

Answers (1)

Phil
Phil

Reputation: 131

I think you can just send the keys using the winForms SendKeys.Send() method, no workers or events required.

see MSDN docs: https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(v=vs.110).aspx

Upvotes: 1

Related Questions