【问题标题】:WinAPI get mouse cursor iconWinAPI 获取鼠标光标图标
【发布时间】:2012-05-15 05:17:32
【问题描述】:

我想在 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 不是很有经验,所以我可能犯了一些愚蠢的错误。

【问题讨论】:

    标签: c windows winapi mouse mouse-cursor


    【解决方案1】:

    您必须在设备上下文中选择您创建的位图。如果没有,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);
    

    【讨论】:

    • 不确定旧版本的 Windows,但在 Windows 10 和 11 上,DrawIconEx() 会忽略设置中配置的大小,始终处理 32x32px 光标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 2010-10-29
    • 2011-04-19
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多