שתף באמצעות


How to click on a specific coordinate of the screen and keep the click pressed

Question

Monday, September 10, 2018 1:46 AM

Basically, I need a timer that clicks on a specific coordinate of the screen for two or three seconds, and then lets go.

All replies (10)

Tuesday, September 11, 2018 5:02 PM ✅Answered

 I have another example at the link below of using the SendInput function to simulate mouse movements/clicking and keyboard keys being pressed/released.  You would just need to simulate the mouse button being pressed down,  then start a Timer with a 2/3 second interval,  and in the Timer's Tick event you first stop the timer and then simulate the mouse button being released.

https://social.msdn.microsoft.com/Forums/vstudio/en-US/80bb4cc8-0b4d-469b-a106-923c870157c0/help-performing-keyboard-events?forum=vbgeneral

 

 There is also the mouse_event function which has been superseded by the SendInput function but,  the mouse_event function can still be used.  Below is an example you can test in a new form project with 1 Button added to the form.  When you click the button,  it moves the cursor to the form's title area and presses the left mouse button down,  then it starts a 3 second timer.  Finally,  in the timer's Tick event,  I stop the timer, move the cursor (drag the form) to the top left corner of the screen.

Imports System.Runtime.InteropServices

Public Class Form1
    Private WithEvents HoldTimer As New Timer

    Private Const MOUSEEVENTF_LEFTDOWN As Integer = &H2
    Private Const MOUSEEVENTF_LEFTUP As Integer = &H4

    <DllImport("user32.dll")>
    Private Shared Sub mouse_event(ByVal dwFlags As UInteger, ByVal dx As Integer, ByVal dy As Integer, ByVal dwData As Integer, ByVal dwExtraInfo As UInteger)
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Cursor.Position = New Point(Me.Left + 40, Me.Top + 10) 'move cursor to title area of this form
        mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) 'press down left mouse button
        HoldTimer.Interval = 3000 '3000 milliseconds = 3 seconds
        HoldTimer.Start()
    End Sub

    Private Sub HoldTimer_Tick(sender As Object, e As EventArgs) Handles HoldTimer.Tick
        HoldTimer.Stop()
        Cursor.Position = New Point(40, 10) 'moves the cursor and drags the form to top left of screen
        mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) 'release left mouse button
    End Sub
End Class

If you say it can`t be done then i`ll try it


Monday, September 10, 2018 3:28 AM

Hi,

You can place a PictureBox control in the specified area and then set the Click event of the PictureBox.

Imports System.Drawing.Drawing2D

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    End Sub

    Private Sub PictureBox1_Click(sender As Object, e As EventArgs) Handles PictureBox1.Click
        Dim t As New Timer With {.Interval = 2000, .Enabled = True}
        AddHandler t.Tick, Sub()
                               PictureBox1.BackColor = Color.Black
                               t.Stop()
                               PictureBox1.BackColor = Color.Transparent
                           End Sub
        PictureBox1.BackColor = Color.Black
    End Sub
End Class

Best Regards,

Alex

MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


Monday, September 10, 2018 2:51 PM

I'm not sure how this is supposed to achieve what I want, but it isn't. 

I need to set a coordinate of my screen, and simulate a click there that keeps the key pressed for two seconds. Using the code you gave me doesn't do any of that.


Monday, September 10, 2018 3:03 PM

I'm not sure how this is supposed to achieve what I want, but it isn't. 

I need to set a coordinate of my screen, and simulate a click there that keeps the key pressed for two seconds. Using the code you gave me doesn't do any of that.

What do you expect to happen with "keep click pressed?"

I don't think that is how windows works. There is a click event, a mouse down, mouse move, mouse up, key pressed events but no keep click pressed event.

What is it exactly you want to do?


Monday, September 10, 2018 3:52 PM

Well, when you keep the click pressed with your mouse, windows definitely recognizes it, right? For example, you select a piece of text by clicking, keeping the click pressed, and dragging it down to select the text.

I want to do that on a specific coordinate, and then let go after two seconds.


Monday, September 10, 2018 4:41 PM

Assuming that the click-point is outside of your VB application's main window, you'll need to use Win32 API calls to automate the mouse.  This is not a trivial task if you are unfamiliar with unmanaged COM interop (though it is trivial if you are accustomed to unmanaged COM).

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Monday, September 10, 2018 4:52 PM

Well, when you keep the click pressed with your mouse, windows definitely recognizes it, right? For example, you select a piece of text by clicking, keeping the click pressed, and dragging it down to select the text.

I want to do that on a specific coordinate, and then let go after two seconds.

Weeksky,

There is mouse down, mouse move, mouse up events. There is no wait two seconds then mouse up event. There is mouse down, wait two seconds, and mouse up?

There are drag events like DragOver, Drag Drop etc.

/en-us/dotnet/api/system.windows.dragdrop?redirectedfrom=MSDN&view=netframework-4.7.2

I ask again. What is it you want to do exactly and why? Why are you attempting things that are outside of your own application if that is what you mean?


Monday, September 10, 2018 5:41 PM | 2 votes

You can simulate clicks with SendInput

The time member from MOUSEINPUT  is the Tick count, not the duration, so you can use Sleep() to wait, although I don't see the purpose...

