Я пытаюсь эмулировать щелчки и перемещения пользователей, особенно в Mozilla Firefox, в среде Windows 7. Решение, которое я получил вместе из различных учебных пособий, сообщений на форумах и документов MSDN, работает для 99% приложений Windows, но не работает для Firefox 8.0.
Из моих предварительных исследований самый точный (низкоуровневый) способ эмуляции ввода с клавиатуры и мыши в Windows - это использование функции SendInput из библиотеки Windows User32.dll. Чтобы проверить это, я написал короткую C # -программу для обхода и вызова SendInput, который создает программный щелчок мыши каждые 5 секунд, независимо от того, где находится курсор мыши на экране.
После запуска программа прекрасно имитирует щелчок мышью практически для каждого окна приложения, на которое я переключаю фокус, даже включая сам интерфейс Windows (кнопка «Пуск», панель задач, проводник Windows и т. Д.), Но при нажатии программных щелчков мыши не происходит. поместите курсор в окно Mozilla Firefox.
Чтобы лучше понять, что происходит внутри, я загрузил Microsoft Spy ++ и начал проверять, какие сообщения фактически передаются в очередь сообщений окна Firefox. Конечно же, окно Firefox не будет получать сообщений, даже если мой курсор будет находиться прямо над ним, когда он был в фокусе. Когда я вручную щелкал мышью, прослушиватель Firefox Spy ++ тогда сходил с ума и отображал полный «nHittest: HTCLIENT wMouseMsg: WM_LBUTTONDOWN», который я видел, наблюдая правильные ответы других приложений на мою программу эмуляции.
Может ли кто-нибудь дать объяснение того, как / почему Mozilla Firefox является единственным приложением, которое вообще не получает никаких сообщений от функции SendInput, и, возможно, предложение о том, как это преодолеть?
Исходный код
(Импорт / внешние ссылки удалены для ясности):
static void Main(string[] args)
{
for (; ; )
{
System.Threading.Thread.Sleep(5000);
INPUT[] inp = new INPUT[2];
inp[0].type = INPUT_MOUSE;
inp[0].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTDOWN);
inp[1].type = INPUT_MOUSE;
inp[1].mi = createMouseInput(0, 0, 0, 0, MOUSEEVENTF_LEFTUP);
SendInput((uint)inp.Length, inp, Marshal.SizeOf(inp[0].GetType()));
}
}
private static MOUSEINPUT createMouseInput(int x, int y, uint data, uint t, uint flag)
{
MOUSEINPUT mi = new MOUSEINPUT();
mi.dx = x;
mi.dy = y;
mi.mouseData = data;
mi.time = t;
mi.dwFlags = flag;
return mi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Explicit)]
private struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(sizeof(int))] //[FieldOffset(8)] for x64
public MOUSEINPUT mi;
[FieldOffset(sizeof(int))] //[FieldOffset(8)] for x64
public KEYBDINPUT ki;
[FieldOffset(sizeof(int))] //[FieldOffset(8)] for x64
public HARDWAREINPUT hi;
}