Почему MapVirtualKey не возвращает флаг расширенного ключа?

Я пытаюсь синтезировать нажатия клавиш с помощью PostMessage(), и мне нужно сгенерировать соответствующие lParam.

Я знаком со структурой KeyStrokeMessage.

Вот код:

///-------------------------------------------------------------------------------------------
/// KeystrokeMessage/KeyLParam struct
///-------------------------------------------------------------------------------------------
typedef struct KeystrokeMessage
{
    unsigned RepeatCount            : 16;
    unsigned ScanCode               : 8;
    unsigned ExtendedFlag           : 1;
    unsigned Reserved               : 4;
    unsigned ContextCode            : 1;
    unsigned PreviousKeyState       : 1;
    unsigned TransitionState        : 1;
} KeyLParam;


///-------------------------------------------------------------------------------------------
/// GetKeyMessageLPARAM:
///     Creates an LPARAM for key messages.
///-------------------------------------------------------------------------------------------
LPARAM GetKeyMessageLPARAM(unsigned aVKey, bool aIsDown, bool aIsSystem)
{
    KeyLParam lp;

    UINT sc = MapVirtualKeyA(aVKey, MAPVK_VK_TO_VSC_EX);

    lp.RepeatCount = 1;
    lp.ScanCode = LOBYTE(sc);
    lp.ExtendedFlag = (HIBYTE(sc) == 0xE0 || HIBYTE(sc) == 0xE1) ? 1 : 0;
    lp.Reserved = 0;
    lp.ContextCode = aIsSystem ? 1 : 0;
    lp.PreviousKeyState = aIsDown ? 0 : 1;
    lp.TransitionState = aIsDown ? 0 : 1;

    return *(LPARAM*)&lp;
}

Я также перехватывал подлинные нажатия клавиш, чтобы понять, что я делаю не так.

В частности, я пытаюсь синтезировать нажатие клавиши «стрелка вверх», то есть VK_UP.

В настоящем сообщении для «стрелки вверх» wParam установлен на VK_UP, а lParam имеет скан-код 0x48 с установленным расширенным флагом.

Подлинное нажатие клавиши для справки:

Сканкод должен быть 0xE048 (с расширенным флажком).

Однако MapVirtualKey() возвращает 72 (0x48) и поэтому не устанавливает ExtendedFlag.

В документации на MSDN указано, что он вернет расширенный флаг.

Я пробовал MapVirtualKey() и MapVirtualKeyEx().

В версиях Ex я пробовал как фактическую раскладку клавиатуры, так и оставлял ее равной 0.

Я использую правильный тип карты MAPVK_VK_TO_VSC_EX, но я также попробовал MAPVK_VK_TO_VSC посмотреть, отличается ли результат.

Я даже попробовал пойти обратным путем, начав с фактического скан-кода и преобразуя его в виртуальный ключ, а затем обратно в скан-код. Я получаю правильный VK_UP, но повторная попытка получить скан-код возвращает неверный ключ.

Независимо от ввода, я никогда не получаю возвращенный расширенный флаг, даже если он должен быть. Я также сделал перекрестную ссылку на свою раскладку клавиатуры через https://kbdlayout.info, и это должно быть 0xE048.

Как мне получить расширенный флаг от MapVirtualKeyA()?

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

Delta 03.09.2024 18:02

Воспроизведено, и это может быть проблема API. Возможно, вам придется внести изменения в возвращаемое значение на основе флага расширенного ключа .

YangXiaoPo-MSFT 04.09.2024 03:43
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
3
162
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отвечаю на свой вопрос, если кто-то еще наткнется на такое поведение:

Возвращаемое значение технически правильное, поскольку MapVirtualKey по умолчанию соответствует нерасширенной версии, а VK_UP используется как клавишей «стрелка вверх» (0xE048), так и цифровой клавиатурой 8 (0x48). Некоторые другие клавиши также используют один и тот же виртуальный код ключа, например VK_RETURN.

Для справки: VK_NUMPAD8 существует и может использоваться в некоторых других макетах, но не в этом случае.

Другие вопросы по теме