C считывает события клавиатуры

#c #winapi #keyboard

#c #winapi #клавиатура

Вопрос:

Я новичок в C и пытаюсь создать программу, которая считывает нажатия клавиш. Это созданная мной функция, которая ищет определенную клавишу.

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

Я знаю, что обнаружение клавиш работает, поскольку я поместил код, который просто печатает true или false внутри инструкции if, поэтому я знаю, что эта часть работает. Например, когда я набираю «s», выводится значение true, если я передаю код виртуальной клавиши 0x53 (код виртуальной клавиши для s). Как только я понял, что эта часть сработала, я попытался использовать функции MapVirtualKeyW и GeyKeyNameTextW для получения имени ключа, чтобы мне не приходилось жестко кодировать их все. Код компилируется, но останавливается сразу после печати Running....

Вот весь код

 #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) amp; 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;
}
  

диапазон 48-90 предназначен для всех буквенных и цифровых клавиш. Идея в том, что всякий раз, когда я нажимаю клавишу, она должна выводиться на консоль.

Я довольно уверен, что проблема в этом блоке кода

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

Любая помощь приветствуется!

Комментарии:

1. Кстати, if ((GetAsyncKeyState(vk) >> 15) amp; 1) также может быть записан как if (GetAsyncKeyState(vk) amp; 0x8000) или как if (GetAsyncKeyState(vk) < 0)

2. Кроме того, в диапазоне ASCII 48 .. 90 есть не только буквы и цифры, но и символы пунктуации. Буквы и цифры ASCII имеют те же числовые значения, что и соответствующие им коды виртуальных клавиш, но виртуальные клавиши в диапазоне ASCII 58-64 не определены, поэтому ваш цикл передает некоторые недопустимые виртуальные клавиши GetAsyncKeyState() .

Ответ №1:

В дополнение к комментариям выше, GetKeynameText требуется буфер для имени ключа, поэтому вместо:

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

вы хотите что-то вроде:

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

Вы также можете выполнить сброс wcout после записи в него.

Комментарии:

1. Обратите внимание, что последний параметр GetKeyNameText выражен в символах , а не в байтах, поэтому использование sizeof(key) само по себе неправильно при вызове версии Unicode. Вместо этого используйте _countof(key) или эквивалент.

2. Что делает его очистка, а также как вы получили размер 128?

3. Промывка wcout записывает все буферизованные символы, чтобы убедиться, что вы их видите. 128, я придумал. Это должно быть «достаточно долго».