Это ошибка для передачи одноэлементного массива в 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
в качестве первого аргумента, если выполняются следующие условия:
- Вход состоит из последовательности отдельных событий ввода.
- Ввод необходимо интерпретировать как единое целое.