C# - 如何使用 SendKeys.Send 通过 SHIFT 键发送小写字母?

发布于 2024-10-27 12:39:38 字数 863 浏览 1 评论 0原文

我正在为我的项目使用 这个 键盘挂钩。我无法在按下 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 事件中,但要保持一致。

请帮助我,我非常沮丧,我的应用程序开发此时受到了打击。

I am using this keyboard hook for my project. I am unable to send small letters using SendKeys.Send() with SHIFT modifier key pressed. My app needs (for example) if the user presses K button "a" should be sent and if he presses SHIFT+K, "b" should be sent. The code is:

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

But it sends "B" (Capital letter) instead of "b", that is the SHIFT key changes the sent keystroke "b" to uppercase. This happens even after adding Keys.Shift to the hook.

I tried many approaches including using e.SupressKeyPress, SendKeys("b".toLower()) and putting above code in KeyUp event but in vein.

Pls help me, I am very frustated, my application developement is struck at this point.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

意中人 2024-11-03 12:39:38

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

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

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

这看起来像是通过覆盖表单的 ProcessCmdKey 方法。例如:

  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> 已被询问并回答了有关 Windows 徽标键的问题。

特别是,您需要编写处理由全局钩子引发的 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;
   }
}

You're sending the keys while the Shift key is still down, which is causing them to be uppercased.
You need to figure out a way to cancel the Shift key press along with the K key press.

The global hook sample that you're using is a little bare; it should also be reporting which modifier keys are held down. Unfortunately, it looks like that functionality hasn't been implemented.

Why do you need to use a keyboard hook in the first place? Do you really need to handle key events that occur when your form doesn't have the focus? And if so, why in the world would you use SendKey? How do you know what the currently active application is going to do with the key presses you send?

This looks like something that would be much better handled in an override of your form's ProcessCmdKey method, instead. For example:

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

EDIT: Your comment suggests that you do in fact need to handle key events that occur when you form does not have the focus. Assuming you need to handle more than simply the K key, you will need to do this using a global hook.

As I mentioned before, the problem is that the user is still holding down the Shift key while you're sending the B key using SendInput, which is causing it to register as a capital letter B instead of a lowercase letter. So then the solution is obvious: you need to figure out a way to cancel that Shift key press so that it is not processed by the operating system. Of course, if you eat the key event, you also need to figure out a way of tracking it so that your application still knows when it was pressed and can act accordingly.

A quick search reveals a similar question has already been asked and answered about the Windows logokey.

In particular, you need to write the code that handles the KeyDown event raised by your global hook like this (at least, this code works with the global hook class that I wrote; it should work with yours, too, but I haven't actually tested it):

// 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;
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文