2017-10-14 32 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

相關問題