Vic*_*huk 4 c windows mouse winapi 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);
Run Code Online (Sandbox Code Playgroud)
所以这部分工作正常,它在活动窗口上绘制当前光标。但这不是我想要的。我想得到一个像素数组,所以我应该在内存中绘制它。
我正在尝试这样做:
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
Run Code Online (Sandbox Code Playgroud)
为什么 GetPixel() 不返回 COLORREF?我错过了什么?
我对 WinAPI 不是很有经验,所以我可能犯了一些愚蠢的错误。
您必须在设备上下文中选择您创建的位图。如果没有,该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);
Run Code Online (Sandbox Code Playgroud)
但是最后一个警告-该DrawIcon功能将很可能因为你所期望无法正常工作。它仅限于以默认大小绘制图标或光标。在大多数系统上,这将是 32x32。从文档:
DrawIcon使用图标的系统度量值指定的宽度和高度绘制图标或光标;有关更多信息,请参阅GetSystemMetrics。
相反,您可能想要使用DrawIconEx函数。以下代码将在资源的实际大小处绘制光标:
DrawIconEx(hdcMem, 0, 0, ci.hCursor, 0, 0, 0, NULL, DI_NORMAL);
Run Code Online (Sandbox Code Playgroud)