"Pop"
"http://example.com/pop"
"Rock"
"http://example.com/rock"
请帮帮我。
如果我在Keyboard.KeyDown(Keys.X)之后添加Keyboard.KeyUp(Keys.X),那么当我释放密钥时它不会重复它,但是密钥将重复得慢得多而GetAsyncKeyState将需要更长的时间检测按键,这样我就无法做到。 - user1785594 2小时前
此外,如果我将Timer1间隔增加到50毫秒,那么异步重复问题将变得不那么频繁,但它仍然会这样做,我不认为这是正确的方法。
Imports InputManager
'Using inputmanager to send keys
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
hotkeyx = GetAsyncKeyState(Keys.X)
If hotkeyX < 0 Then
Keyboard.KeyUp(Keys.X)
System.Threading.Thread.Sleep(5)
Keyboard.KeyDown(Keys.X)
System.Threading.Thread.Sleep(5)
End If
'Timer1 interval is 10 ms
&#39; - 谢谢Hans Passant,我制作了一个有效的代码,但我认为我使用了不正确的方法来做到这一点。 由于程序需要keyUP来模拟X键按下,它会有同样的问题,虽然不像以前那样频繁,我不知道如何解决它,所以我只是每10轮增加一次键。有更好的解决方案吗?
答案 0 :(得分:0)
代码段很奇怪,它会在密钥关闭时生成KeyUp通知。您通常可以依赖GetAsyncKeyState()返回的值来检测键入状态,如果键先前已关闭,则将设置位#0。但是当你有一个Timer滴答声时,这种情况不太可能正常工作,显然你的代码有一个调度程序循环。
因此,您需要跟踪以前的值以检测关键状态:
Private prevState(255) As Boolean
您的计时器Tick事件处理程序现在只需要更新此数组并根据需要生成通知。使其尽可能通用:
Private Sub CheckKey(key As Integer)
Dim state = GetAsyncKeyState(key)
If state < 0 Then
prevState(key) = True
Keyboard.KeyDown(CType(key, Keys))
ElseIf prevState(key) Then
prevState(key) = False
Keyboard.KeyUp(CType(key, Keys))
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
CheckKey(Keys.X)
End Sub
Declare Function GetAsyncKeyState Lib "user32.dll" (key As Integer) As Short
请注意这样的代码的失败模式。如果按住键很短的时间,小于计时器的间隔,那么你将完全错过它。使用操作系统提供的KeyUp / Down事件要好得多,你永远不会错过。只需使用相同的数组即可生成事件。而且您不能依赖10毫秒定时器间隔,默认值为15.625毫秒。