Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Наведение курсора на пиксель, Наведение курсора на пиксель 
:(
    Опции темы
CWD
Дата 19.8.2012, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 26.11.2011

Репутация: нет
Всего: нет



Здравствуйте нашел в сети кусок кода который должен наводить курсор, на пиксель определенного цвета. Но возникла некая проблема не совсем понятно почему оно не работает. Как я понял программа переводит изображение с Рабочего стола, в массив пикселей формата (r,g,b,a). 

Не совсем понятно что нужно вписать вместо дескриптора исходного DC, screen. (BitBlt(hdcTemp, bx/2, by/2, MAX_WIDTH, MAX_HEIGHT, screen, 0, 0, SRCCOPY);)

Компилирую под VS 2010.

Код

#include <iostream>
#include <cstdio>
#include <windows.h>

#define MAX_WIDTH 100
#define MAX_HEIGHT 100

int main()
{
HDC hdc, hdcTemp;
RECT rect;
BYTE* bitPointer;
int x, y;
int red, green, blue, alpha;
int bx,by;

bx = GetSystemMetrics(SM_CXSCREEN);
by = GetSystemMetrics(SM_CYSCREEN);

while(true)
{
    hdc = GetDC(HWND_DESKTOP);
    hdcTemp = CreateCompatibleDC(hdc);
    BITMAPINFO bitmap;
    bitmap.bmiHeader.biSize = sizeof(bitmap.bmiHeader);
    bitmap.bmiHeader.biWidth = MAX_WIDTH;
    bitmap.bmiHeader.biHeight = MAX_HEIGHT;
    bitmap.bmiHeader.biPlanes = 1;
    bitmap.bmiHeader.biBitCount = 32;
    bitmap.bmiHeader.biCompression = BI_RGB;
    bitmap.bmiHeader.biSizeImage = MAX_WIDTH * 4 * MAX_HEIGHT;
    bitmap.bmiHeader.biClrUsed = 0;
    bitmap.bmiHeader.biClrImportant = 0;
    HBITMAP hBitmap2 = CreateDIBSection(hdcTemp, &bitmap, DIB_RGB_COLORS, (void**)(&bitPointer), NULL, NULL);
    SelectObject(hdcTemp, hBitmap2);
    BitBlt(hdcTemp, bx/2, by/2, MAX_WIDTH, MAX_HEIGHT, screen, 0, 0, SRCCOPY);
    
    for (int i=0; i<(MAX_WIDTH * 4 * MAX_HEIGHT); i+=4)
    {
        red = (int)bitPointer[i];
        green = (int)bitPointer[i+1];
        blue = (int)bitPointer[i+2];
        alpha = (int)bitPointer[i+3];

        x = i / (4 * MAX_HEIGHT);
        y = i / (4 * MAX_WIDTH);

        if (red == 1 && green == 0 && blue == 0)
        {
            SetCursorPos(x,y);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            Sleep(50);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            Sleep(25);
        }
    }
}
    return 0;
}

PM MAIL   Вверх
leniviy
Дата 19.8.2012, 14:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Переменная hdc не используется. Может она и есть screen?
PM MAIL   Вверх
CWD
Дата 19.8.2012, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 26.11.2011

Репутация: нет
Всего: нет



leniviy, Я тоже так думал и тестировал вариант такой BitBlt(hdcTemp, 100, 100, MAX_WIDTH, MAX_HEIGHT, hdc, 0, 0, SRCCOPY); 
получил "Unhandled exception at 0x00411545 in FindPixelByCursor.exe: 0xC0000005: Access violation reading location 0x00000000."
PM MAIL   Вверх
leniviy
Дата 19.8.2012, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



BitBlt должен заполнять буфер, но он у тебя не заполняется.
Попробуй взять пример отсюда: http://it-talk.org/topic2646.html
Он тоже кривой, но буфер, по крайней мере, заполняется. В качестве параметра попробуй GetDesktopWindow(), а не HWND_DESKTOP
PM MAIL   Вверх
leniviy
Дата 19.8.2012, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Код

bx/2, by/2, MAX_WIDTH, MAX_HEIGHT

Что это? Зачем заполнять только середину своего битмапа?

Это сообщение отредактировал(а) leniviy - 19.8.2012, 15:54

Присоединённый файл ( Кол-во скачиваний: 13 )
Присоединённый файл  bbb.png 38,70 Kb
PM MAIL   Вверх
CWD
Дата 19.8.2012, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 26.11.2011

Репутация: нет
Всего: нет



Получилось копировать буфер в bitPointer, но он получается какого-то не очень адекватного размера.

Это сообщение отредактировал(а) CWD - 19.8.2012, 16:00
PM MAIL   Вверх
leniviy
Дата 19.8.2012, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Цитата(CWD @  19.8.2012,  15:41 Найти цитируемый пост)
как теперь определить размер массива bitPointer?

А какой размер нужен? С теми параметрами, которые у тебя были изначально, у тебя было вот такое изображение в буфере:
http://forum.vingrad.ru/act-Attach/type/post/id-2512388.html
Значит размер массива - x*y*(24/8);

Я так и не понял, какой параметр овечает за выбор между 24- и 32-битным изображением.
PM MAIL   Вверх
CWD
Дата 19.8.2012, 16:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 26.11.2011

Репутация: нет
Всего: нет



leniviy, Ну просто теперь хотелось бы наводить курсор на пиксель нужно цвета. Но это не выходит с помощью того когда который есть, потому что bitPointer, состоит и 3332 ячеек. И почему именно 3332 светит я тоже не понимаю.

Код

for (int i=0; i<(MAX_WIDTH * 4 * MAX_HEIGHT); i+=4)
    {
        red = (int)bitPointer[i];
        green = (int)bitPointer[i+1];
        blue = (int)bitPointer[i+2];
        alpha = (int)bitPointer[i+3];

        x = i / (4 * MAX_HEIGHT);
        y = i / (4 * MAX_WIDTH);

        if (red == 1 && green == 0 && blue == 0)
        {
            SetCursorPos(x,y);
            mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
            Sleep(50);
            mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
            Sleep(25);
        }

PM MAIL   Вверх
leniviy
Дата 19.8.2012, 17:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Починил твою программу. Объяснять тяжело, но работает
Я её немного переделал. Теперь она не кликает, а только обводит курсором красные точки в пределах квадрата 100x100 .
И сохраняет изображение aaa.bmp в папку с программой.

Код

#include <iostream>
#include <cstdio>
#include <windows.h>
#define MAX_WIDTH 100
#define MAX_HEIGHT 100


void ClickPixel()
{
    HWND window = GetDesktopWindow();
    RECT windowRect;
    GetWindowRect(window, &windowRect);

    int bitmap_dx = windowRect.right-windowRect.left;
    int bitmap_dy = windowRect.bottom-windowRect.top;

    BITMAPINFO info;
    BITMAPINFOHEADER &bmpInfoHeader = info.bmiHeader;
    BITMAP* pBitmap;

    bmpInfoHeader.biSize = sizeof(bmpInfoHeader);
    bmpInfoHeader.biWidth = MAX_WIDTH;
    bmpInfoHeader.biHeight = MAX_HEIGHT;
    bmpInfoHeader.biPlanes = 1;
    bmpInfoHeader.biBitCount = 32;
    bmpInfoHeader.biCompression = BI_RGB;
    bmpInfoHeader.biSizeImage = bmpInfoHeader.biWidth*bmpInfoHeader.biHeight*(bmpInfoHeader.biBitCount/8);
    bmpInfoHeader.biXPelsPerMeter = 0;
    bmpInfoHeader.biYPelsPerMeter = 0;
    bmpInfoHeader.biClrUsed = 0;
    bmpInfoHeader.biClrImportant = 0;

    BYTE* bitPointer;
    HDC winDC = GetWindowDC(window);
    HDC bmpDC = CreateCompatibleDC(winDC);
    
    HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, (void**)&bitPointer, NULL, 0);
    SelectObject(bmpDC, bitmap);//Выбираем в контекст битмэп
    BitBlt(bmpDC, 0, 0, MAX_WIDTH, MAX_HEIGHT, winDC, 0, 0, SRCCOPY);
    ReleaseDC(window, winDC);

    if (1) {
      for (int y = 0; y < MAX_HEIGHT; y++) for (int x = 0; x < MAX_WIDTH; x++)
      {
        BYTE *ppoint = &bitPointer[4*( MAX_WIDTH*(MAX_HEIGHT-1 - y) + x)];
          int red, green, blue, alpha;

          red = (int)ppoint[0];
          green = (int)ppoint[1];
          blue = (int)ppoint[2];
          alpha = (int)ppoint[3];
          if (0
            //(red == 255 && green == 0 && blue == 0)
            || (red == 0 && green == 0 && blue == 255)
            //|| (red == 0 && green == 255 && blue == 0)
            )
          {
              SetCursorPos(x,y);
              //mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
              //mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
              // break;
              Sleep(50);
          }
      }
    }

    if (1) {
    HANDLE hFile = CreateFile(
      "aaa.bmp", 
        GENERIC_WRITE, 
        0,
        NULL,
        CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL);
    if (hFile == INVALID_HANDLE_VALUE) 
        return;
    DWORD dwWritten = 0;

    BITMAPFILEHEADER bmpFileHeader;
    bmpFileHeader.bfType = 0x4d42;
    bmpFileHeader.bfSize = 0;
    bmpFileHeader.bfReserved1 = 0;
    bmpFileHeader.bfReserved2 = 0;
    bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    WriteFile(hFile, &bmpFileHeader, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);
    WriteFile(hFile, &bmpInfoHeader, sizeof(BITMAPINFOHEADER), &dwWritten, NULL);
    WriteFile(hFile, bitPointer, bmpInfoHeader.biSizeImage, &dwWritten, NULL);
    CloseHandle(hFile);
    }
}

int main()
{
  
  ClickPixel();
  return 0;
}



Добавлено через 1 минуту и 14 секунд
Что было починено:
- неправильно вычислялись координаты точки
- байты идут не в порядке rgba, а в порядке bgra

Добавлено через 4 минуты и 8 секунд
Код

        x = i / (4 * MAX_HEIGHT);
        y = i / (4 * MAX_WIDTH);

так получается по диагонали. Надо было считать y как частное от деления на  MAX_WIDTH, а x как остаток от этого деления

Добавлено через 8 минут и 5 секунд
ччч

Присоединённый файл ( Кол-во скачиваний: 12 )
Присоединённый файл  red.png 0,14 Kb
PM MAIL   Вверх
leniviy
Дата 19.8.2012, 17:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Тебе надо открыть вот этот файл: http://forum.vingrad.ru/act-Attach/type/post/id-2512402.html
и поместить его в левый верхний угол экрана, как на 

Это сообщение отредактировал(а) leniviy - 19.8.2012, 17:26

Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  aaa.png 8,77 Kb
PM MAIL   Вверх
CWD
Дата 19.8.2012, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 26.11.2011

Репутация: нет
Всего: нет



leniviy, Спасибо. Буду разбираться.
PM MAIL   Вверх
CWD
Дата 22.8.2012, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 26.11.2011

Репутация: нет
Всего: нет



Возникла небольшая идея переписать функцию как класс. Но что-то ничего не получается.

stdafx.cpp
Код

#include "stdafx.h"
#include <windows.h>
#include <time.h>
#define MAX_HEIGHT 620
#define MAX_WIDTH 1440

void A::init()
{
    HWND window = GetDesktopWindow();
    RECT windowRect;
    GetWindowRect(window, &windowRect);
    int bitmap_dx = windowRect.right-windowRect.left;
    int bitmap_dy = windowRect.bottom-windowRect.top;
    BITMAPINFO info;
    BITMAPINFOHEADER &bmpInfoHeader = info.bmiHeader;
    BITMAP* pBitmap;
    bmpInfoHeader.biSize = sizeof(bmpInfoHeader);
    bmpInfoHeader.biWidth = MAX_WIDTH;
    bmpInfoHeader.biHeight = MAX_HEIGHT;
    bmpInfoHeader.biPlanes = 1;
    bmpInfoHeader.biBitCount = 32;
    bmpInfoHeader.biCompression = BI_RGB;
    bmpInfoHeader.biSizeImage = bmpInfoHeader.biWidth*bmpInfoHeader.biHeight*(bmpInfoHeader.biBitCount/8);
    bmpInfoHeader.biXPelsPerMeter = 0;
    bmpInfoHeader.biYPelsPerMeter = 0;
    bmpInfoHeader.biClrUsed = 0;
    bmpInfoHeader.biClrImportant = 0;
    HDC winDC = GetWindowDC(window);
    HDC bmpDC = CreateCompatibleDC(winDC);
   
    BYTE* bitPointer;
    HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, (void**)&bitPointer, NULL, 0);
    SelectObject(bmpDC, bitmap);//Выбираем в контекст битмэп
    BitBlt(bmpDC, 0, 0, MAX_WIDTH, MAX_HEIGHT, winDC, 0, 0, SRCCOPY);
    ReleaseDC(window, winDC);
}

