Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

I created a small program that should take a screenshot. I want to understand line 11:

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

If I call CreateCompatibleBitmap with the desktop DC, it works well; but, if I put hdcmem as the first argument, it goes wrong: The buffer ends up being empty. Why is that so if hdcmem is compatible with desktop 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;
}

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The CreateCompatibleBitmap function creates a bitmap that is compatible with the physical device that is associated with the device context passed as its first argument. A memory device context does not have such an associated physical device, so what will that bitmap be compatible with? Probably, though not explicitly documented, it will be compatible with the bitmap that is currently selected – which, for a newly-created memory DC is a 1 x 1 monochrome bitmap.

From 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 …

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading