问题描述
我试图在按住 LButton 时自动重复它,然后在松开时停止,我遇到了一个问题,即使它没有被按住,它也会不断重复自己.
I'm trying to automatically repeat LButton while it's held down, then stop when it's released, I've ran into a problem where it will continuously repeat itself even while it's not been held down.
是否有任何解决方法?我需要它也适用于其他应用程序,这就是我使用 GetAsyncKeyState
的原因.
Is there any workarounds for this? I need it to also work on other applications which is why I'm using GetAsyncKeyState
.
这是我目前所拥有的:
Imports System.Threading
Public Class Form1
Const KeyDownBit As Integer = &H8000
Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Integer) As Short
Private Declare Sub mouse_event Lib "user32" (ByVal dwflags As Integer, ByVal dx As Integer, ByVal cbuttons As Integer, ByVal dy As Integer, ByVal dwExtraInfo As Integer)
Private Const mouseclickup = 4
Private Const mouseclickdown = 2
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If (GetAsyncKeyState(Keys.LButton) And KeyDownBit) = KeyDownBit Then
mouse_event(mouseclickup, 0, 0, 0, 0)
Thread.Sleep(100)
mouse_event(mouseclickdown, 0, 0, 0, 0)
End If
End Sub
使用此代码,当我左键单击时,即使 Lbutton 被释放,代码也会持续自动单击,但这并不是我想要的.我想要它,所以当我按住 LButton 时,它会继续点击,然后当 LButton 被释放时,它会停止点击.
With this code, when I left click, the code will continuously keep clicking automatically even when Lbutton is released, but that's not exactly what i want. I want it so when I hold LButton, it will then continuously click, then when LButton is released, it will stop clicking.
我尝试过使用 BackgroundWorker
,尽管发生了同样的事情.
I have tried using a BackgroundWorker
, although the same thing happens.
我也试过在 mouse_event(mouseclickup, 0, 0, 0, 0)
之前有 mouse_event(mouseclickdown, 0, 0, 0, 0)
,但后来每次按下它只是将单击变成双击,然后停止.
I have also tried having mouse_event(mouseclickdown, 0, 0, 0, 0)
before mouse_event(mouseclickup, 0, 0, 0, 0)
, but then it just turns a single click into a double click each time it's pressed down, then stops.
推荐答案
不断被点击的原因是因为你每次检测到鼠标点击时都会发送一次新的鼠标点击.
The reason keeps getting clicked is because you keep sending a new mouse click every time you detect one.
由于 GetAsyncKeyState()
读取键盘/鼠标输入流,因此您无法使用任何向流添加点击的方法,因为一切都会像您当前遇到的那样卡住.
Since GetAsyncKeyState()
reads the keyboard/mouse input stream you cannot use any method that adds clicks to the stream since everything will get stuck like you are currently experiencing.
为了解决这个问题,我将一个辅助类和一个方法放在一起,该方法将鼠标点击作为窗口消息发送到点击点下方的窗口.通过这样做,我们现在将鼠标点击直接发送到窗口而不是键盘/鼠标输入流,这意味着 GetAsyncKeyState()
不会注意到它.
In order to eliminate the problem I put together a helper class with a method that will send mouse clicks as window messages to the window below the click point. By doing so we are now sending mouse clicks directly to the window instead of the keyboard/mouse input stream, meaning that GetAsyncKeyState()
won't take notice of it.
编辑 (2019-08-16)
MouseInputHelper
类早已与 InputHelper
合并.答案已更新为使用后者.
The MouseInputHelper
class has since long been merged with InputHelper
. The answer has been updated to use the latter instead.
从 GitHub 下载 InputHelper:
https://github.com/Visual-Vincent/InputHelper/releases
现在您可以在计时器中执行以下操作:
Now in your timer you can do:
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If InputHelper.Mouse.IsButtonDown(MouseButtons.Left) Then
InputHelper.WindowMessages.SendMouseClick(MouseButtons.Left, Cursor.Position)
End If
End Sub
希望这会有所帮助!
这篇关于如何在按住按键时以编程方式重复按键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!