2012-05-06 157 views
4

我想在Windows中获取光标图标。 我觉得语言我用的是不是在这里非常重要,所以我只写与WinAPI的功能,我想用伪代码: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不太了解,所以我可能会犯一些愚蠢的错误。

回答

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