הערה
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות להיכנס או לשנות מדריכי כתובות.
הגישה לדף זה מחייבת הרשאה. באפשרותך לנסות לשנות מדריכי כתובות.
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.
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 :)