vb.net – 如何在按住键的同时以编程方式重复键?

前端之家收集整理的这篇文章主要介绍了vb.net – 如何在按住键的同时以编程方式重复键?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图在按下它时自动重复LButton,然后在它被释放时停止,我遇到了一个问题,即使它没有按下它也会不断重复.

这有什么变通方法吗?我需要它也可以用于其他应用程序,这就是我使用GetAsyncKeyState的原因.

这是我到目前为止:

  1. Imports System.Threading
  2.  
  3. Public Class Form1
  4. Const KeyDownBit As Integer = &H8000
  5. Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vkey As Integer) As Short
  6. 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)
  7. Private Const mouseclickup = 4
  8. Private Const mouseclickdown = 2
  9.  
  10. Private Sub Timer1_Tick(sender As Object,e As EventArgs) Handles Timer1.Tick
  11. If (GetAsyncKeyState(Keys.LButton) And KeyDownBit) = KeyDownBit Then
  12. mouse_event(mouseclickup,0)
  13. Thread.Sleep(100)
  14. mouse_event(mouseclickdown,0)
  15. End If
  16. End Sub

使用此代码,当我左键单击时,即使释放Lbutton,代码也会不断自动点击,但这并不是我想要的.我想要它,所以当我按住LButton时,它会不断点击,然后当LButton被释放时,它会停止点击.

我尝试过使用BackgroundWorker,尽管发生了同样的事情.

我也试过在mouse_event(mouseclickup,0)之前使用mouse_event(mouseclickdown,0),但是每次按下它时它只需单击一次就会双击,然后停止.

LMB持续点击的原因是每次检测到LMB时都会发送新的鼠标.

由于GetAsyncKeyState()读取键盘/鼠标输入流,因此您无法使用任何向流添加点击的方法,因为一切都会像您当前遇到的那样陷入困境.

为了消除这个问题,我将一个帮助类放在一起,该方法将鼠标点击作为窗口消息发送到点击点下方的窗口.通过这样做,我们现在直接将鼠标点击发送到窗口而不是键盘/鼠标输入流,这意味着GetAsyncKeyState()将不会注意到它.

