【问题标题】:C# KEYEVENTF_KEYUP doesn't work in specific appC# KEYEVENTF_KEYUP 在特定应用程序中不起作用
【发布时间】:2013-11-27 11:51:15
【问题描述】:

我需要模拟一些键,这里是代码:

[DllImport("user32.dll")]
private static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

private const int KEYEVENTF_EXTENDEDKEY = 1;
private const int KEYEVENTF_KEYUP = 2;

public static void KeyDown(Keys vKey)
{
    keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
}

public static void KeyUp(Keys vKey)
{
    keybd_event((byte)vKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}

KeyboardSend.KeyDown(Keys.Z);
KeyboardSend.KeyUp(Keys.Z);

但在一个特定的应用程序中,“KeyUp”方法不起作用并且在我按下键盘上的键之前一直被按下。

我做错了什么?

【问题讨论】:

  • 考虑在您的 KeyDown() 和 KeyUp() 调用之间放置一个小的 延迟System.Threading.Thread.Sleep(100);
  • 我已经试过了:(
  • 你试过SendKeys.SendWait("z"); 吗? ...你为什么在这里使用KEYEVENTF_EXTENDEDKEY
  • 我需要按下键并在需要时将其向上。
  • Z 虽然不是扩展键。请参阅here扩展键由键盘右侧的 ALT 和 CTRL 键组成; INS、DEL、HOME、END、PAGE UP、PAGE DOWN 和数字键盘左侧集群中的箭头键;数字锁定键; BREAK (CTRL+PAUSE) 键;打印 SCRN 键;以及数字键盘中的除 (/) 和 ENTER 键。

标签: c# key emulation user32


【解决方案1】:

我在 Ryan West 的解决方案中看到的唯一变化是,他在 KeyDown 和 @ 的第三个参数中从调用函数 keybd_event 中删除了 KEYEVENTF_EXTENDEDKEY 标志987654324@方法,所以结果在KeyDown方法中,调用keybd_event函数的第三个参数为0,而在KeyUp方法中,只有KEYEVENTF_KEYUP。 只是很小的变化导致KeyUp 方法起作用并解决了您的问题。

正确地阅读 MSDN 站点中的 keybd_event 函数,如果您之前阅读过,甚至可以再次

它们提供有关该函数及其参数的信息和详细信息。他们还解释了您可以在keybd_event 函数的第三个参数中使用的所有标志,尤其是您的问题KEYEVENTF_EXTENDEDKEY 中的情况。

如果您将正确再次阅读,也许您会明白为什么KEYEVENTF_EXTENDEDKEY标志会导致您的KeyUp方法工作,以及为什么你必须删除该标志,以使你的KeyUp方法工作。

可能还可以了解将来如何正确调用keybd_event函数,这样您就不会遇到任何问题用它。

【讨论】:

    【解决方案2】:

    当我将代码更改为以下代码时,它似乎工作得很好。我通过打开记事本,运行程序,然后按住“a”键对其进行了测试。它打印小写 3 秒,然后开始做大写,然后又回到小写。

    public static void KeyDown(Keys vKey)
    {
        keybd_event((byte)vKey, 0, 0, 0);
    }
    
    public static void KeyUp(Keys vKey)
    {
        keybd_event((byte)vKey, 0, KEYEVENTF_KEYUP, 0);
    }
    
    System.Threading.Thread.Sleep(3000);
    KeyDown(Keys.SHIFT);
    System.Threading.Thread.Sleep(4000);
    KeyUp(Keys.SHIFT);
    

    尝试查看 Windows 输入模拟器,了解如何模拟按键的一个很好的示例。它是 User32.dll 中 SendInput 函数的开源包装器。

    我学到的一件事是,要模拟按住键,通常发送 keydown 是不够的,稍等片刻,然后向上发送键。如果您希望按键像普通键盘一样重复按键,您是否必须继续发送键盘事件并以按键事件结束。

    http://inputsimulator.codeplex.com/

    【讨论】:

      猜你喜欢
      • 2022-01-10
      • 2014-11-03
      • 2016-04-28
      • 2011-06-02
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      • 2017-09-28
      • 2021-02-10
      相关资源
      最近更新 更多