WinAPI获取鼠标光标图标

时间:2012-05-06 09:37:04

标签: c windows winapi mouse mouse-cursor

我想在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 个答案:

答案 0 :(得分:4)

您必须在设备上下文中选择您创建的位图。如果没有,GetPixel function将返回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 function 可能 无法按预期工作。它仅限于以默认大小绘制图标或光标。在大多数系统上,这将是32x32。来自文档:

  

DrawIcon使用图标的系统指标值指定的宽度和高度绘制图标或光标;有关详细信息,请参阅GetSystemMetrics

相反,您可能想要使用DrawIconEx function。以下代码将光标绘制为资源的实际大小:

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