void A::Plus(int IRed,int IGreen, int IBlue)
{
    init();
    if (1) {
      for (int y = 0; y < MAX_HEIGHT; y++) for (int x = 0; x < MAX_WIDTH; x++)
      {
        BYTE *ppoint = &bitPointer[4*( MAX_WIDTH*(MAX_HEIGHT-1 - y) + x)];
          int red, green, blue, alpha;
          red = (int)ppoint[0];
          green = (int)ppoint[1];
          blue = (int)ppoint[2];
          alpha = (int)ppoint[3];
          if (0 || (red == IBlue && green == IGreen && blue == IRed))
          {
              SetCursorPos(x,y);
              mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0);
              mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
              Sleep(2000);
              break;
          }
      }
     
    }
}


stdafx.h
Код

#pragma once

class A
{

private:
//BYTE* bitPointer;
    void init(void);
public:
    void Plus(int IRed,int IGreen, int IBlue);
};


Постоянно выдает ошибку error C2065: 'bitPointer' : undeclared identifier.. Описать переменную в файле h тоже не получается. Буду благодарен если подскажете почему. Спасибо.

Это сообщение отредактировал(а) CWD - 22.8.2012, 10:40
PM MAIL   Вверх
leniviy
Дата 22.8.2012, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



убери "BYTE* bitPointer;" из функции init() и раскоментируй "//BYTE* bitPointer;" в .h файле
и добавь
Код

