【问题标题】:Mouse cursor bitmap鼠标光标位图
【发布时间】:2011-04-19 08:16:08
【问题描述】:

我正在尝试从鼠标光标获取位图,但是使用下一个代码,我无法获取颜色。

CURSORINFO cursorInfo = { 0 };
cursorInfo.cbSize = sizeof(cursorInfo);

if (GetCursorInfo(&cursorInfo))  {

    ICONINFO ii = {0};
    int p = GetIconInfo(cursorInfo.hCursor, &ii);

    // get screen
    HDC dc = GetDC(NULL);
    HDC memDC = CreateCompatibleDC(dc);
    //SelectObject(memDC, ii.hbmColor);

    int counter = 0;

    //
    byte* bits[1000];// = new byte[w * 4]; 
    BITMAPINFO bmi;
    memset(&bmi, 0, sizeof(BITMAPINFO)); 
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = 16;
    bmi.bmiHeader.biHeight = 16;
    bmi.bmiHeader.biBitCount = 32;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biSizeImage     = 0;
    bmi.bmiHeader.biXPelsPerMeter = 0;
    bmi.bmiHeader.biYPelsPerMeter = 0;
    bmi.bmiHeader.biClrUsed       = 0;
    bmi.bmiHeader.biClrImportant  = 0;
    int rv = ::GetDIBits(memDC, ii.hbmColor, 0, 1, (void**)&bits, &bmi, DIB_RGB_COLORS);
}

【问题讨论】:

    标签: c windows visual-studio-2008 bitmap mouse-cursor


    【解决方案1】:

    首先获取Windows记录的位图参数:

    BITMAP bitmap = {0};
    GetObject(ii.hbmColor, sizeof(bitmap), &bitmap);
    

    您可以使用返回的值来填充bmi 结构。

    关于bmi 结构:BITMAPINFO 确实没有为调色板保留足够的空间。您应该为此创建自己的结构:

    struct BitmapPlusPalette
    {
        BITMAPINFOHEADER bmiHeader;
        RGBQUAD palette[256];
    };
    

    计算位图所需的字节数有点棘手,因为它需要四舍五入:

    w = ((bitmap.bmWidth * bitmap.bmBitsPixel) + 31) / 8;
    byte* bits = new byte[w * bitmap.bmHeight];
    

    这是您最后一行的更正版本:

    int rv = ::GetDIBits(dc, ii.hbmColor, 0, bitmap.bmHeight, bits, (BITMAPINFO *)&bmi, DIB_RGB_COLORS);
    

    【讨论】:

    • 在这种情况下,BITMAPINFO 不为完整的调色板保留空间真的很重要吗?为什么GetDIBits 会写信给它(尤其是DIB_RGB_COLORS)?
    • @jamesdlin,如果图像不需要调色板,那么你是对的,没关系。不过,确保安全并不是一个坏主意。
    【解决方案2】:

    我认为您的代码的问题在于您为“位”变量分配内存的方式以及您如何在 GetDIBits 函数中使用它。

    首先,评论部分byte* bits = new byte[w*4]优于byte* bits[1000]。当你写byte* bits[1000] 时,计算机会分配 1000 个指针给字节。这些指针中的每一个都不指向任何东西。

    其次,GetDIBits 接受 LPVOID lpvBits 作为第 5 个参数。所以,它是一个指向 void 的指针。 在大多数平台 sizeof(void *) > sizeof(byte),所以你不能只传递一个字节数组,可能最好传递一个指向 int 或 unsigned int 的指针(我不擅长 Windows 类型,所以也许更合适的东西应该更好,抱歉)。

    所以,我的猜测是这样的:

    unsigned bits[1000];
    memset(bits, 0, sizeof(bits));
    //...
    int tv = GetDIBits(memDC, ii.hmbColor, 0, 1, (LPVOID)bits, /* ... */);
    

    【讨论】:

      猜你喜欢
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-15
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多