【问题标题】:C# - How to send small letters with SHIFT key using SendKeys.Send?C# - 如何使用 SendKeys.Send 发送带有 SHIFT 键的小写字母?
【发布时间】:2011-03-26 15:15:57
【问题描述】:

我正在为我的项目使用this 键盘挂钩。我无法在按下 SHIFT 修饰键的情况下使用 SendKeys.Send() 发送小写字母。我的应用程序需要(例如)如果用户按下 K 按钮 "a" 应该发送并且如果他按下 SHIFT+K , "b" 应该被发送。代码是:

void gkh_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.K)
    {
        if (Control.ModifierKeys == Keys.Shift)
            SendKeys.Send("b");
        else
            SendKeys.Send("a");
    }
    e.Handled == true;   
}

但它发送的是“B”(大写字母)而不是“b”,即SHIFT键改变了发送的击键“ b" 为大写。即使在将 Keys.Shift 添加到钩子之后也会发生这种情况。

我尝试了很多方法,包括使用 e.SupressKeyPressSendKeys("b".toLower()) 并将上面的代码放入 KeyUp 事件中,但要保持一致。 p>

请帮助我,我很沮丧,我的应用程序开发在这一点上受到打击。

【问题讨论】:

    标签: c# .net sendkeys keyboard-hook


    【解决方案1】:

    您在 Shift 键仍然按下时发送键,这导致它们变为大写。
    您需要找到一种方法来取消 Shift 按键以及 K 按键。

    您使用的全局钩子示例有点简单;它应该报告哪些修饰键被按住。不幸的是,该功能似乎尚未实现。

    为什么首先需要使用键盘挂钩?您真的需要处理表单没有焦点时发生的关键事件吗?如果是这样,你到底为什么要使用SendKey?您如何知道当前活动的应用程序将如何处理您发送的按键操作?

    这看起来可以更好地处理表单的ProcessCmdKey method,而不是。例如:

      protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
      {
         if (keyData == (Keys.K | Keys.Shift))
         {
            SendKeys.Send("b");
            return true;  // indicate that you handled the key
         }
         else if (keyData == Keys.K)
         {
            SendKeys.Send("a");
            return true;  // indicate that you handled the key
         }
    
         // call the base class to handle the key
         return base.ProcessCmdKey(ref msg, keyData);
      }
    

    编辑:您的评论表明您确实需要处理当您形成 没有焦点时发生的关键事件。假设您需要处理的不仅仅是 K 键,您将需要使用全局挂钩来执行此操作。

    正如我之前提到的,问题是当您使用SendInput 发送 B 键时,用户仍然按住 Shift 键,即导致它注册为大写字母 B 而不是小写字母。那么解决方案很明显:您需要找出一种方法来取消Shift 键按下,以便操作系统不会对其进行处理。当然,如果你吃掉了按键事件,你还需要想办法跟踪它,这样你的应用程序仍然知道它什么时候被按下并可以做出相应的反应。

    快速搜索发现a similar question 已经被询问并回答了关于 键的问题。

    特别是,您需要编写代码来处理由全局钩子引发的KeyDown 事件,如下所示(至少,此代码适用于我编写的全局钩子类;它也应该适用于您的,但我还没有实际测试过):

    // Private flag to hold the state of the Shift key even though we eat it
    private bool _shiftPressed = false;
    
    private void gkh_KeyDown(object sender, KeyEventArgs e)
    {
       // See if the user has pressed the Shift key
       // (the global hook detects individual keys, so we need to check both)
       if ((e.KeyCode == Keys.LShiftKey) || (e.KeyCode == Keys.RShiftKey))
       {
          // Set the flag
          _shiftPressed = true;
    
          // Eat this key event
          // (to prevent it from being processed by the OS)
          e.Handled = true;
       }
    
    
       // See if the user has pressed the K key
       if (e.KeyCode == Keys.K)
       {
          // See if they pressed the Shift key by checking our flag
          if (_shiftPressed)
          {
             // Clear the flag
             _shiftPressed = false;
    
             // Send a lowercase letter B
             SendKeys.Send("b");
          }
          else
          {
             // Shift was not pressed, so send a lowercase letter A
             SendKeys.Send("a");
          }
    
          // Eat this key event
          e.Handled = true;
       }
    }
    

    【讨论】:

    • 我需要键盘挂钩,因为我的项目是一个重新映射键盘键的 IME(输入法编辑器)。表单在启动时未加载,应用程序位于系统托盘中,捕获按键并将不同的字符(使用 SendKeys.Send 方法)发送到焦点应用程序(例如文字处理器)。 e.Handled 抑制 K 键但不抑制 SHIFT 键的效果。我还添加了 Keys.Shift 到钩子中,但在静脉中。
    • @ePandit:我已经更新了我的答案。看看这是否更适合你。正如我所提到的,我使用我自己的全局钩子类来测试它,但由于它都基于相同的 Windows API 函数,它也应该适用于你正在使用的那个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-28
    • 1970-01-01
    • 2019-02-11
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 2015-07-08
    相关资源
    最近更新 更多