Many forums give the following code regarding how to get into an array a copy of the screen's pixels:
char* Pixels = NULL;
HDC MemDC = CreateCompatibleDC(Context);
HBITMAP Section = CreateDIBSection(Context, &Info, DIB_RGB_COLORS, (void**)&Pixels, 0, 0);
DeleteObject(SelectObject(MemDC, Section));
BitBlt(MemDC, 0, 0, Width, Height, Context, Area.left, Area.top, SRCCOPY);
DeleteDC(MemDC);
std::fstream hFile(FilePath, std::ios::out | std::ios::binary);
if (hFile.is_open())
{
hFile.write((char*)&Header, sizeof(Header));
hFile.write((char*)&Info.bmiHeader, sizeof(Info.bmiHeader));
hFile.write(Pixels, (((BitsPerPixel * Width + 31) & ~31) / 8) * Height);
hFile.close();
DeleteObject(Section);
return true;
}
(Link)
But this involves actually copying the pixels "memory" area from screen HDC to an in-memory one. Why not this:
char* Pixels = NULL;
HBITMAP Section = CreateDIBSection(Context, &Info, DIB_RGB_COLORS, (void**)&Pixels, 0, 0);
SelectObject(Context, Section);
The Context HDC already contains all the data. Why can't I just read it?
And I thought that a bitmap must be selected into a HDC and that the HDC actually carries the data. Then why does CreateDIBSection
return a pointer although the bitmap was not yet selected into any HDC? (If it gives a pointer to the memory of the HDC passed as argument then the array already contains the screen's pixels values but this is not the case because BitBlt
is still required.)
I reached this conclusion because BitBlt accepts an HDC argument, not a bitmap. This probably means it copies the data to the associated HDC.