Search code examples
c++imagemfcscreenshotcbitmap

Screen capture only returns a black image


I'm trying to take a screen capture of the main dialog in my MFC application and save it as an image file. I tried about every example I could find online and always end up with the same result: the image file has the correct dimensions (I tried this with dialogs other than the main one just to be sure), but it is all black. My most recent solution is using the CBitmap class to transfer the main dialog handle to a CImage. Here is my code:

CWnd* mainWindow;
CDC* mainWindowDC;
CBitmap bitmapToSave;
CImage imageToSave;
CRect windowRect;

//Get main window context and create bitmap from it
mainWindow = AfxGetMainWnd();
mainWindowDC = mainWindow->GetWindowDC();
mainWindow->GetWindowRect(&windowRect);
bitmapToSave.CreateCompatibleBitmap(mainWindowDC, windowRect.Width(), windowRect.Height());
imageToSave.Attach(bitmapToSave);
imageToSave.Save("C:\\Capture\\image.bmp", Gdiplus::ImageFormatBMP);

Solution

  • Here is the way to do it:

    HRESULT CaptureScreen(const CString& sImageFilePath)
    {
       CWnd* pMainWnd = AfxGetMainWnd();
       CRect rc;
       pMainWnd->GetWindowRect(rc);
       CImage img;
       img.Create(rc.Width(), rc.Height(), 24);
       CDC memdc;
       CDC* pDC = pMainWnd->GetWindowDC();
       memdc.CreateCompatibleDC(pDC);
       CBitmap* pOldBitmap = memdc.SelectObject(CBitmap::FromHandle((HBITMAP)img));
       memdc.BitBlt(0, 0, rc.Width(), rc.Height(), pDC, 0, 0, SRCCOPY);
       memdc.SelectObject(pOldBitmap);
       return img.Save(sImageFilePath, Gdiplus::ImageFormatPNG);
    }
    

    Please also take a look at this nice implementation: http://www.codeguru.com/cpp/article.php/c18347/C-Programming-Easy-Screen-Capture-Using-MFCATL.htm