Задать вопрос
wataru
@wataru
Разработчик на С++, экс-олимпиадник.

Есть ли аналог библиотеки pyautogui на C++ под windows?

Хочу написать бота для игры (пасьянс от zachtronics).
Уже есть рабочий вариант - костыльная мерзость, где скрипт на пинтоне с pyautogui получает скриншоты, разбирает что там на экране, скармливает состояние поля С++ exe-шнику решателю, получает команды для мышки и выполняет их.

Переписать логику на питоне - слишком медленно работает, да и питонист я хреновый.
Хотелось бы переписать все на C++.
Но надо уметь делать:
- Скриншоты окна
- Сравнение кусков скриншота с картинками из файла
- Посылка команд мышкой
- Минимальное управление окном, вроде фокуса
- Глобальные хот-кеи

Знает кто-нибудь удобную библиотеку (или набор библиотек) для этого?
Не очень хочется через GDI получать HBITMAPы, руками все это резать на части и сравнивать с шаблонами. Все-таки работа с winapi - это очень-очень много мерзкого кода.

Если такой библиотеки нет, то посоветуйте хотя бы, что можно использовать для работы только с изображениями?
Может CImage из MFC?
  • Вопрос задан
  • 447 просмотров
Подписаться 2 Простой 7 комментариев
Решения вопроса 1
QWERTYUIOPas
@QWERTYUIOPas
КраткоОСеБе
Есть. Python.h называется.
Но если прям чистый С++, то делаете скрин, находите на нём изображение из файла, тыкаете мышью.
шаг1. Скрин
https://ru.stackoverflow.com/questions/627095/Как-...
void CaptureScreen(){
// Определение контекстов
HDC ScreenDC = GetDC(0);
HDC MemoryDC = CreateCompatibleDC(ScreenDC);

// Фиксация размеров экрана
int ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int ScreenHeight = GetSystemMetrics(SM_CYSCREEN);

// Создание и частичное заполнение структуры формата
BITMAPINFO BMI;
BMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
BMI.bmiHeader.biWidth = ScreenWidth;
BMI.bmiHeader.biHeight = -ScreenHeight; // Отрицательное значение высоты, чтобы изображение не было перевёрнутым
BMI.bmiHeader.biSizeImage = ScreenWidth * ScreenHeight * 3; // Ширина * Высота * Количество_цветов_на_пиксель
BMI.bmiHeader.biCompression = BI_RGB;
BMI.bmiHeader.biBitCount  = 24;
BMI.bmiHeader.biPlanes = 1;

ScreenshotSize = BMI.bmiHeader.biSizeImage; // ScreenshotSize - глобальная переменная типа int, может меняться в ходе выполнения программы
unsigned char *ImageBuffer; // Указатель на блок данных BGR, управляемый HBITMAP (да, именно BGR - не RGB)
HBITMAP hBitmap = CreateDIBSection(ScreenDC,&BMI,DIB_RGB_COLORS,(void**)&ImageBuffer,0,0);
SelectObject(MemoryDC, hBitmap);
BitBlt(MemoryDC, 0, 0, ScreenWidth, ScreenHeight, ScreenDC , 0, 0, SRCCOPY);

// Контексты больше не нужны
DeleteDC(MemoryDC);
ReleaseDC(NULL, ScreenDC);

// Если требуется RGB вместо BGR - следующий цикл перевернёт нужные байты
for(int i = 0; i < ScreenshotSize; i += 3){
    unsigned char ColorValue = ImageBuffer[i];
    ImageBuffer[i] = ImageBuffer[i + 2];
    ImageBuffer[i + 2] = ColorValue;
}

// Используем ImageBuffer как нам хочется... после удаляем его хендлер (HBITMAP) для избежания утечки памяти
DeleteObject(hBitmap);
}
шаг2. Поиск на скрине

Тут всё сложнее. Я думаю так:
Получение Х
  1. преобр. скрин в битмап
  2. преобр. изобр в битмап
  3. извлечь первые \ширина_изобр\ байт из битмапа изображения
  4. разделить битмап скрина на куски \ширина_скрина\ байт
  5. пройтись по кускам битмапа скрина, пытаясь найти индекс первых \ширина_изобр\ байт из битмапа изображения
  6. Вы получили Х
Получение У
повернуть оба изобр. на 90гр. влево
  1. преобр. скрин в битмап
  2. преобр. изобр в битмап
  3. извлечь первые \высота_изобр\ байт из битмапа изображения
  4. разделить битмап скрина на куски \высота_скрина\ байт
  5. пройтись по кускам битмапа скрина, пытаясь найти индекс первых \высота_изобр\ байт из битмапа изображения
  6. Вы получили У
  7. повернуть оба изобр. на 90гр. вправо
шаг3. Тык мышью
  1. clickХ=Х+(\ширина_изобр\)/2
  2. clickY=Y+(\высота_изобр\)/2
    https://ru.stackoverflow.com/questions/1127812/Как...
скармливает состояние поля С++ exe-шнику решателю

А не лучше сделать ДЛЛ и импорт ДЛЛ из питона?
from ctypes import *
pasyansbot=CDLL("пасьянс.DLL")

pasyans.reshit(['Sobakas', 'Koshkas'], ['Linux', 'Windows'])
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы