【问题标题】:How to press and hold a key?如何按住一个键?
【发布时间】:2025-12-28 04:20:08
【问题描述】:

我正在创建一个程序来使用我的鼠标和键盘自动与另一个应用程序交互。我找到了可以单击一次键并立即释放它的代码(据我所知);这是 SendKeys.Send("{up}")。如果可以的话,请不要把事情复杂化,我在这里学习。

我的问题是如何发送按键并将其按住由变量确定的时间长度。我大致想:

Press and hold arrow key "up"
wait(Random.next(1,10))
Release arrow key "up"

我在 Visual Studio 17 社区中用 Visual Basic 编写它。

谢谢!

查看 Valyrean Groups 代码后,我将其编辑为:

Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Integer, ByVal wMapType As Integer) As Integer

Private Sub HoldKeyDown(ByVal key As Byte, ByVal durationInSeconds As Integer)

    keybd_event(key, MapVirtualKey(key, 0), 0, 0) ' Down
    Threading.Thread.Sleep((RandNum.Next(1000, 5000)))
    keybd_event(key, MapVirtualKey(key, 0), 2, 0) ' Up

End Sub

我现在的问题是如何更改按住的箭头键?

【问题讨论】:

  • 仅供参考 keybd_event() 已弃用并替换为 SendInput()

标签: vb.net input keyboard wait


【解决方案1】:

您需要使用 System32 中的 keybd 事件库。将以下代码添加到您的表单中。

Private Declare Sub keybd_event Lib "user32.dll" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Integer, ByVal wMapType As Integer) As Integer

Private Sub HoldKeyDown(ByVal key As Byte, ByVal durationInSeconds As Integer)
    Dim targetTime As DateTime = DateTime.Now().AddSeconds(durationInSeconds)
    keybd_event(key, MapVirtualKey(key, 0), 0, 0) ' Down
    While targetTime.Subtract(DateTime.Now()).TotalSeconds > 0
        Application.DoEvents()
    End While
    keybd_event(key, MapVirtualKey(key, 0), 2, 0) ' Up
End Sub

那就用吧……

HoldKeyDown(Keys.Up,3)

【讨论】:

  • 感谢您的回复,尽管这可能有用 我正在寻找尽可能简单的东西。我使用计时器来帮助保持长度;这能让事情变得更容易吗?我想对箭头的所有方向(上、下、左、右)重复这一点,这样它可能会成为一个相当大的工作
  • 代码不会变大。这相当简单......要“按住”另一个键,只需使用另一个键和时间再次调用该函数。
  • 只需使用您想要按住的任何键调用该函数。 HoldKeyDown(Keys.Down,5)HoldKeyDown(Keys.Left,4)。将按住箭头 5 秒,另一个将按住左键 4 秒。
  • 不要在无延迟循环中调用 Application.DoEvents() 这会占用大量 CPU,坦率地说,你根本不应该调用 DoEvents() !请改用 Async/Await、线程或计时器。