将单元素数组传递给SendInput是一个错误吗?

IIn*_*ble 0 winapi 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));
};
Run Code Online (Sandbox Code Playgroud)

在连续调用中将单元素数组传递给SendInput是一个错误吗?文档似乎完全支持这一点.

IIn*_*ble 8

简短的回答:也许吧.

更长的答案:这取决于.

要了解它所依赖的内容,以及何时重要,有助于理解为什么将SendInput引入Windows API:例如,它将keybd_eventmouse_event API合并到一个API调用中.更重要的是,它增加了以前调用无法使用的重要功能.这在文档中提到:

SendInput函数插入在事件INPUT结构串联到键盘或鼠标输入流.这些事件不会插入用户(使用键盘或鼠标)插入的其他键盘或鼠标输入事件,也不会调用keybd_event,mouse_event或其他SendInput调用.

换句话说:SendInput建立注入的输入序列的原子性,而不管调用代码控制之外的外部事件.

当输入由一系列单个事件组成时,例如在问题中,通过原子方式注入输入通常很重要.代码注入一个鼠标按钮,然后在两个单独的调用中按下鼠标按钮SendInput.虽然目的是只有一个鼠标单击事件,但实现允许其他输入源散布输入.当另一个输入源在鼠标按钮向下和向上事件之间产生鼠标移动事件时,预期的点击已变为拖放操作.不是在文件资源管理器中选择文件,而是将相同的代码抛出到回收站中.这显然构成了一个错误.

同样,注入由键组合组成的键盘输入通常需要原子性保证.注入Ctrl+ C要求所有四个输入事件都在一个事务中.否则,(恶意)输入源可能会CtrlCtrl按键关闭后立即合成一个按键事件,使代码注入一个C带有杂散Ctrl键事件尾随的代码.这可能不是我想要的.

总结:如果满足以下条件,则SendInput重复调用是一个错误,1作为第一个参数传递:

  • 输入由一系列单独的输入事件组成.
  • 输入需要被解释为单个单元.

  • @VTT:这是一个适合所有人的问答网站.如果您认为自己可以做得更好,请继续提交您自己的答案. (2认同)