I'm writing an autoclicker right now. I have a very difficult problem to solve at my level of knowledge. I have low level hooks to detect Mouse KeyDown & KeyUp.
private bool LeftButtonStatus;
private void AutoClicker_Load(object sender, EventArgs e)
{
core.mouseHook.LeftButtonDown = new MouseHook.MouseHookCallback(mouseHook_LeftKeyDown);
core.mouseHook.LeftButtonUp = new MouseHook.MouseHookCallback(mouseHook_LeftKeyUp);
}
private void mouseHook_LeftKeyDown(MouseHook.MSLLHOOKSTRUCT ma)
{
LeftButtonStatus = true;
StartClicking();
}
private void mouseHook_LeftKeyUp(KeyboardHook.VKeys key)
{
LeftButtonStatus = false;
StartClicking();
}
private void StartClicking()
{
if (LeftButtonStatus)
LeftButtonTimer.Start();
else
LeftButtonTimer.Stop();
}
private void LeftButtonTimer_Tick(object sender, EventArgs e)
{
Core.LeftClick();
}
My click method in the Core
class looks like this:
[DllImport("user32.dll")]
private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo);
public static void LeftClick()
{
mouse_event(((int)KeyStates.LeftDown) | ((int)KeyStates.LeftDown), 0, 0, 0, 0);
}
The problem is that when I call Core.LeftClick();
my hooks detect it
and stops the Timer.
How to do I make sure Core.LeftClick();
is ignored by the mouseHook_LeftKeyUp
and mouseHook_LeftKeyDown
methods?
CodePudding user response:
You could use a flag in your own code where you set ignore = true
in LeftClick()
and check if (ignore == true)
in your hook methods. But the problem there is you open yourself up to a race condition where a user-generated click could be processed between the time that it's set to true
and when your hook is run, which would lead to a user-generated click being ignored.
A better way would be to use the dwExtraInfo
parameter of mouse_event
.
For the autoClick methods, I used SendInput
since mouse_event
is obsolete (see Hans Passant comment on this
If you'd like to browse the full code or experiment with it, the full sample code is on GitHub.