MouseInputHelper.vb

  1. Imports System.Runtime.InteropServices
  2.  
  3. Public NotInheritable Class MouseInputHelper
  4. Private Sub New()
  5. End Sub
  6.  
  7. #Region "Methods"
  8. #Region "SendMouseClick()"
  9. ''' <summary>
  10. ''' Sends a Window Message-based mouse click to the specified coordinates of the screen.
  11. ''' </summary>
  12. ''' <param name="Button">The button to press.</param>
  13. ''' <param name="Location">The position where to send the click (in screen coordinates).</param>
  14. ''' <remarks></remarks>
  15. Public Shared Sub SendMouseClick(ByVal Button As MouseButtons,ByVal Location As Point)
  16. Dim hWnd As IntPtr = NativeMethods.WindowFromPoint(New NativeMethods.NATIVEPOINT(Location.X,Location.Y)) 'Get the window at the specified click point.
  17. Dim ButtonMessage As NativeMethods.MouseButtonMessages = NativeMethods.MouseButtonMessages.None 'A variable holding which Window Message to use.
  18.  
  19. Select Case Button 'Set the appropriate mouse button Window Message.
  20. Case MouseButtons.Left : ButtonMessage = NativeMethods.MouseButtonMessages.WM_LBUTTONDOWN
  21. Case MouseButtons.Right : ButtonMessage = NativeMethods.MouseButtonMessages.WM_RBUTTONDOWN
  22. Case MouseButtons.Middle : ButtonMessage = NativeMethods.MouseButtonMessages.WM_MBUTTONDOWN
  23. Case MouseButtons.XButton1,MouseButtons.XButton2
  24. ButtonMessage = NativeMethods.MouseButtonMessages.WM_XBUTTONDOWN
  25. Case Else
  26. Throw New InvalidOperationException("Invalid mouse button " & Button.ToString())
  27. End Select
  28.  
  29. Dim ClickPoint As New NativeMethods.NATIVEPOINT(Location.X,Location.Y) 'Create a native point.
  30.  
  31. If NativeMethods.ScreenToClient(hWnd,ClickPoint) = False Then 'Convert the click point to client coordinates relative to the window.
  32. Throw New Exception("Unable to convert screen coordinates to client coordinates! Win32Err: " & _
  33. Marshal.GetLastWin32Error())
  34. End If
  35.  
  36. Dim wParam As IntPtr = IntPtr.Zero 'Used to specify which X button was clicked (if any).
  37. Dim lParam As IntPtr = NativeMethods.CreateLWParam(ClickPoint.X,ClickPoint.Y) 'Click point.
  38.  
  39. If Button = MouseButtons.XButton1 OrElse _
  40. Button = MouseButtons.XButton2 Then
  41. wParam = NativeMethods.CreateLWParam(0,Button / MouseButtons.XButton1) 'Set the correct XButton.
  42. End If
  43.  
  44. NativeMethods.SendMessage(hWnd,ButtonMessage,wParam,lParam) 'Button down.
  45. NativeMethods.SendMessage(hWnd,ButtonMessage + 1,lParam) 'Button up.
  46. End Sub
  47. #End Region
  48. #End Region
  49.  
  50. #Region "NativeMethods"
  51. Private NotInheritable Class NativeMethods
  52. Private Sub New()
  53. End Sub
  54.  
  55. <DllImport("user32.dll",SetLastError:=True,CharSet:=CharSet.Auto)> _
  56. Public Shared Function SendMessage(ByVal hWnd As IntPtr,ByVal Msg As UInteger,ByVal wParam As IntPtr,ByVal lParam As IntPtr) As IntPtr
  57. End Function
  58.  
  59. <DllImport("user32.dll",SetLastError:=True)> _
  60. Public Shared Function WindowFromPoint(ByVal p As NATIVEPOINT) As IntPtr
  61. End Function
  62.  
  63. <DllImport("user32.dll",SetLastError:=True)> _
  64. Public Shared Function ScreenToClient(ByVal hWnd As IntPtr,ByRef lpPoint As NATIVEPOINT) As Boolean
  65. End Function
  66.  
  67. <StructLayout(Runtime.InteropServices.LayoutKind.Sequential)> _
  68. Public Structure NATIVEPOINT
  69. Public X As Integer
  70. Public Y As Integer
  71.  
  72. Public Sub New(ByVal X As Integer,ByVal Y As Integer)
  73. Me.X = X
  74. Me.Y = Y
  75. End Sub
  76. End Structure
  77.  
  78. Public Shared Function CreateLWParam(LoWord As Integer,HiWord As Integer) As IntPtr
  79. Return New IntPtr((HiWord << 16) Or (LoWord And &HFFFF))
  80. End Function
  81.  
  82. #Region "Enumerations"
  83. Public Enum MouseButtonMessages As Integer
  84. None = 0
  85. WM_LBUTTONDOWN = &H201
  86. WM_LBUTTONUP = &H202
  87. WM_MBUTTONDOWN = &H207
  88. WM_MBUTTONUP = &H208
  89. WM_RBUTTONDOWN = &H204
  90. WM_RBUTTONUP = &H205
  91. WM_XBUTTONDOWN = &H20B
  92. WM_XBUTTONUP = &H20C
  93. XBUTTON1 = &H1
  94. XBUTTON2 = &H2
  95. End Enum
  96. #End Region
  97. End Class
  98. #End Region
  99. End Class

现在在您的计时器中,您可以:

  1. Const KeyDownBit As Integer = &H8000
  2.  
  3. Private Sub Timer1_Tick(sender As Object,e As EventArgs) Handles Timer1.Tick
  4. If (GetAsyncKeyState(Keys.LButton) And KeyDownBit) = KeyDownBit Then
  5. MouseInputHelper.SendMouseClick(Windows.Forms.MouseButtons.Left,Cursor.Position)
  6. End If
  7. End Sub

希望这可以帮助!

猜你在找的VB相关文章