Растровое изображение курсора мыши - PullRequest
1 голос
/ 30 сентября 2010

Я пытаюсь получить растровое изображение от курсора мыши, но с помощью следующего кода я просто не могу получить цвета.

CURSORINFO cursorInfo = { 0 };
cursorInfo.cbSize = sizeof(cursorInfo);

if (GetCursorInfo(&cursorInfo))  {

    ICONINFO ii = {0};
    int p = GetIconInfo(cursorInfo.hCursor, &ii);

    // get screen
    HDC dc = GetDC(NULL);
    HDC memDC = CreateCompatibleDC(dc);
    //SelectObject(memDC, ii.hbmColor);

    int counter = 0;

    //
    byte* bits[1000];// = new byte[w * 4]; 
    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(BITMAPINFO)); 
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = 16;
    bmi.bmiHeader.biHeight = 16;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage     = 0;
    bmi.bmiHeader.biXPelsPerMeter = 0;
    bmi.bmiHeader.biYPelsPerMeter = 0;
    bmi.bmiHeader.biClrUsed       = 0;
    bmi.bmiHeader.biClrImportant  = 0;
    int rv = ::GetDIBits(memDC, ii.hbmColor, 0, 1, (void**)&bits, &bmi, DIB_RGB_COLORS);
}

Ответы [ 2 ]

1 голос
/ 16 июня 2011

Начните с получения параметров растрового изображения, записанных Windows:

BITMAP bitmap = {0};
GetObject(ii.hbmColor, sizeof(bitmap), &bitmap);

Вы можете использовать возвращаемые значения для заполнения структуры bmi.

И о bmi структура: BITMAPINFO не не резервирует достаточно места для палитры.Вы должны создать свою собственную структуру для этого:

struct BitmapPlusPalette
{
    BITMAPINFOHEADER bmiHeader;
    RGBQUAD palette[256];
};

Вычислить количество байтов, необходимых для растрового изображения, немного сложно, потому что его необходимо округлить:

w = ((bitmap.bmWidth * bitmap.bmBitsPixel) + 31) / 8;
byte* bits = new byte[w * bitmap.bmHeight];

исправленная версия вашей последней строки:

int rv = ::GetDIBits(dc, ii.hbmColor, 0, bitmap.bmHeight, bits, (BITMAPINFO *)&bmi, DIB_RGB_COLORS);
0 голосов
/ 16 июня 2011

Проблема с вашим кодом, я думаю, в том, как вы выделили память для переменной 'bits' и как вы использовали ее тогда в функции GetDIBits.

Во-первых, комментируемая часть byte* bits = new byte[w*4] была лучше, чем byte* bits[1000]. Когда вы пишете byte* bits[1000], компьютер выделяет 1000 указателей на байт. Каждый из этих указателей ни на что не указывает.

Во-вторых, GetDIBits принимает LPVOID lpvBits в качестве 5-го параметра. Таким образом, это указатель на пустоту. В большинстве платформ sizeof (void *)> sizeof (byte), поэтому вы не можете просто передать ему байтовый массив, возможно, было бы лучше передать указатель на int или unsigned int (я не очень хорош в типах Windows, так что, может быть, что-то более подходящее должно быть лучше, извините).

Итак, я думаю, это:

unsigned bits[1000];
memset(bits, 0, sizeof(bits));
//...
int tv = GetDIBits(memDC, ii.hmbColor, 0, 1, (LPVOID)bits, /* ... */);
...