Get bitmap of a CF_DIBV5 from clipboard

2019-09-15 05:08发布

I'm trying to get bitmap data from the clipboard. I can successfully get the header information for the CF_DIBV5 object:

    BOOLEAN exists = IsClipboardFormatAvailable(CF_DIBV5) &&
        OpenClipboard(session->windowHandle);

    if (exists) {
        HGLOBAL clipboard = GetClipboardData(CF_DIBV5);
        exists = clipboard != NULL;
        if (exists) {
            LPTSTR lptstr = GlobalLock(clipboard);
            exists = lptstr != NULL;
            if (exists) {
                BITMAPV5HEADER * header = clipboard;
                //now need the HBITMAP!
            }
        }
    }
    //...

I can successfully log info from the header. Now I want the actual HBITMAP so I can pass it into GetDIBits. The docs say CF_DIBV5 is a BITMAPV5HEADER "followed by the bitmap color space information and the bitmap bits".

That last part confuses me ironically because it's in plain English. I assume to get to the bitmap bits, I need to add the size of the header and the "color space information" to the header pointer. So

HBITMAP bitmap = header + sizeof(BITMAPV5HEADER) + /* ???? */;

I think...

How can I know the size of this mysterious color space information? And are the "bitmap bits" literally an HBITMAP such that the above expression would be true?

I may be overlooking the obvious since I am a C newbie.

Update: I now realize from experimenting and rereading some documentation that an HBITMAP is a DDB, whereas I have a DIB. So GetDIBits is not the right function for me. What function can be used to convert any DIB to a format with no compression?

1条回答
Animai°情兽
2楼-- · 2019-09-15 05:34

Here's how to get the appropriate pointer to the bitmap bits. The arrangement of the contents depends on the compression type and bit count described in the header.

HGLOBAL clipboard = GetClipboardData(CF_DIBV5);
BITMAPV5HEADER* bitmapV5Header = (BITMAPV5HEADER*)GlobalLock(clipboard);
int offset = bitmapV5Header->bV5Size + bitmapV5Header->bV5ClrUsed * sizeof(RGBQUAD);
if (bitmapV5Header->bV5Compression == BI_BITFIELDS)
    offset += 12; //bit masks follow the header
BYTE *bits = (BYTE*)bitmapV5Header + offset;
查看更多
登录 后发表回答