Search code examples
c++winapikeyboard

C++ read keyboard events


I am new to C++ and I am trying to make a program that reads keystrokes. This is a function I made that looks for a certain key.

void printKey(short vk)
{
    if ((GetAsyncKeyState(vk) >> 15) & 1)
    {
        LPWSTR key;
        GetKeyNameTextW(MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) << 16, key, sizeof(key));
        wcout << key;
    }
}

I know that the key detection works as I have put code that just prints true or false inside of the if statement so I know that that part is working. For example when I type "s" it prints true if I pass in the virtual key code 0x53 (virtual key code for s). Once I knew that part worked I tried to use the MapVirtualKeyW and GeyKeyNameTextW functions to get the name of the key so I wouldn't have to hard code all of them in. The code compiles but stops immediately after printing Running....

Here is the whole code

#include <iostream>
#include <Windows.h>

#pragma comment(lib, "User32.lib")

using std::cout;
using std::endl;
using std::wcout;

void printKey(short vk)
{
    if ((GetAsyncKeyState(vk) >> 15) & 1)
    {
        LPWSTR key;
        GetKeyNameTextW(MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) << 16, key, sizeof(key));
        wcout << key;
    }
}

int main()
{
    cout << "Running...." << endl;

    while (true)
    {
        for (int i = 48; i <= 90; i++)
        {
            printKey(i);
        }
    }

    return 0;
}

the range 48-90 is for all the letter and number keys. The idea is that whenever I press a key it should print to the console.

I am fairly confident the issue is in this block of code

LPWSTR key;
GetKeyNameTextW(MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) << 16, key, sizeof(key));
wcout << key;

Any help is appreciated!


Solution

  • In addition to the comments above, GetKeynameText needs a buffer for the key name, so instead of:

    LPWSTR key;
    GetKeyNameTextW(MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) << 16, key, sizeof(key));
    

    you want something like:

    WCHAR key [128];
    GetKeyNameTextW(MapVirtualKeyW(vk, MAPVK_VK_TO_CHAR) << 16, key, sizeof(key) / sizeof (WCHAR));
    

    You might also flush wcout after writing to it.