Ответ 1
Это действительно длинный ответ на ваш комментарий выше, но вставляя его в ответ, потому что он слишком длинный для комментария:)
Основная проблема для понимания здесь заключается в том, что ключи и символы не совсем то же самое. Некоторые (но не все) ключи генерируют символы; некоторые клавиши генерируют разные символы в зависимости от сдвига или другого состояния клавиатуры. И для реализации редактора вам необходимо обрабатывать как текстовый ввод, так и нетекстовый ввод клавиатуры, например, клавиши со стрелками. Теперь длинная версия, отбирающая из чего-то неправильное предположение:
Видимо, окна работают по-настоящему странно. [...] Кажется, что когда вы нажимаете [shift] +9, окна отправляют VK_LEFT в wParam сообщения WM_CHAR
Похоже, вы можете смешивать две вещи здесь. Вещь с WM_CHAR заключается в том, что она дает вам коды символов для текстовых символов: поэтому, если кто-то нажимает клавишу 9, вы получите "9". Если кто-то нажал SHIFT + 9, Windows примет во внимание состояние переключения - и вы получите '(' (если используете клавиатуру США). Но вы никогда не получите WM_CHAR для клавиш со стрелками, HOME, END и т.д. поскольку они не являются текстовыми символами. С другой стороны, WM_KEYDOWN не обрабатывается символами, а в кодах VK_, поэтому нажатие 9 дает вам VK_9 независимо от состояния сдвига, а стрелка влево дает вам VK_LEFT - снова рассматривает состояние сдвига.
Дело в том, что WM_CHAR и WM_KEYDOWN дают вам две части общего входного изображения - но вам действительно нужно обрабатывать оба изображения, чтобы получить полную картину. И имейте в виду, что wParam - это совсем другое дело в обоих случаях. Это код символа для WM_CHAR, но код VK_ для WM_KEYDOWN. Не смешивайте их.
И чтобы сделать вещи более запутанными, значения VK_ имеют те же значения, что и допустимые символы. Откройте WinUser.h(он входит в каталог include в каталоге установки компилятора) и найдите VK_LEFT:
#define VK_LEFT 0x25
Оказывается, что 0x25 также является кодом для символа "%" (подробности см. в любой таблице ascii/unicode). Поэтому, если WM_CHAR получает 0x25, это означает, что shift-5 был нажат (при условии, что клавиатура США) создает "%"; но если WM_KEYDOWN получает 0x25, это означает, что нажата стрелка влево (VK_LEFT). И чтобы добавить немного больше путаницы, коды виртуального ключа для клавиш AZ и клавиш 0-9 оказались такими же, как символы "A" - "Z" и "0" - "9", что делает его похожим на символы и VK_ взаимозаменяемы. Но это не так: код для нижнего регистра "a", 0x61, - VK_NUMPAD1! (Таким образом, получение 0x61 в WM_CHAR означает "a", получение его в WM_KEYDOWN означает NUMPAD 1. И если пользователь нажимает клавишу "A" в состоянии без сдвига, то вы фактически получаете VK_A (то же значение, что и "A" ) в WM_KEYDOWN, который переводится в WM_CHAR из 'a'.)
Таким образом, связывая все это вместе, типичным способом обработки клавиатуры является использование всего следующего:
-
Используйте WM_CHAR для обработки текстового ввода: фактические текстовые клавиши. wParam - это символ, который вы хотите добавить в свою строку, или сделать что-нибудь еще. Это делает всю обработку сдвига для вас.
-
Используйте WM_KEYDOWN для обработки "мета" ключей - например, клавиш со стрелками, дома, конца, страницы и т.д. Передайте все значения A-Z/0-9, обработка по умолчанию превратит их в WM_CHAR, которые вы можете обрабатывать в вашем обработчике WM_CHAR. (Здесь вы также можете обрабатывать клавиши numpad, если вы хотите использовать их для специальных функций, иначе они "проваливаются", чтобы заканчиваться как числовые WM_CHAR, в зависимости от состояния numlock. Windows заботится об этом, точно так же, как обрабатывает состояние сдвига для алфавитные клавиши.)
-
Если вы хотите явно обрабатывать ALT-комбо (вместо использования таблицы ускорителей), вы получите их через WM_SYSKEYDOWN.
Я думаю, что есть некоторые ключи, которые могут отображаться в обоих - Enter может отображаться как WM_KEYDOWN из VK_RETURN, так и как \r или\n WM_CHAR, но я предпочитаю обрабатывать его в WM_KEYDOWN, чтобы редактировать управление ключами отдельно от текстовых клавиш.