How to stop LMB clicker on physical release LMB

Hello, I want to create a clicker. I have a hotkey (R+LMB to start loop, release R and still hold LMB to clicks spam) but I dont know how to pause this loop on LMB release.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  void click::press()
{
    INPUT    Input={0};

    static long xPos = 0, yPos= 0;
    if(GetAsyncKeyState(0x52) & 0x8000 && GetAsyncKeyState(0x01) & 0x8000)
    {
        clickerActive = true;
        qDebug() << clickerActive << "ON";
        while (clickerActive)
        {
            if(GetAsyncKeyState(0x01) == 0)
            {
                qDebug () << "disabled";
                clickerActive = false;
            }
            else
            {
                mouse_event(MOUSEEVENTF_LEFTDOWN, xPos, yPos, 0, 0);
                mouse_event(MOUSEEVENTF_LEFTUP, xPos, yPos, 0, 0);

                qDebug() << "Click";
            }
            Sleep(1000);
        }
    }
}


In future I want to add async because my GUI is not responding.

Really need help, Im stuck here.
Last edited on
Just a guess, but for line 12 above try:

 
if (GetAsyncKeyState(0x01) & 0x8000)

The documentation suggests that the low-order bit could possibly be set (and that it's basically useless), so you need to ignore it the same way you do in the other tests.
Last edited on
Like this?
1
2
3
    if(GetAsyncKeyState(0x52) && GetAsyncKeyState(0x01))

    if(!GetAsyncKeyState(0x01))


Still not pausing :/
No, do it exactly as you were before, but do the same for the if on line 12, too. Like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void click::press()
{
    INPUT    Input={0};

    static long xPos = 0, yPos= 0;
    if(GetAsyncKeyState(0x52) & 0x8000 && GetAsyncKeyState(0x01) & 0x8000)
    {
        clickerActive = true;
        qDebug() << clickerActive << "ON";
        while (clickerActive)
        {
            if (GetAsyncKeyState(0x01) & 0x8000)
            {
                qDebug () << "disabled";
                clickerActive = false;
            }
            else
            {
                mouse_event(MOUSEEVENTF_LEFTDOWN, xPos, yPos, 0, 0);
                mouse_event(MOUSEEVENTF_LEFTUP, xPos, yPos, 0, 0);

                qDebug() << "Click";
            }
            Sleep(1000);
        }
    }
}

But it's just a guess, since I don't actually use windows at the moment.
It's now work like "disable when pressed", I want to disable when released.
Then try:
 
if ( ! (GetAsyncKeyState(0x01) & 0x8000) )

Now It's clicked one time, and
 
qDebug () << "disabled";
Then I'm out of ideas. Maybe someone else can help.
Maybe u know sth about async? My GUI wont load (not responding).
@bump
Maybe u know sth about async? My GUI wont load (not responding).
Do not start a loop. Instead start a timer.

- When r+l are pressed set a bool to true.
- When the bool is true and just l is down start the timer.
- When both r+l are released set the bool to false and stop the timer.

For timer see:

https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-settimer
Ok I have sth like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
    static long xPos = 0, yPos= 0;

    bool rLMB = false;
    if(GetAsyncKeyState(0x52) && GetAsyncKeyState(0x01))
    {
        rLMB = true;
    }
    if(GetAsyncKeyState(0x01) == 0)
    {
        rLMB = false;
        qDebug() << "released";
    }
    while(rLMB && GetAsyncKeyState(0x01))
    {
        qDebug() << "CLicked";
        Sleep(500);
    }

}

But if I add
1
2
        mouse_event(MOUSEEVENTF_LEFTDOWN, xPos, yPos, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, xPos, yPos, 0, 0);

on
1
2
3
4
5
    while(rLMB && GetAsyncKeyState(0x01))
    {
        qDebug() << "CLicked";
        Sleep(500);
    }

my function dont know when I release the LMB.

Are there any differences between real mouse clicks and virtual mouse clicks?
Last edited on
bump
The point is that within that while loop you block the message handling. So when blocking the event handling you don't get any messages anymore.

You should handle the [real] mouse click events in the main message loop not the timer. In the timer you just emit the fake mouse clicks without loop and Sleep.
But still have to use
1
2
while(true){
}


loop?

This laggy my program and that's why I need async.

bump
bump
It should be easier than you think it is.

In your main event handler you do this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void click::press()
{
    static bool rLMB = false; // Note: static
    if(GetAsyncKeyState(0x52) && GetAsyncKeyState(0x01))
    {
        if(not rLMB)
          StartTimer(...);
    }
    if(GetAsyncKeyState(0x01) == 0)
    {
        if(rLMB)
        {
          rLMB = false;
          KillTimer(...);
        }
    }
}


In your timer handler just this:
1
2
3
4
5
void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
        mouse_event(MOUSEEVENTF_LEFTDOWN, xPos, yPos, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, xPos, yPos, 0, 0);
}
But still have to use "while" loop to check "press" function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
        mouse_event(MOUSEEVENTF_LEFTDOWN, xPos, yPos, 0, 0);
        mouse_event(MOUSEEVENTF_LEFTUP, xPos, yPos, 0, 0);
}

void press()
{
    qDebug() << "press work";

    static bool rLMB = false; // Note: static
    if(GetAsyncKeyState(0x52) && GetAsyncKeyState(0x01))
    {
        qDebug() << "if(GetAsyncKeyState(0x52) && GetAsyncKeyState(0x01))";
        if(!rLMB)
          {
          qDebug() << "if(not rLMB)";
          SetTimer(NULL, 1, 3000, &TimerProc); // This SetTimer dont start Timer.
          }
    }
    if(GetAsyncKeyState(0x01) == 0)
    {
        qDebug() << "if(GetAsyncKeyState(0x01) == 0)";
        if(rLMB)
        {
          qDebug() << "if(rLMB)";
          rLMB = false;
          KillTimer(NULL, 1);
        }
    }
}



In Main

1
2
3
4
5
    while(true)
    {
        press();
        Sleep(1000);
    }


Lol, solved.

The problem is
 
mouse_event(MOUSEEVENTF_LEFTUP, xPos, yPos, 0, 0);
Last edited on
Topic archived. No new replies allowed.