Learning
Learning

Reputation: 23

GetKeyState function not working when checking if left mouse button is clicked

I am trying to see if the left mouse button is clicked and if it is it will output You clicked I have this piece of code which will work the first time you click. After that though, I have to right click and then left click in order for it to work again. If I just left click nothing will happen. Why is this?

#include <iostream>
#include <windows.h>
using namespace std;

int main()
{
    while (true)
    {
        if (GetKeyState(VK_LBUTTON) < 0) {
            cout << "clicked" << endl;
        }
    }


}

Upvotes: 1

Views: 4426

Answers (2)

Rita Han
Rita Han

Reputation: 9710

After that though, I have to right click and then left click in order for it to work again. If I just left click nothing will happen. Why is this?

Yes, I can reproduce this issue when click on client area of the console window.

There is a console edit mode misleading us. When you click on client area of the console window, cause it enter edit mode and program stops. To solve this issue you can uncheck the "Quick Edit Mode" option (You can find it via click icon at left top of the console window then select Properties -> Options -> Edit Options), or click on title bar of the console window instead of on client area.

Please check if it is your situation.

enter image description here

Upvotes: 1

Remy Lebeau
Remy Lebeau

Reputation: 598011

GetKeyState() relies on the keyboard state of the calling thread, which is updated when the calling thread processes keyboard window messages, like WM_KEYDOWN and WM_KEYUP. But your loop does not process any messages at all, which is why GetKeyState() does not work. This is very clearly stated in the documentation:

The key status returned from this function changes as a thread reads key messages from its message queue. The status does not reflect the interrupt-level state associated with the hardware. Use the GetAsyncKeyState function to retrieve that information.

Also note the GetAsyncKeyState() documentation states:

The GetAsyncKeyState function works with mouse buttons. However, it checks on the state of the physical mouse buttons, not on the logical mouse buttons that the physical buttons are mapped to. For example, the call GetAsyncKeyState(VK_LBUTTON) always returns the state of the left physical mouse button, regardless of whether it is mapped to the left or right logical mouse button. You can determine the system's current mapping of physical mouse buttons to logical mouse buttons by calling GetSystemMetrics(SM_SWAPBUTTON), which returns TRUE if the mouse buttons have been swapped.

With that said, try this instead:

#include <iostream>
#include <windows.h>
using namespace std;

int main() {
    int vk = GetSystemMetrics(SM_SWAPBUTTON) ? VK_RBUTTON : VK_LBUTTON;
    while (true) {
        if (GetAsyncKeyState(vk) < 0) {
            cout << "clicked" << endl;
        }
    }
}

Upvotes: 1

Related Questions