Это действительно длинный ответ на ваш комментарий выше, но помещать его в ответ, потому что он слишком длинный для комментария:)
Основная проблема, которую необходимо понять, заключается в том, что ключи и символы не совсем одно и то же. Некоторые (но не все) ключи генерируют символы; некоторые клавиши генерируют разные символы в зависимости от смещения или другого состояния клавиатуры. А для реализации редактора вам необходимо обрабатывать как текстовый, так и нетекстовый ввод с клавиатуры, например клавиши со стрелками. Теперь длинная версия, основанная на неверном предположении:
По-видимому, Windows работает очень странным образом. [...] Кажется, что когда вы нажимаете [shift] +9, Windows отправляет 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 означает NUMPAD1. И если пользователь нажимает клавишу «A» в несмещенном состоянии, то, что вы на самом деле получаете, это сначала VK_A (то же значение, что и «A») в WM_KEYDOWN, который переводится в WM_CHAR 'a'.)
Таким образом, связывая все это вместе, типичный способ работы с клавиатурой - использовать все следующее:
Используйте WM_CHAR для обработки текстового ввода: фактические текстовые клавиши. wParam - это символ, который вы хотите добавить в свою строку или сделать с ним что угодно. Это сделает всю сменную обработку за вас.
Используйте WM_KEYDOWN для обработки мета-клавиш - таких как клавиши со стрелками, home, end, page up и так далее. Пропустите все значения A-Z / 0-9, обработка по умолчанию превратит их в WM_CHAR, которые вы можете обработать в своем обработчике WM_CHAR. (Вы также можете обрабатывать цифровые клавиши здесь, если хотите использовать их для специальных функций; в противном случае они «проваливаются», превращаясь в числовые WM_CHAR, в зависимости от состояния numlock. Windows заботится об этом так же, как обрабатывает состояние сдвига для буквенные клавиши.)
Если вы хотите работать с ALT-комбинациями явно (а не с таблицей ускорений), вы получите их через WM_SYSKEYDOWN.
Я думаю, что есть некоторые ключи, которые могут отображаться в обоих - Enter может отображаться как WM_KEYDOWN из VK_RETURN и как \ r или \ n WM_CHAR - но я бы предпочел обрабатывать его в WM_KEYDOWN, чтобы продолжить редактирование обработка ключей отдельно от текстовых ключей.