鼠标光标位图

发布于 2024-09-25 05:49:01 字数 1038 浏览 3 评论 0原文

我试图从鼠标光标获取位图,但在下一个代码中,我无法获取颜色。

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

I am trying to get bitmap from mouse cursor, but with next code, i just can't get colors.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

别闹i 2024-10-02 05:49:01

首先获取 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);

Start by getting the parameters of the bitmap as recorded by Windows:

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

You can use the returned values to populate the bmi structure.

And about the bmi structure: BITMAPINFO does not reserve enough space for a palette. You should create your own structure for this:

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

Calculating the number of bytes needed for the bitmap is a bit tricky because it needs to be rounded up:

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

And here's a corrected version of your final line:

int rv = ::GetDIBits(dc, ii.hbmColor, 0, bitmap.bmHeight, bits, (BITMAPINFO *)&bmi, DIB_RGB_COLORS);
残龙傲雪 2024-10-02 05:49:01

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

首先,注释部分byte* bits = new byte[w*4]byte* bits[1000]要好。当您写入 byte* bits[1000] 时,计算机会为 byte 分配 1000 个指针。这些指针中的每一个都没有指向任何东西。

其次,GetDIBits 接受 LPVOID lpvBits 作为第五个参数。所以,它是一个指向 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, /* ... */);

The problem with your code I think is in the way you allocated memory for 'bits' variable and how you used it then in GetDIBits function.

Firstly, the commented part byte* bits = new byte[w*4] was better than byte* bits[1000]. When you write byte* bits[1000] computer allocates 1000 POINTERS to byte. Each of these pointers doesn't point to anything.

Secondly, GetDIBits accepts LPVOID lpvBits as a 5th param. So, its a pointer to void.
In most platforms sizeof(void *) > sizeof(byte), so you can't just pass it a byte array, probably it would be better to pass a pointer to int or unsigned int (I'm not good at Windows types, so maybe something more appropriate should be better, sorry).

So, my guess is this:

unsigned bits[1000];
memset(bits, 0, sizeof(bits));
//...
int tv = GetDIBits(memDC, ii.hmbColor, 0, 1, (LPVOID)bits, /* ... */);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文