#include <windows.h>

вначале .h файла

Это сообщение отредактировал(а) leniviy - 22.8.2012, 10:51
PM MAIL   Вверх
CWD
Дата 22.8.2012, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 26.11.2011

Репутация: нет
Всего: нет



Спасибо. Модифицировал функцию ClickPixel(Красный, Зеленый,Синий,Кордината Х, Коодината Y), которая в идеале должна была бы проверить цвет точки в координатах и вернуть значение типа true false. При смене цвета точки программа в лучшем случае вылетает. Не могу разобраться почему.

Код

#include <iostream>
#include <cstdio>
#include <windows.h>
#define MAX_WIDTH 100
#define MAX_HEIGHT 100
using namespace std;
class A
{
private:
    BITMAP* pBitmap;
    BYTE* bitPointer;
    bool ClickPixel(int Red, int Green, int Blue, int X, int Y)
    {
        long int a=0;
        long int b=0;
        init();
        if (1) {
          for (int y = 0; y < MAX_HEIGHT; y++) for (int x = 0; x < MAX_WIDTH; x++)
          {
            BYTE *ppoint = &bitPointer[4*( MAX_WIDTH*(MAX_HEIGHT-1 - y) + x)];
              int red, green, blue, alpha;
              red = (int)ppoint[0];
              green = (int)ppoint[1];
              blue = (int)ppoint[2];
              alpha = (int)ppoint[3];
              if (0 || (red == Blue && green == Green && blue == Red))
              {
                  SetCursorPos(x,y);
                  a=x;
                  b=y;
                  Sleep(50);
                  break;
              }
          }
        }
        if (a == X && b == Y) {exit(1);} else { return true;}
    }
    void init (void)
    {
        HWND window = GetDesktopWindow();
    RECT windowRect;
    GetWindowRect(window, &windowRect);
    int bitmap_dx = windowRect.right-windowRect.left;
    int bitmap_dy = windowRect.bottom-windowRect.top;
    BITMAPINFO info;
    BITMAPINFOHEADER &bmpInfoHeader = info.bmiHeader;
    bmpInfoHeader.biSize = sizeof(bmpInfoHeader);
    bmpInfoHeader.biWidth = MAX_WIDTH;
    bmpInfoHeader.biHeight = MAX_HEIGHT;
    bmpInfoHeader.biPlanes = 1;
    bmpInfoHeader.biBitCount = 32;
    bmpInfoHeader.biCompression = BI_RGB;
    bmpInfoHeader.biSizeImage = bmpInfoHeader.biWidth*bmpInfoHeader.biHeight*(bmpInfoHeader.biBitCount/8);
    bmpInfoHeader.biXPelsPerMeter = 0;
    bmpInfoHeader.biYPelsPerMeter = 0;
    bmpInfoHeader.biClrUsed = 0;
    bmpInfoHeader.biClrImportant = 0;
    HDC winDC = GetWindowDC(window);
    HDC bmpDC = CreateCompatibleDC(winDC);
    HBITMAP bitmap = CreateDIBSection(winDC, &info, DIB_RGB_COLORS, (void**)&bitPointer, NULL, 0);
    SelectObject(bmpDC, bitmap);//Выбираем в контекст битмэп
    BitBlt(bmpDC, 0, 0, MAX_WIDTH, MAX_HEIGHT, winDC, 0, 0, SRCCOPY);
    ReleaseDC(window, winDC);

    }
public:
    
    void test(void)
    {
        while (ClickPixel(81,36,156,15,11))
        {
            cout << "test" << endl;
        }
    }
};

int main()
{
  A a;
  a.test();
  system("pause");
  return 0;
}

PM MAIL   Вверх
leniviy
Дата 22.8.2012, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: 1
Всего: 5



Я думаю, просто память кончается.
У тебя Sleep() только если находит, поэтому он успевает сделать кучу скриншотов, а bitPointer надо освобождать после использования.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0577 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.