Низкоуровневая клавиатура: различать коды клавиш

Я пытаюсь ограничить доступ пользователей моей программы к клавиатуре. Для этого я определил низкоуровневый хук клавиатуры:

LRESULT CALLBACK lowLevelKeyboardProc(int key, WPARAM wParam, LPARAM lParam)
{
KBDLLHOOKSTRUCT* pkbhs = (KBDLLHOOKSTRUCT*)lParam;

switch (key)
{
case HC_ACTION:
....

и подключил это:

m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)lowLevelKeyboardProc, 0, 0);

Мне нужно, чтобы пользователи могли использовать только буквенно-цифровые символы, ~, @, # … только те символы, которые могут быть в пароле (печатные символы).
Какой самый простой способ провести различие между этими символами и всеми остальными, используя параметры хуков клавиатуры низкого уровня: клавиша int, WPARAM wParam, LPARAM lParam?

Программа написана на C ++ и скомпилирована в VC2010.

Вся помощь приветствуется!

0

Решение

Прежде чем ответить на ваш вопрос, у меня есть пара вопросов к вам:

  1. Почему вы хотите это сделать глобально, используя глобальную низкоуровневую клавиатуру?

    Хотя иногда они являются единственным способом решения проблемы, использование таких глобальных хуков обычно не рекомендуется по многим причинам. Есть много лучших способов предотвратить ввод пользователем недопустимых или недопустимых данных. Например, я бы просто отключил ненужные клавиши для определенного элемента управления или набора элементов управления (например, для всех текстовых полей). Таким образом, пользователь все еще может использовать сочетания клавиш и другие не алфавитно-цифровые клавиши для взаимодействия с вашим приложением, что очень важно для обеспечения доступности. Помните, что глобальный хук повлияет все из других потоков, запущенных на машине, а не только в вашем приложении — это, вероятно, не то, что вы хотите.

  2. Даже если ты делать решите использовать глобальный хук, вы уверены, что вы действительно нужно отключить все не алфавитно-цифровые ключи? Как насчет Backspace и Delete? Разве пользователь не должен иметь возможность удалять вещи? А как насчет Tab? Войти? А как насчет клавиш-модификаторов, таких как Shift, Ctrl и Alt: они разрешены?

пожалуйста шутки в сторону Прежде чем продолжить работу с этим дизайном, пересмотрите, действительно ли вам нужен крючок низкого уровня. Если вам нужна помощь в разработке другого решения, задайте новый вопрос, описывающий, чего вы хотите достичь (например, Я хочу запретить пользователям вводить любые не буквенно-цифровые символы в элемент управления текстового поля; вот код, который я использую для создания моего текстового поля …).

Но если вы настаиваете на игнорировании моего совета, решение довольно простое: исследуйте членов KBDLLHOOKSTRUCT состав это передается в процедуру подключения. vkCode член дает вам код виртуального ключа клавиши, которая была нажата. Скорее всего, это вся информация, которая вам нужна. Но на всякий случай код аппаратного сканирования ключа также указан в scanCode член.

К сожалению, код, который у вас есть, неверен. Первый параметр в процедуре обратного вызова ловушки действительно int, но это не ключевой код. Скорее, это код, который сигнализирует, как процедура ловушки должна обрабатывать сообщение. Используйте это так:

LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// If nCode is greater than or equal to HC_ACTION, process the message.
if (nCode >= HC_ACTION)
{
KBDLLHOOKSTRUCT* pkbhs = reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);

// Handle the keys as you wish here.
//
// Remember that pkbhs->vkCode gives you the virtual key code
// of the key that was pressed.
//
// To prevent a particular key from being processed, you should
// return a non-zero value (e.g. 1) immediately.
}

// Pass the message on.
return CallNextHookEx(m_hHook, nCode, wParam, lParam);
}

И когда вы устанавливаете ловушку, совершенно не нужно приводить указатель на функцию. Подобные бессмысленные приведения просто скрывают потенциальные ошибки во время компиляции, приводящие к сбою во время выполнения. Напишите это просто:

m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, lowLevelKeyboardProc, 0, 0);
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]