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