Это ошибка для передачи одноэлементного массива в SendInput?

Учитывая следующий код

void foo() {
    INPUT input{};
    input.type = INPUT_MOUSE;
    input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    SendInput(1, &input, sizeof(input));
    input.mi.dwFlags = MOUSEEVENTF_LEFTUP;
    SendInput(1, &input, sizeof(input));
};

Это ошибка для передачи одноэлементного массива в SendInput в последовательных вызовах? Кажется, это прекрасно подтверждается документацией.

1 ответ

Решение

Краткий ответ: возможно.

Более длинный ответ: это зависит.

Чтобы понять, от чего это зависит, и когда это имеет значение, полезно понять, почему SendInput был введен в Windows API: во- первых, он объединяет API- ключи keybd_event и mouse_event в один вызов API. Что еще более важно, он добавляет важную функцию, которая не доступна для предыдущих вызовов. Это называется в документации:

Функция SendInput вставляет события в структурах INPUT последовательно в поток ввода с клавиатуры или мыши. Эти события не перемежаются с другими событиями ввода с клавиатуры или мыши, вставленными пользователем (с помощью клавиатуры или мыши) или вызовами keybd_event, mouse_event или другими вызовами SendInput.

Другими словами: SendInput устанавливает атомарность введенных входных последовательностей независимо от внешних событий вне контроля вызывающего кода.

Обычно важно вводить ввод атомарно, когда ввод состоит из последовательности отдельных событий, как в вопросе. Код вводит кнопку мыши вниз, а затем кнопку мыши вверх за 2 отдельных вызова SendInput, В то время как намерение состоит в том, чтобы иметь одно событие щелчка мышью, реализация позволяет другим источникам входных данных перемежать ввод. Когда другой источник ввода генерирует событие перемещения мыши между событиями нажатия кнопки "вниз" и "вверх", предполагаемый щелчок превращается в операцию перетаскивания. Вместо того, чтобы выбирать файл в проводнике, тот же самый код выбросил файл в корзину. Это явно составляет ошибку.

Аналогично, для ввода с клавиатуры, состоящей из комбинаций клавиш, обычно требуются гарантии атомарности. Внедрение Ctrl + C требует, чтобы все четыре входных события были в одной транзакции. В противном случае (злонамеренный) источник ввода может синтезировать событие нажатия клавиши Ctrl сразу после нажатия клавиши Ctrl, оставляя код, вводящий C, с последующим событием случайного нажатия клавиши Ctrl. Это, вероятно, не то, что было задумано.

В итоге: это ошибка для вызова SendInput неоднократно, проходя 1 в качестве первого аргумента, если выполняются следующие условия:

  • Вход состоит из последовательности отдельных событий ввода.
  • Ввод необходимо интерпретировать как единое целое.
Другие вопросы по тегам