I'm trying to take a screenshot of a given window and store the bytes into an array. I've already seen this article
Screen capture of specific window c++
but it can't solve my problem (I think). Here's what I've got so far. The code only works partially, namely the width and height are correct. It fails to get the colors of the pixels (because they are all 0 at the end of the function).
And now I'm stuck because I don't know how to further approach this.
edit note: Although I output it as a .bmp I still need the pixels values in the BYTE array.
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
void screenshot(BYTE **Pixels, char *Window)
{
// take a screenshot
HWND hWnd = FindWindowA(NULL, Window);
if(!hWnd) return;
HDC hScreen = GetWindowDC(hWnd);
if(!hScreen) return;
RECT rWnd;
if(!GetWindowRect(hWnd, &rWnd)) return;
int Width = rWnd.right - rWnd.left;
int Height = rWnd.bottom - rWnd.top;
HDC hdcMem = CreateCompatibleDC(hScreen);
if(!hdcMem) return;
HBITMAP hBitmap = CreateCompatibleBitmap(hScreen, Width, Height);
if(!hBitmap) return;
HGDIOBJ hOld = SelectObject(hdcMem, hBitmap);
if(!hOld) return;
if(!BitBlt(hdcMem, 0, 0, Width, Height, hScreen, 0, 0, SRCCOPY)) return;
if(!SelectObject(hdcMem, hOld)) return;
BITMAPINFOHEADER BitmapInfoHeader = {0};
BitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
BitmapInfoHeader.biPlanes = 1;
BitmapInfoHeader.biBitCount = 32;
BitmapInfoHeader.biWidth = Width;
BitmapInfoHeader.biHeight = -Height;
BitmapInfoHeader.biCompression = BI_RGB;
BitmapInfoHeader.biSizeImage = 4 * Width * Height;
if(*Pixels)
{
free(*Pixels);
}
*Pixels = malloc(sizeof **Pixels * 4 * Width * Height);
if(!*Pixels)
{
return;
}
if(!GetDIBits(hdcMem, hBitmap, 0, Height, *Pixels, (BITMAPINFO*)&BitmapInfoHeader, DIB_RGB_COLORS)) return;
ReleaseDC(GetDesktopWindow(),hScreen);
DeleteDC(hdcMem);
DeleteObject(hBitmap);
// save as a bitmap
FILE * file = fopen("image.bmp", "wb");
if(!file) return;
// file header
BITMAPFILEHEADER BitmapFileHeader = {0};
BitmapFileHeader.bfType = 0x4D42;
BitmapFileHeader.bfOffBits = 40 + 14;
BitmapFileHeader.bfSize = 40 + 14 + BitmapInfoHeader.biSizeImage;
fwrite(&BitmapFileHeader.bfType, 2, 1, file);
fwrite(&BitmapFileHeader.bfSize, 4, 1, file);
fwrite(&BitmapFileHeader.bfReserved1, 2, 1, file);
fwrite(&BitmapFileHeader.bfReserved2, 2, 1, file);
fwrite(&BitmapFileHeader.bfOffBits, 4, 1, file);
// info header
fwrite(&BitmapInfoHeader.biSize, 4, 1, file);
fwrite(&BitmapInfoHeader.biWidth, 4, 1, file);
fwrite(&BitmapInfoHeader.biHeight, 4, 1, file);
fwrite(&BitmapInfoHeader.biPlanes, 2, 1, file);
fwrite(&BitmapInfoHeader.biBitCount, 2, 1, file);
fwrite(&BitmapInfoHeader.biCompression, 4, 1, file);
fwrite(&BitmapInfoHeader.biSizeImage, 4, 1, file);
fwrite(&BitmapInfoHeader.biXPelsPerMeter, 4, 1, file);
fwrite(&BitmapInfoHeader.biYPelsPerMeter, 4, 1, file);
fwrite(&BitmapInfoHeader.biClrUsed, 4, 1, file);
fwrite(&BitmapInfoHeader.biClrImportant, 4, 1, file);
// pixels
fwrite(*Pixels, BitmapInfoHeader.biSizeImage, 1, file);
fclose(file);
}
int main(int argc, char **argv)
{
BYTE *byte;
screenshot(&byte, "Rechner");
printf("hello world\n");
return 0;
}