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

查看:16
本文介绍了将单元素数组传递给 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 连续调用?这似乎得到了文档的完美支持.

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 被引入 Windows API:首先,它整合了 keybd_eventmouse_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 函数将事件插入 INPUT 结构串行到键盘或鼠标输入流中.这些事件不会与由用户(使用键盘或鼠标)或通过调用 keybd_eventmouse_event,或对 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 是错误吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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