For example, this sample right-clicks down at 50, 10, waits 2 seconds, then right-clicks up 

(I tested with desktop visible and an icon at this position to get the context menu displayed by the right-click)

=>

Dim nX, nY, nXMove, nYMove As Integer
nXMove = 50
nYMove = 10
Dim nScreenWidth As Integer = GetSystemMetrics(SM_CXVIRTUALSCREEN)
Dim nScreenHeight As Integer = GetSystemMetrics(SM_CYVIRTUALSCREEN)
Dim nScreenLeft As Integer = GetSystemMetrics(SM_XVIRTUALSCREEN)
Dim nScreenTop As Integer = GetSystemMetrics(SM_YVIRTUALSCREEN)
nX = ((nXMove - nScreenLeft) * 65536) / nScreenWidth + 65536 / (nScreenWidth)
nY = ((nYMove - nScreenTop) * 65536) / nScreenHeight + 65536 / (nScreenHeight)

Dim currentInput As INPUT() = New INPUT(0) {}
currentInput(0).type = INPUT_MOUSE
currentInput(0).union.mi.dx = nX
currentInput(0).union.mi.dy = nY
currentInput(0).union.mi.dwFlags = MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_MOVE
SendInput(1, currentInput, Marshal.SizeOf(currentInput(0)))

currentInput(0).union.mi.dwFlags = MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_RIGHTDOWN
SendInput(1, currentInput, Marshal.SizeOf(currentInput(0)))
System.Threading.Thread.Sleep(2000)

currentInput(0).union.mi.dwFlags = MOUSEEVENTF_ABSOLUTE Or MOUSEEVENTF_RIGHTUP
SendInput(1, currentInput, Marshal.SizeOf(currentInput(0)))

Declarations :

Public Const KEYEVENTF_KEYDOWN As Integer = &H0
Public Const KEYEVENTF_EXTENDEDKEY As Integer = &H1
Public Const KEYEVENTF_KEYUP As Integer = &H2

Public Const KEYEVENTF_UNICODE As Integer = &H4
Public Const KEYEVENTF_SCANCODE As Integer = &H8

<StructLayout(LayoutKind.Sequential)>
Public Structure INPUT
    Public type As Integer
    Public union As INPUTUNION
End Structure

<StructLayout(LayoutKind.Explicit)>
Public Structure INPUTUNION
    <FieldOffset(0)>
    Public mi As MOUSEINPUT
    <FieldOffset(0)>
    Public ki As KEYBDINPUT
    '<FieldOffset(0)>
    'Public hi As HARDWAREINPUT
End Structure

<StructLayout(LayoutKind.Sequential)>
Public Structure MOUSEINPUT
    Public dx As Integer
    Public dy As Integer
    Public mouseData As Integer
    Public dwFlags As Integer
    Public time As Integer
    Public dwExtraInfo As IntPtr
End Structure

<StructLayout(LayoutKind.Sequential)>
Public Structure KEYBDINPUT
    Public wVk As Short
    Public wScan As Short
    Public dwFlags As Integer
    Public time As Integer
    Public dwExtraInfo As IntPtr
End Structure

Public Const INPUT_MOUSE As Integer = 0
Public Const INPUT_KEYBOARD As Integer = 1
<DllImport("User32.dll", SetLastError:=True)>
Public Shared Function SendInput(ByVal nInputs As Integer, <MarshalAs(UnmanagedType.LPArray)> ByVal pInputs() As INPUT, ByVal cbSize As Integer) As Integer
End Function

<DllImport("user32.dll", ExactSpelling:=True, CharSet:=CharSet.Auto)>
Public Shared Function GetSystemMetrics(nIndex As Integer) As Integer
End Function

Public Const SM_XVIRTUALSCREEN As Integer = 76
Public Const SM_YVIRTUALSCREEN As Integer = 77
Public Const SM_CXVIRTUALSCREEN As Integer = 78
Public Const SM_CYVIRTUALSCREEN As Integer = 79

Public Const MOUSEEVENTF_MOVE As Integer = &H1
Public Const MOUSEEVENTF_LEFTDOWN As Integer = &H2
Public Const MOUSEEVENTF_LEFTUP As Integer = &H4
Public Const MOUSEEVENTF_RIGHTDOWN As Integer = &H8
Public Const MOUSEEVENTF_RIGHTUP As Integer = &H10

Public Const MOUSEEVENTF_ABSOLUTE As Integer = &H8000

Tuesday, September 11, 2018 10:19 PM

Here's a third option: SendMessage:

Private Const WM_LBUTTONDOWN = &H201
Private Const WM_LBUTTONUP = &H202

Private Declare Auto Function SendMessage Lib "User32.dll" (ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

Public Shared Sub MouseLeftClickAt(handle As IntPtr, x As Integer, y As Integer)
    Dim clickPoint = CType((y << 16) Or (x And &HFFFF), IntPtr)
    SendMessage(handle, WM_LBUTTONDOWN, CType(1, IntPtr), clickPoint)
    SendMessage(handle, WM_LBUTTONUP, CType(0, IntPtr), clickPoint)
End Sub

Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


Wednesday, September 12, 2018 3:04 AM

Thank you all so much!! Your answer worked best, but I appreciate every input :)