2017-10-14 28 views
1

鉴于以下代码将单元素数组传递给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一个错误?这似乎完全由文档支持。

+0

该问题可以重命名为“如何正确地发送SendInput输入事件序列?”因为它本质上就是答案。 – VTT

+0

@VTT:是的,可以。但这不是被问到的问题。一遍又一遍被问到的问题就是标题中的问题。这是一个[参考](https://stackoverflow.com/questions/46742660/c-execution-causes-monitor-to-disconnect#comment80434590_46742660)。 – IInspectable

+2

问题标题应该更容易找到用户与这些问题挣扎并寻求帮助。我认为更通用的标题变体会更容易发现。如果输入序列应该更长,那么将'2'或'3'或'4'作为第一个参数传递也可能是一个潜在的错误。因此,关于传递'1'的标题太窄了。 – VTT

回答

9

简答:也许吧。

较长的答案:这取决于。

,看看它依赖于,当这个重要的,它有助于理解,为什么SendInput引入的Windows API:其一,它整合了keybd_eventmouse_event API整合到一个单一的API调用。更重要的是,它增加了以前调用不可用的重要功能。这是在文档中调出:

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

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

当输入由一系列单个事件组成时,如问题中那样,通常会自动注入输入。该代码注入一个鼠标按钮,然后按下一个鼠标按钮,以2个单独调用SendInput。虽然意图是有一个单一的鼠标点击事件,该实现允许其他输入源散布输入。当另一个输入源在鼠标按钮向下和向上事件之间产生鼠标移动事件时,预期点击变为拖放操作。与在文件资源管理器中选择文件不同,该代码已将该文件引入回收站。这显然构成了一个错误。同样,注入由键组合组成的键盘输入通常需要原子性保证。注入Ctrl + C要求所有四个输入事件都在单个事务中。否则,(恶意的)输入源可以合成的Ctrl键键按下后右一Ctrl键键抬起事件,留下注入Ç的代码,具有杂散Ctrl键键抬起事件后。这可能不是既定目标。

总结:这是调用SendInput反复,经过1作为第一个参数的错误,如果满足以下条件:

  • 输入由单独的输入事件的序列。
  • 输入需要解释为一个单元。
+0

这个答案只是文档的不必要的详细排练。 – VTT

+0

@VTT:是吗? [这](https://stackoverflow.com/q/8021954/1889329)会不同意没有必要。或者[this](https://stackoverflow.com/a/11438156/1889329)。 [This](https://stackoverflow.com/q/11438677/1889329),[this](https://stackoverflow.com/q/23203944/1889329)或[this](https://stackoverflow.com/q /一百八十八万九千三百二十九分之三千一百六十〇万六千九百六十二)。事实上,挑选任何*随机'SendInput'问题,你会发现,这个问答非常需要。 – IInspectable

+0

它可以大大缩短,基本上“如果你发送一系列输入事件,并且不想让其他事件进入你之间,你必须通过一次调用将SendInput发送给'SendInput'。 – VTT

相关问题