2017-02-14 105 views
1

我一直在構建一個遊戲相關程序,需要將模擬輸入發送到遊戲(這是屏幕上的頂部窗口並以全屏模式運行)。經過一番掙扎後,我終於得到了鼠標移動(光標拖動)和鍵盤輸入工作,但由於某種原因,遊戲不會響應模擬鼠標點擊。發送鼠標點擊DirectX遊戲以管理員身份運行

我曾嘗試以下:

#if TRUE // SendInput works for keyboard simulation and mouse drag, but not clicks: 
    INPUT mouse = {0}; 
    mouse.type = INPUT_MOUSE; 
    mouse.mi.dwFlags = MOUSEEVENTF_LEFTDOWN; 
    SendInput(1, &mouse, sizeof(INPUT)); 

    Sleep(100); 

    ZeroMemory(&mouse, sizeof INPUT); 
    mouse.type = INPUT_MOUSE; 
    mouse.mi.dwFlags = MOUSEEVENTF_LEFTUP; 
    SendInput(1, &mouse, sizeof(INPUT)); 
#else // tried this, but it did not work: 
    mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); 
    Sleep(75); 
    mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); 
#endif 

我面對一般是發送郵件,但我意識到這個問題是由遊戲進程權限造成>發送應用程序權限的第一個困境。在此之後,我遇到了另一個按鍵註冊問題,只在某些遊戲窗口/屏幕上註冊,但經過一番搜索後,我能夠使用掃描代碼來克服這一點。例如:

void SendSpacePress(bool bHardwareLevel){ 
    INPUT space = {0}; 
    space.type = INPUT_KEYBOARD; 
    space.ki.time = 0; 
    space.ki.dwExtraInfo = 0; 

    if(!bHardwareLevel){ 
     space.ki.wVk = VK_SPACE; 
    }else{ 
     space.ki.wScan = 0x39; // physical keyboard scan code 
    } 

    space.ki.dwFlags = bHardwareLevel ? KEYEVENTF_SCANCODE : 0; 
    SendInput(1, &space, sizeof(INPUT)); 

    Sleep(rand()%25 + 25); 

    space.ki.dwFlags = bHardwareLevel ? KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP : KEYEVENTF_KEYUP; 
    SendInput(1, &space, sizeof(INPUT)); 
} 

我也能做到鼠標移動使用輸入象下面這樣:

void PanMouse(){ 
    INPUT mouse = {0}; 
    mouse.type = INPUT_MOUSE; 
    mouse.mi.time = 0; 
    mouse.mi.mouseData = 0; 
    mouse.mi.dwExtraInfo = 0; 
    mouse.mi.dwFlags = MOUSEEVENTF_MOVE; 
    mouse.mi.dx = rand()%10 -5; 
    mouse.mi.dy = rand()%10 -5; 
    SendInput(1, &mouse, sizeof(INPUT)); 
} 

現在我具有很大的問題是遊戲不予登記我的模擬鼠標點擊。我最好喜歡一種發送鼠標輸入的方式,而不必深入鉤子。 (遊戲有多個客戶端反作弊機制,所以我敢冒險猜測任何類型的外部進程掛鉤或DLL注入都會觸發保護。)從我讀過的內容中,我可能需要編寫一個自定義驅動程序一個模擬的硬件鼠標,所以輸入來自內核級。不是一個可取的選擇,但如果需要的話,sobeit。 (如果需要的話,任何人都可以爲此提供有用的信息,我從來沒有與編寫驅動程序好惹的,但有一個第一次的一切,我想是不是?)

TL; DR:那我需要做的獲得模擬鼠標點擊以註冊遊戲,似乎忽略了非硬件輸入? (也就是說,我怎麼能欺騙遊戲思考鼠標點擊是否合法,類似於在模擬鍵盤輸入時使用KEYEVENTF_SCANCODE?)

所有的建議,解決方案和建議值得讚賞。提前致謝!

+0

爲什麼遊戲首先以管理員身份運行? –

+0

@ChuckWalbourn,遊戲如何運行。可能是爲了防止其他進程修改它。不幸的是,它不能以較低的特​​權級別運行。 – SpencerD

+0

作爲管理員運行並沒有什麼能夠保護您免受以管理員身份運行的其他進程。我問,因爲MSFT在過去的12年中花費了大約 ,告訴遊戲開發者不要求管理員權限來運行他們的遊戲。管理員安裝,當然。管理員運行,而不是太多。請參閱[遊戲開發者的用戶帳戶控制](https://msdn.microsoft.com/en-us/library/windows/desktop/ee419001.aspx) –

回答

0

而不是在輸入之間休眠,你需要注入一對鼠標輸入連同time成員適當設置,以指示「多久」。

以下是接近你想要的東西。這將用鼠標左鍵點擊當前光標位置100ms。

INPUT inputs[2] = {}; 

inputs[0].type = INPUT_MOUSE; 
inputs[0].mi.time = 0; 
inputs[0].mi.dx = 0; 
inputs[0].mi.dy = 0; 
inputs[0].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; 

inputs[1].type = INPUT_MOUSE; 
inputs[1].mi.time = 100; 
inputs[1].mi.dx = 0; 
inputs[1].mi.dy = 0; 
inputs[1].mi.dwFlags = MOUSEEVENTF_LEFTUP; 

SendInput(2, inputs, sizeof(INPUT)); 

鼠標事件不會立即發生。它會在排隊後不久發生。

您應該對鍵盤事件使用相同的技巧。不要叫「睡眠」。

+0

感謝您的意見和建議。我會試一試。 – SpencerD

+0

嗯。我只是嘗試了一下,但它仍然沒有在遊戲過程中註冊點擊(或至少沒有作爲鼠標點擊來響應)。我知道這不是一個進程升級的問題,因爲我離開了常規的鍵盤點擊,並且仍然可以正常工作,所以它似乎必須成爲忽略虛假「MOUSEEVENTF」過程的問題。 – SpencerD

相關問題