Home > Software engineering >  How to distinguish a physical mouse click from a code one?
How to distinguish a physical mouse click from a code one?

Time:12-09

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. simple


For the autoClick methods, I used SendInput since mouse_event is obsolete (see Hans Passant comment on this interspersed

If you'd like to browse the full code or experiment with it, the full sample code is on GitHub.

  • Related