свайп в окне эмулятора Android через winapi

128
16 ноября 2020, 19:00

Имею эмулятор BlueStacks. Цель: написать простого бота, который в окне эмулятора нажимает на определенные области экрана эмулируя тапы, а также свайпает окно, когда нужно. Поскольку в winapi я не силен, по всей видимости, что-то просто упускаю. Моя логика следующая:

  • С помощью EnumWindows пройтись по всем родительским окнам и найти окно с заголовком "BlueStacks"
  • С помощью EnumChildWindows пройтись по всем найденным экземплярам родительских окно и найти дочерние окна.
  • Перебрать дочерние окна (благо, их не много) и проверить какие откликаются на отправку им сообщений WM_LBUTTONDOWN в конкретной клиентской области, содержащей интерактивный элемент. В моем случае, интерактивная область должна "замерцать" если нажать на ней мышкой и не отпускать ее.
  • Запомнить на будущее класс найденного "отзывчивого" дочернего окна и начать работать с ним.

Напосредственная работа с окном:

Кликнуть мышкой в нужном месте.

[StructLayout(LayoutKind.Sequential)]
        public struct WINDOWINFO
        {
            public int cbSize;
            public RECT rcWindow;
            public RECT rcClient;
            public uint dwStyle;
            public uint swExStyle;
            public uint dwWindowStatus;
            public uint cxWindowBorders;
            public uint cyWindowBorders;
            public ushort atomWindowType;
            public ushort wCreatorVersion;
            public string sTitle;
            public int Width;
            public int Height;
            public HWND hWnd;
            public WINDOWINFO(Boolean ? filler) : this ()
            {
                cbSize = (int)(Marshal.SizeOf(typeof(WINDOWINFO)));
            }
        }

.....

 this.WindowState = FormWindowState.Minimized;
 BringWindowToTop(currentChildWindow.hWnd);
 ShowWindow(currentChildWindow.hWnd, (int)SW.SW_SHOW);
 SetForegroundWindow(currentChildWindow.hWnd);
 this.Cursor  = new Cursor(Cursor.Current.Handle);
 //сWindow - переменная для отладки дальнейших массовых манипуляций с окнами
 cWindow = currentChildWindow;
 Cursor.Position = new Point(cWindow.rcWindow.Left + 70, cWindow.rcWindow.Top + 370);
 SendMessage(cWindow.hWnd, WM_MOUSEMOVE, MK_NONE, MakeLParam(new Point(cWindow.rcWindow.Left + 70, cWindow.rcWindow.Top + 370)));
 SendMessage(cWindow.hWnd, WM_LBUTTONDOWN, MK_LBUTTON | MK_NONE, MakeLParam(new Point(cWindow.rcWindow.Left + 70, cWindow.rcWindow.Top + 370)));

Т.е. я создаю курсор, перемещаю его в нужную точку в окне. Затем отправляю событие окну WM_MOUSEMOVE и следом WM_LBUTTONDOWN

И Это работает! Если отправить WM_LBUTTONUP - тоже сработает. Но, ни в какую не работает свайп. Я думал, свайп можно сделать совсем просто, как это происходит вживую с мышкой:

  1. Зажать левую кнопку мыши
  2. Провести мышкой по экрану в пределах окна
  3. Отпустить мышку

Сделал так (продолжение предыдущего кода с нажатой клавишей):

for(int x = 0; x < 100; x++)
{ 
   Cursor.Position = new Point(cWindow.rcWindow.Left + 70 + x, cWindow.rcWindow.Top + 370);
   SendMessage(cWindow.hWnd, WM_MOUSEMOVE, MK_NONE, MakeLParam(new Point(cWindow.rcWindow.Left + 70 + x, cWindow.rcWindow.Top + 370)));
   Thread.Sleep(15);
}
SendMessage(cWindow.hWnd, WM_LBUTTONUP, MK_NONE, MakeLParam(new Point(cWindow.rcWindow.Left + 170, cWindow.rcWindow.Top + 370)));

Это не работает! По мерцанию элемента в окне видно, что окно приняло событие WM_LBUTTONDOWN Затем я вижу, что мышь двигается по игровому окну по горизонтали. Затем срабатывает WM_LBUTTONUP и мерцание интерактивного объекта в окне исчезает. Но свайп не работает. Мышь просто скользит по окну и всё. Я понимаю, что накрутил лишнего и, возможно, смотрю вообще не туда. Очень прошу помочь разобраться.

Answer 1

Ларчик открывался намного проще. PostMessage для событий мыши, вместо SendMessage

READ ALSO
Проблема при работе БД с IIS

Проблема при работе БД с IIS

Опубликовал свой проект в IISПри работе с БД выдаёт следующую ошибку: "Не удается открыть базу данных "RefsDB", запрашиваемую именем входа

135