Вопрос по windows, c, winapi – WinAPI получить значок курсора мыши

4

Я хочу получить значок курсора в Windows. Я думаю, что язык, который я использую, здесь не очень важен, поэтому я просто напишу псевдокод с функциями WinAPI, которые я пытаюсь использовать:

c = CURSORINFO.new(20, 1, 1, POINT.new(1,1));
GetCursorInfo(c); #provides correctly filled structure with hCursor

DrawIcon(GetWindowDC(GetForegroundWindow()), 1, 1, c.hCursor);

Так что эта часть работает нормально, она рисует текущий курсор на активном окне. Но это не то, что я хочу. Я хочу получить массив пикселей, поэтому я должен нарисовать его в памяти.

Я пытаюсь сделать это так:

hdc = CreateCompatibleDC(GetDC(0)); #returns non-zero int
canvas = CreateCompatibleBitmap(hdc, 256, 256); #returns non-zero int too

c = CURSORINFO.new(20, 1, 1, POINT.new(1,1));
GetCursorInfo(c);

DrawIcon(hdc, 1, 1, c.hCursor); #returns 1
GetPixel(hdc, 1, 1); #returns -1

Почему GetPixel () не возвращает COLORREF? Что мне не хватает?

Я не очень разбираюсь в WinAPI, поэтому я, вероятно, совершил какую-то глупую ошибку.

Ваш Ответ

1   ответ
4

которое вы создаете в контексте устройства. Если нет, тоGetPixel function вернусьCLR_INVALID (0xFFFFFFFF):

A bitmap must be selected within the device context, otherwise, CLR_INVALID is returned on all pixels.

Кроме того, показанный вами псевдокод плохо пропускает объекты. Всякий раз, когда вы звонитеGetDC, выmust вызовReleaseDC когда вы закончите использовать его. И всякий раз, когда вы создаете объект GDI, вы должны уничтожить его, когда закончите использовать его.

Наконец, вы, кажется, предполагаете, что координаты для исходной точки, то есть верхней левой точки, равны (1, 1). Они на самом деле (0, 0).

Вот код, который я бы написал (для краткости проверка ошибок опущена):

// Get your device contexts.
HDC hdcScreen = GetDC(NULL);
HDC hdcMem = CreateCompatibleDC(hdcScreen);

// Create the bitmap to use as a canvas.
HBITMAP hbmCanvas = CreateCompatibleBitmap(hdcScreen, 256, 256);

// Select the bitmap into the device context.
HGDIOBJ hbmOld = SelectObject(hdcMem, hbmCanvas);

// Get information about the global cursor.
CURSORINFO ci;
ci.cbSize = sizeof(ci);
GetCursorInfo(&ci);

// Draw the cursor into the canvas.
DrawIcon(hdcMem, 0, 0, ci.hCursor);

// Get the color of the pixel you're interested in.
COLORREF clr = GetPixel(hdcMem, 0, 0);

// Clean up after yourself.
SelectObject(hdcMem, hbmOld);
DeleteObject(hbmCanvas);
DeleteDC(hdcMem);
ReleaseDC(hdcScreen);

Но одна заключительная оговорка -DrawIcon function будутprobably не работает, как вы ожидаете. Он ограничен рисованием значка или курсора с размером по умолчанию. На большинстве систем это будет 32x32. Из документации:

DrawIcon draws the icon or cursor using the width and height specified by the system metric values for icons; for more information, see GetSystemMetrics.

Вместо этого вы, вероятно, хотите использоватьDrawIconEx function, Следующий код нарисует курсор на фактическом размере ресурса:

DrawIconEx(hdcMem, 0, 0, ci.hCursor, 0, 0, 0, NULL, DI_NORMAL);

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