【问题标题】:Simulate sending keys模拟发送密钥
【发布时间】:2018-08-09 21:55:37
【问题描述】:

我正在尝试通过使用 keybd_event 发送键来模拟键盘,如下所述。

最初从我的窗口加载事件中,我创建了一个后台工作程序并启动它。如果模拟参数处于活动状态,则此后台工作人员会订阅表单按键事件。

我已确保此参数处于活动状态,因此我正确订阅了 winform keypress 事件。

我也有一个按钮来启动键盘的模拟。当单击此按钮“btnSimulateKeyboard_Click”时,我会发送一个字符串,然后将其转换为字节数组,最后在循环中使用 keybd_event 发送每个字节。

我的问题是表单按键事件永远不会被触发。为什么?不是模拟发送密钥的正确方式吗?

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");
        }       
    }
}

键盘模拟类:

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
    }
}

【问题讨论】:

  • 你不应该在KeyPress之前打电话给KeyDown吗? AFAIK 正常顺序是KeyDown => KeyPress => KeyUp
  • 发送击键以控制焦点,您刚刚单击的按钮,没有用。一个按钮只响应一个空间,而不是你想要发送的空间,因为它永远不会结束。当您有一个可以获得焦点的控件时,表单永远不会获得 KeyPress 事件。这段代码没有用,也无法猜测它的用途。
  • @HansPassant 那么如何在单击按钮后以编程方式将键发送到 winform 表单按键事件?
  • 当您可以直接调用 MyForm_KeyPress() 方法时,您不需要事件。直接调用事件处理程序方法并没有错,尽管您通常倾向于将通用代码移动到另一个方法中。

标签: c# winforms .net-3.5


【解决方案1】:

我认为您可以使用 winForms SendKeys.Send() 方法发送密钥,不需要工作人员或事件。

请参阅 MSDN 文档:https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys.send(v=vs.110).aspx

【讨论】:

  • 是的,但这与 Hans Passant 评论的问题相同。如果我从按钮单击事件中使用 SendKeys.Send(),则永远不会引发表单按键事件,因为刚刚单击的按钮是当前活动的并且它具有焦点....那么如何解决这个问题?
猜你喜欢
  • 2020-12-14
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多