2

I'm making a C++ program which takes screenshot of the entire screen. I am facing quite a problem. When I run the program, it takes screenshot of the console screen only, not the entire desktop.

 HDC Screen = CreateDC(L"DISPLAY", NULL, NULL, NULL);
    HDC Capture = CreateCompatibleDC(Screen);
    int width = GetDeviceCaps(Screen, HORZRES);
    int height = GetDeviceCaps(Screen, VERTRES);
    LPBYTE lpcapture;
    BITMAPINFO bmiCapture = 
    { {        sizeof(BITMAPINFOHEADER),width,height,1,24,BI_RGB,0,0,0,0,0 } };
    HBITMAP hbmCapture = CreateDIBSection(Screen, &bmiCapture, DIB_RGB_COLORS, (LPVOID *)&lpcapture, NULL, 0);
    if (hbmCapture)
    {
        HBITMAP hbmOld = (HBITMAP) SelectObject(Capture, Capture);
        BitBlt(Capture, 0, 0, width, height, Screen, 0, 0, SRCCOPY);
        SelectObject(Capture, hbmOld);
    }
    DeleteDC(Capture);
    DeleteDC(Screen);
    return hbmCapture;
  • Possible duplicate of [Desktop Window Manager capture the whole screen](http://stackoverflow.com/questions/1800898/desktop-window-manager-capture-the-whole-screen) – jww Mar 15 '15 at 05:25
  • I use the WinSnap tool, pay version. It's good (although it was better in the previous version). Not perfect but good. It demonstrates that contrary to the selected answer of the suggested duplicate, this is very much possible. – Cheers and hth. - Alf Mar 15 '15 at 06:21
  • http://stackoverflow.com/questions/3291167/how-to-make-screen-screenshot-with-win32-in-c The answer for how to copy the full screen to the clipboard works for me in Windows 7 and captures both of my monitors. Try it and see if it's a dupe. – Retired Ninja Mar 15 '15 at 06:25
  • I just tested this on win 8.1 and it works fine. I put it in a Windows program, I don't know what you mean by console screen. Maybe try `GetSystemMetrics(SM_CXFULLSCREEN);` and `SM_CYFULLSCREEN` for width and height. – Barmak Shemirani Mar 15 '15 at 07:01
  • i am making a console program to capture screenshot. So, i told that. it took screenshot of the console screen only –  Mar 15 '15 at 12:59

1 Answers1

2

This should work in a console program, but it would show black console screen in the middle

int ScreenCapture(const char* fname)
{
    int result = 0; 
    HWND hWnd = GetDesktopWindow();
    HBITMAP hbmScreen = NULL;
    HDC hdcScreen = GetDC(NULL);
    HDC hdcWindow = GetDC(hWnd);
    int w = GetSystemMetrics(SM_CXSCREEN);
    int h = GetSystemMetrics(SM_CYSCREEN);

    HDC hdcMemDC = CreateCompatibleDC(hdcWindow);
    if (!hdcMemDC) goto cleanup;

    hbmScreen = CreateCompatibleBitmap(hdcWindow, w, h);
    if (!hbmScreen) goto cleanup;

    SelectObject(hdcMemDC, hbmScreen);
    if (!BitBlt(hdcMemDC, 0, 0, w, h, hdcWindow, 0, 0, SRCCOPY)) goto cleanup;

    BITMAPFILEHEADER   bmfHeader;
    BITMAPINFOHEADER   bi;

    bi.biSize = sizeof(BITMAPINFOHEADER);
    bi.biWidth = w;
    bi.biHeight = h;
    bi.biPlanes = 1;
    bi.biBitCount = 32;
    bi.biCompression = BI_RGB;
    bi.biSizeImage = 0;
    bi.biXPelsPerMeter = 0;
    bi.biYPelsPerMeter = 0;
    bi.biClrUsed = 0;
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((w * bi.biBitCount + 31) / 32) * 4 * h;

    HANDLE hDIB = GlobalAlloc(GHND, dwBmpSize);
    char* lpbitmap = (char*)GlobalLock(hDIB);

    GetDIBits(hdcWindow, hbmScreen, 0, h, lpbitmap, (BITMAPINFO*)&bi, DIB_RGB_COLORS);

    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);
    bmfHeader.bfSize = dwBmpSize + sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
    bmfHeader.bfType = 0x4D42; //'BM' for Bitmaps

    DWORD temp = 0;
    HANDLE hFile = CreateFileA(fname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &temp, NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &temp, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &temp, NULL);
    CloseHandle(hFile); 

    GlobalUnlock(hDIB); 
    GlobalFree(hDIB);

    result = 1; //success

cleanup:
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(NULL, hdcScreen);
    ReleaseDC(hWnd, hdcWindow);

    return result;
}
Barmak Shemirani
  • 26,741
  • 4
  • 33
  • 61
  • if i run the console in stealth mode, then it won't show the console window rt –  Mar 15 '15 at 17:58