Introduction
There are some computer games or applications where you need to repeatedly click on the same place on the screen many times. Imagine a game where you chop down a tree by clicking on it. Then a next tree appears on the same spot, so after a while, you need to click there again.
As we are human beings, we like to simplify boring tasks. As programmers, we can simplify this task by creating software to do it for us.
The Coding
What do we need to do in the autoclicker? To keep things simple, we only set two things: where to click and how often to click. The point where to click can be stored in a variable of type Point
, the interval will be set on our Timer
.
The first thing to do is to create a new Windows Form. Then we add our variable to hold the click location.
Point clickLocation = new Point(0,0);
Next, we need to set the location for our clicking. One of the ways to do this is to start a countdown. While it is running, the user can point the mouse to the desired position and after the countdown ends, we get its coordinates.
We can do this by activating appropriately long timeout (for example 5 seconds) and then collecting the mouse location. So, we can add a button with following OnClick
event handler:
private void btnSetPoint_Click(object sender, EventArgs e)
{
timerPoint.Interval = 5000;
timerPoint.Start();
}
We also create a timer to help us get the mouse location. We can get the mouse location from the Position
property of the Cursor
class. The set location can be displayed for example on the window title.
So, let's create the second timer and add the following Tick
handler to it:
private void timerPoint_Tick(object sender, EventArgs e)
{
clickLocation = Cursor.Position;
this.Text = "autoclicker " + clickLocation.ToString();
timerPoint.Stop();
}
Now we want to set the main timer interval (we can use the NumericUpDown
control). Remember that the lower bound of its interval should be greater than zero, as we cannot set the timer interval to zero milliseconds.
Now to the clicking itself. In each time our main timer elapses (add another Timer
control to the form), we want to click on a specified position. We cannot do this in pure managed code, we must use the import method SendInput
of the user32.dll library. We will use it to synthesize the mouse click. Don't forget to place using System.Runtime.InteropServices;
to the beginning of your code when you use DllImport
.
[DllImport("User32.dll", SetLastError = true)]
public static extern int SendInput(int nInputs, ref INPUT pInputs,
int cbSize);
The method SendInput
uses three parameters:
nInputs
specifies how many structures pInputs
points to
pInputs
is a reference to an array of INPUT structures
cbSize
is the size of INPUT structure
To keep things simple, we will use only one INPUT
structure. We will need to define this structure and some constants too:
const int MOUSEEVENTF_LEFTDOWN = 2;
const int MOUSEEVENTF_LEFTUP = 4;
const int INPUT_MOUSE = 0;
public struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
public struct INPUT
{
public uint type;
public MOUSEINPUT mi;
};
Each time our timer elapses, we want to click. We do it by moving the cursor to the memorized place, then setting up the INPUT
structure and filling it with required values. Each click consists of pressing mouse button and releasing mouse button, so we need to send two messages - one for button down (press) and another for button up (release).
So add a handle to the Tick
event of the main timer with this code:
private void timer1_Tick(object sender, EventArgs e)
{
Cursor.Position = clickLocation;
INPUT i = new INPUT();
i.type = INPUT_MOUSE;
i.mi.dx = 0;
i.mi.dy = 0;
i.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
i.mi.dwExtraInfo = IntPtr.Zero;
i.mi.mouseData = 0;
i.mi.time = 0;
SendInput(1, ref i, Marshal.SizeOf(i));
i.mi.dwFlags = MOUSEEVENTF_LEFTUP;
SendInput(1, ref i, Marshal.SizeOf(i));
}
Finally - we can use a button to start/stop the autoclicking feature. Let's create a button with the following handler:
private void btnStart_Click(object sender, EventArgs e)
{
timer1.Interval = (int)numericUpDown1.Value;
if (!timer1.Enabled)
{
timer1.Start();
this.Text = "autoclicker - started";
}
else
{
timer1.Stop();
this.Text = "autoclicker - stopped";
}
}
Further Steps
That's it. It's quite simple. How can we further improve this program?
We could...
- use random intervals of clicking
- add random movements with the mouse, then return to the point where we click
- move the mouse while "holding" down the button
- capture what is displayed on the screen and click on a specific colour
- click on sequence of points (create some kind of macros)
History
- 30th August, 2006: Initial post