Sunday, May 12, 2013

How to send a click to a coordinate in an inactive program in vb.net

Today I'm writing down how to send a click to an exact coordinate in an inactive program in vb.net.  I used this in the iRazoo bot I just released.  I'm writing this down to remember this for the future and understand it better.  Before I begin, here are useful resources that helped teach me how to accomplish this:
To begin we need to make something that can grab the coordinates.  To do this add a textbox and set it to multiline and set the scrollbars property to vertical.  Then add a button and change it's text to find point.  Lastly, add a timer and set its interval to 1000.  With this all added you should now have the following:
What are we going to do with these three controls?  Well, on the button click we are going to enable timer1 if it's disabled and disable it if it's enabled with the following:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

If Timer1.Enabled = True Then

Timer1.Enabled = False

ElseIf Timer1.Enabled = False Then

Timer1.Enabled = True

End If

End Sub


Then on the timer1 tick event, we're going to add the coordinate of the cursor's position on the form to textbox1's text by doing:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick

TextBox1.Text = TextBox1.Text + vbNewLine + Me.Cursor.Position.ToString

End Sub


So now when you run you're app and click the button you should get something like this:

Now that we've got a way to find our coordinates we can make something to send a click to a certain coordinate.  First let's add something that we want to click to our form (like a button).  Then add a couple textboxes and another button underneath that.  Lastly, add another timer to the form and set it's interval for whatever time you'd like to wait before another click is sent (I set mine at 1000).  So now you're form should look something like this:
The first text box you added is for the x coordinate and the second is for the y coordinate.  The click point button will work the same way as the find point button and trigger timer2.  Before we code this and anything else though, let's paste the following below, Public Class Form1:
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _

Public Shared Function PostMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As Integer

End Function



<DllImport("user32.dll")> _

Shared Function WindowFromPoint(ByVal pnt As Point) As IntPtr

End Function

Private point As New Point
Private lButtonUp As UInteger = &H202
Private lButtonDown As UInteger = &H201

Private Function returnlParam(ByVal Lo As Short, ByVal Hi As Short) As IntPtr
Return CInt(Hi) << 16 Or Lo
End Function


  • The private var point is what we assign our textbox1's and textbox2's text too for our x and y.
  • The private var lButtonUp is a uint that contains the code for sending an on left mouse click up message.
  • The private var lButtonDown is a unit that contains the code for sending an on left mouse click down message.
With that done let's go back to our button2 (click point button) and add code to it's click event:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

point = New Point(TextBox2.Text, TextBox3.Text)



If Timer2.Enabled = True Then

Timer2.Enabled = False

ElseIf Timer2.Enabled = False Then
Timer2.Enabled = True
End If
End Sub

This first sets point equal two a new point with textbox2 as its x coord and textbox3 as its y coord and then does the same thing with timer2 that button1 does.  Okay almost done.  Now let's fill in the code for the timer2 tick event:
Private Sub Timer2_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer2.Tick
Dim hWnd As IntPtr
Dim wParam As IntPtr
Dim lParam As IntPtr

hWnd = WindowFromPoint(point)
wParam = CUInt(Keys.LButton)
lParam = returnlParam(point.X, point.Y)

PostMessage(hWnd, lButtonDown, wParam, lParam)
PostMessage(hWnd, lButtonUp, wParam, lParam)
End Sub


With Dim hWnd, wParam, and lParam you're just declaring the vars you'll be using for the PostMessage function.  Then we are assigning things to them.  hWnd will be getting the handle given off from the WindowFromPoint function.  wParam will be getting a uinteger data type of keys.LButton (which is the left mouse key).  lParam will be getting whatever is returned from the returnlParam function.  Then we use the postmessage function twice.  One time we use it with lButtonDown and the other with lButtonUp (simulating when you click the mouse down then let go of it).

Now if you run you're code, grab the point of the item you want to click, type in the coordinates, and hit the click point button it will send a click to the point you desire.  For all you botters out there, this might come in useful if you need to click something on a webbrowser (and can't figure out how normally;this way is kinda cheating).  Hope some of you find this interesting/useful.

btw if you want to just click a control and don't care what point it is you can always just use the control's handle.  So if I wanted to click button3 it would be:
PostMessage(button3.handle, lButtonDown, wParam, lParam)
PostMessage(button3.handle, lButtonUp, wParam, lParam)

You can download the complete project from here: http://www.mediafire.com/download.php?m5b4ht8j75n6j1l

No comments:

Post a Comment