WinAPI получает значок курсора мыши

Я хочу получить значок курсора в 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, поэтому, наверное, совершаю какую-то глупую ошибку.


person Victor Marchuk    schedule 06.05.2012    source источник


Ответы (1)


Вы должны выбрать растровое изображение, которое вы создаете, в контексте устройства. В противном случае функция GetPixel вернет CLR_INVALID (0xFFFFFFFF):

Растровое изображение должно быть выбрано в контексте устройства, в противном случае для всех пикселей возвращается CLR_INVALID.

Кроме того, показанный вами псевдокод сильно пропускает объекты. Каждый раз, когда вы вызываете GetDC, вы должны вызывать 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 функция будет вероятно не получится, как вы ожидали. Он ограничен рисованием значка или курсора с размером по умолчанию. В большинстве систем это будет 32x32. Из документации:

DrawIcon рисует значок или курсор, используя ширину и высоту, заданные системными значениями метрики для значков; для получения дополнительной информации см. GetSystemMetrics.

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

DrawIconEx(hdcMem, 0, 0, ci.hCursor, 0, 0, 0, NULL, DI_NORMAL);
person Cody Gray    schedule 06.05.2012