Лучший способ получить ввод с клавиатуры с помощью Windows API? - PullRequest
0 голосов
/ 11 сентября 2018

В настоящее время я использую c ++ и Windows API для создания программы, которая требует ввода данных пользователем с клавиатуры.

Мое текущее решение работает, но я хотел спросить, есть ли лучший способ добиться того, чтоЯ пытаюсь это сделать.

Текущее решение:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){
    switch (message){
    case WM_CHAR:
        switch (wParam) {
        case 119:
            std::cout << "W" << std::endl;
            break;
        case 97:
            std::cout << "A" << std::endl;
            break;
        case 115:
            std::cout << "S" << std::endl;
            break;
        case 100:
            std::cout << "D" << std::endl;
            break;
        }
        break;
    return 0;
}

Если я хочу получить каждую клавишу на клавиатуре, мне придется сделать кейс для каждой клавиши.Есть ли лучший способ?

Кроме того, есть ли какие-либо ссылки в Интернете, где я могу получить код для каждого ключа?

Редактировать: Я хочу реализовать логику для каждого отдельного ключа.Должен был упомянуть, что в начале мои извинения.

Спасибо

1 Ответ

0 голосов
/ 11 сентября 2018

Если вы буквально просто хотели напечатать каждый ключ, Таблица ASCII, отображаемая непосредственно в этом случае , очевидным является наличие этого внутри case WM_CHAR: вместо целой секунды switch:

std::wcout << static_cast<wchar_t>(wParam) << std::endl;

В случае, если вы хотите иметь возможность определять отдельную, специфичную логику обработчика для каждого ключа, возможно, следующий пример будет лучшим шаблоном, поскольку он упростит логику вашего WndProc() и добавит уровень косвенности , что позволяет вам рассматривать обработчики как первоклассные объекты:

#include <iostream>
#include <functional>
#include <map>

#include <Windows.h>

std::map<uint32_t, std::function<void()>> gKeyCallback;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CHAR:
        auto mapIter = gKeyCallback.find(static_cast<uint32_t>(wParam));
        if (mapIter != gKeyCallback.end())
            mapIter->second();
        break;
    }
    return 0;
}

int main()
{
    gKeyCallback['W'] = [] {std::cout << "Handler for 'W'" << std::endl; };
    gKeyCallback['A'] = [] {std::cout << "Handler for 'A'" << std::endl; };
    gKeyCallback['S'] = [] {std::cout << "Handler for 'S'" << std::endl; };
    gKeyCallback['D'] = [] {std::cout << "Handler for 'D'" << std::endl; };

    return 0;
}

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

Эта строка:

std::map<uint32_t, std::function<void()>> gKeyCallback;

определяет контейнер сопоставления (a.k.a. словарь ). Он имеет тип type std::map, и здесь он обозначает сопоставление типа uint32_t с типом функции обратного вызова обработчика - в настоящее время является унифицированным обратным вызовом void().

Что делает эта строка:

gKeyCallback['W'] = [] {std::cout << "Handler for 'W'" << std::endl; };

- это значение ключа 119 (значение ASCII 'W') для конкретной логики, требуемой для него, указанной в {} ( фигурных скобках ). Ключевым синтаксическим элементом для этого здесь является []. Здесь вы можете прочитать все о том, как использовать это лямбда-выражение синтаксис .

Примечание: это определенно не рекомендация для использования глобальных переменных (gKeyCallback), это просто для полной простоты примера кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...