Search code examples
c++windowswinapibitmapscreenshot

Getting a Bitmap Object of a screenshot in VC++


I'm trying to write a program that grabs a screen shot of the current active window and then does some basic computer vision with the result. The current code I have is as follows:

RECT rc;
HWND hwnd = GetForegroundWindow();    //the window can't be min
if(hwnd == NULL) {
    cerr << "it can't find any 'note' window" << endl;
    system ("pause");
    return 0;
}
GetClientRect(hwnd, &rc);

//create
HDC hdcScreen = GetDC(NULL);
HDC hdc = CreateCompatibleDC(hdcScreen);
HBITMAP hbmp = CreateCompatibleBitmap(hdcScreen, rc.right - rc.left, rc.bottom - rc.top);
SelectObject(hdc, hbmp);

//Print to memory hdc
PrintWindow(hwnd, hdc, PW_CLIENTONLY);

//Get the bitmap
BITMAP bm;
GetObject (hbmp, sizeof(bm), &bm);

//release
DeleteDC(hdc);
DeleteObject(hbmp);
ReleaseDC(NULL, hdcScreen);

After everything's said an done, bm.bmBits is NULL. This is especially strange because all of bm's other fields are correct. Obviously I can't do very much without bm.bmBits. Could anyone tell me what I'm doing wrong?

This code is mostly copied from the answer to another question, but in that code handle to a bitmap was never transferred into a BITMAP struct, but instead was used to add the bitmap to the clipboard. Since I want to process the screenshot immediately, I'd rather extract the data within the handle immediately and process it.


Solution

  • bm.bmBits is NULL because you don't own the memory referenced by the bitmap. You need to have the kernel copy them for you, using GetDIBits or the like.