Растровое изображение курсора мыши

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

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); } 

Начните с получения параметров растрового изображения, записанного 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); 

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

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

Во-вторых, GetDIBits принимает LPVOID lpvBits как пятый параметр. Итак, это указатель на пустоту. В большинстве платформ 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, /* ... */);