将单元素数组传递给SendInput是否有bug? [英] Is it a bug to pass a single-element array to SendInput?

查看:74
本文介绍了将单元素数组传递给SendInput是否有bug?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出以下代码

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 ?该文档似乎完全支持了这一点.

is it a bug to pass a single-element array to SendInput in consecutive calls? This seems to be perfectly supported by the documentation.

推荐答案

简短的回答:也许.

更长的答案:这取决于.

Longer answer: It depends.

要查看它所依赖的内容,以及在什么时候重要,这有助于理解为什么 SendInput :其中,它整合了将mouse_event API转换为单个API调用.更重要的是,它增加了一项重要功能,以前的呼叫无法使用.在文档中对此进行了标注:

To see what it depends on, and when this matters, it helps to understand, why SendInput was introduced into the Windows API: For one, it consolidates the keybd_event and mouse_event APIs into a single API call. More importantly, it adds a significant feature that isn't available to the previous calls. This is called out in the documentation:

SendInput 函数将事件插入

The SendInput function inserts the events in the INPUT structures serially into the keyboard or mouse input stream. These events are not interspersed with other keyboard or mouse input events inserted either by the user (with the keyboard or mouse) or by calls to keybd_event, mouse_event, or other calls to SendInput.

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

In other words: SendInput establishes atomicity of injected input sequences, irrespective of external events outside the control of the calling code.

当输入由一系列单个事件组成时(例如在问题中),原子地注入输入通常很重要.该代码在对SendInput的2个单独调用中分别按下了鼠标键,然后按下了鼠标键.尽管意图是使鼠标单击事件,但该实现允许其他输入源散布输入.当另一个输入源在鼠标按下和按下事件之间产生鼠标移动事件时,预期的单击已变为拖放操作.与其在文件资源管理器"中选择文件,不如说是相同的代码将文件扔到了回收站中.显然,这构成了一个错误.

It is usually important to atomically inject input, when the input consists of a sequence of individual events, like in the question. The code injects a mouse button down followed by a mouse button up in 2 individual calls to SendInput. While the intention is to have a single mouse click event, the implementation allows other input sources to intersperse input. When another input source produces a mouse move event in between the mouse button down and up events, the intended click has turned into a drag-and-drop operation. Instead of selecting a file in File Explorer, that very same code has thrown the file into the Recycle Bin. That clearly constitutes a bug.

同样,注入由组合键组成的键盘输入通常需要原子性保证.注入 Ctrl + C 要求所有四个输入事件都在单个事务中.否则,(恶意)输入源可能会在按下 Ctrl 键之后立即合成一个 Ctrl 键上升事件,从而使代码注入 C ,使用杂乱的 Ctrl 键跟踪事件尾随.这可能也不是我们想要的.

Likewise, injecting keyboard input consisting of key combinations generally requires atomicity guarantees. Injecting Ctrl+C requires all four input events to be in a single transaction. Otherwise, a (malicious) input source could synthesize a Ctrl key up event right after the Ctrl key down, leaving the code injecting a C, with a stray Ctrl key up event trailing. That's probably not what was intended either.

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

In summary: It is a bug to call SendInput repeatedly, passing 1 as the first argument if the following conditions are true:

  • 输入由一系列单独的输入事件组成.
  • 要求将输入解释为单个单位.

这篇关于将单元素数组传递给SendInput是否有bug?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