向UnityWndClass发送“按钮按下”消息
问题描述:
我有3D游戏,我需要从另一个应用程序按此游戏中的按钮。 Spy ++说这个游戏的窗口是UnityWndClass。当我在游戏中按下按钮时,窗口只会收到类似WM_SETCURSOR
,WM_LBUTTONDOWN
等的鼠标消息,但是当我尝试将WM_LBUTTONDOWN
和WM_LBUTTONUP
与其他窗口中的按钮坐标一起发送时,什么也没有发生。为什么?任何想法如何按下按钮?向UnityWndClass发送“按钮按下”消息
答
WM_SETCURSOR
用于更改您自己的窗口的光标图像。 WM_LBUTTONDOWN
和WM_LBUTTONUP
是鼠标点击后发送的通知消息。 WM_LBUTTONXXX
消息可能不是由主窗口过程处理的。
要伪造鼠标输入,您可以使用mouse_event
或SendInput
。例如,这将光标移动到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_COMMAND
与WPARAM
设置为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);
}
窗口应该是活动的,当我做假鼠标输入? –
是的,窗口应该至少可见,如果它处于活动状态,它会更好。我更新答案。 –
窗口**必须**具有输入焦点才能接收输入(合成或真实)。请再次阅读[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