为什么 CreateCompatibleBitmap() 与 CreateCompatibleDC() 不兼容

Why CreateCompatibleBitmap() isn't compatible with CreateCompatibleDC()

我创建了一个应该截屏的小程序。我想了解第 11 行:

HBITMAP hbm = CreateCompatibleBitmap(hdcmem, w, h);

如果我用桌面DC调用CreateCompatibleBitmap,效果很好;但是,如果我将 hdcmem 作为第一个参数,就会出错:缓冲区最终为空。如果 hdcmem 与桌面 DC 兼容,为什么会这样?

#include <Windows.h>
#include <fstream>
int main()
{
    UINT w = 100;
    UINT h = 100;
    UINT bitsPerPix = 24;
    UINT buffSize = (w * bitsPerPix + 31) / 32 * 4 * h;
    HDC desktop = GetDC(0);
    HDC hdcmem = CreateCompatibleDC(desktop);
    HBITMAP hbm = CreateCompatibleBitmap(hdcmem, w, h);
    hbm = (HBITMAP)SelectObject(hdcmem, hbm);
    BitBlt(hdcmem, 0, 0, w, h, desktop, 0, 0, SRCCOPY);
    hbm = (HBITMAP)SelectObject(hdcmem, hbm);
    BITMAPFILEHEADER bmf{};
    bmf.bfType = 0x4d42;
    bmf.bfOffBits = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER;
    bmf.bfSize = sizeof BITMAPFILEHEADER + sizeof BITMAPINFOHEADER + buffSize;
    BITMAPINFOHEADER bmi{};
    bmi.biSize = sizeof bmi;
    bmi.biWidth = w;
    bmi.biHeight = h;
    bmi.biBitCount = bitsPerPix;
    bmi.biCompression = 0;
    bmi.biPlanes = 1;
    char* buff = new char[buffSize];
    GetDIBits(hdcmem, hbm, 0, h, buff, (LPBITMAPINFO)&bmi, DIB_RGB_COLORS);
    std::ofstream ofile("D:\test.bmp", std::ios_base::binary);
    ofile.write((char*)&bmf, sizeof bmf);
    ofile.write((char*)&bmi, sizeof bmi);
    ofile.write(buff, buffSize);
    ofile.close();
    delete[] buff;
    DeleteObject(hbm);
    DeleteDC(hdcmem);
    ReleaseDC(0, desktop);
    return 0;
}

CreateCompatibleBitmap 函数创建一个与 物理设备 兼容的位图,该位图与作为其第一个参数传递的设备上下文相关联。内存设备上下文没有这样的关联物理设备,那么该位图将与什么兼容?可能,虽然没有明确记录,但它将与当前选择的位图兼容——对于newly-created内存DC是1 x 1 单色 位图。

来自the documentation

Note: When a memory device context is created, it initially has a 1-by-1 monochrome bitmap selected into it. If this memory device context is used in CreateCompatibleBitmap, the bitmap that is created is a monochrome bitmap. To create a color bitmap, use the HDC that was used to create the memory device context, as shown in the following code …