#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, я придумал. Это должно быть «достаточно долго».