向UnityWndClass发送“按钮按下”消息

问题描述:

我有3D游戏,我需要从另一个应用程序按此游戏中的按钮。 Spy ++说这个游戏的窗口是UnityWndClass。当我在游戏中按下按钮时,窗口只会收到类似WM_SETCURSORWM_LBUTTONDOWN等的鼠标消息,但是当我尝试将WM_LBUTTONDOWNWM_LBUTTONUP与其他窗口中的按钮坐标一起发送时,什么也没有发生。为什么?任何想法如何按下按钮?向UnityWndClass发送“按钮按下”消息

WM_SETCURSOR用于更改您自己的窗口的光标图像。 WM_LBUTTONDOWNWM_LBUTTONUP是鼠标点击后发送的通知消息。 WM_LBUTTONXXX消息可能不是由主窗口过程处理的。

要伪造鼠标输入,您可以使用mouse_eventSendInput。例如,这将光标移动到x=10/y=10,然后单击鼠标左键。

int x = 10 * 65536/GetSystemMetrics(SM_CXSCREEN); 
int y = 10 * 65536/GetSystemMetrics(SM_CYSCREEN); 

mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x, y, 0, 0); 
mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0); 
mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0); 

或者使用SendInput多个电话(见注释)

INPUT input[3]; 
for (int i = 0; i < 3; i++) 
{ 
    memset(&input[i], 0, sizeof(INPUT)); 
    input[i].type = INPUT_MOUSE; 
} 

input[0].mi.dx = x; 
input[0].mi.dy = y; 
input[0].mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE; 
input[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; 
input[2].mi.dwFlags = MOUSEEVENTF_LEFTUP; 
SendInput(3, input, sizeof(INPUT)); 

窗口应至少可见,最好是活动的。您可以使用SetForegroundWindow。请参阅此example以确保窗口可见并处于活动状态。

其他替代方案:

用狙++,以获取有关要按下按钮信息。例如,如果这是Windows计算器,您可以窥探计算器的按钮,它会显示计算器按钮的ID已设置为0x84。您可以发送WM_COMMANDWPARAM设置为0x84来模拟按钮按下。

HWND hwnd = FindWindow(0, L"Calculator"); 
if (IsWindow(hwnd)) 
{ 
    //this should put "234" in to calculator's edit box 
    SendMessage(hwnd, WM_COMMAND, 0x84, 0);  
    SendMessage(hwnd, WM_COMMAND, 0x85, 0);  
    SendMessage(hwnd, WM_COMMAND, 0x86, 0);  
} 
+0

窗口应该是活动的,当我做假鼠标输入? –

+0

是的,窗口应该至少可见,如果它处于活动状态,它会更好。我更新答案。 –

+0

窗口**必须**具有输入焦点才能接收输入(合成或真实)。请再次阅读[SendInput](https://msdn.microsoft.com/en-us/library/windows/desktop/ms646310.aspx)的文档。为'nInputs'传递'1'是一个错误。 *备注*部分解释,为什么。另外,你提出的任何黑客都不是一个可靠的解决方案。正确的方法是使用[UI自动化](https://msdn.microsoft.com/en-us/library/windows/desktop/ee684009.aspx),它不要求任何特定的窗口有任何输入焦点点。 – IInspectable