I have an HDC file(that is taken by screen that I want to save it to any image file (prefer Bmp) , the thing is I don't really know the format and any function that I find for saving takes to many function inputs (that must be maximum 2). Any help saving it?

int nScreenWidth = GetSystemMetrics(SM_CXSCREEN);
int nScreenHeight = GetSystemMetrics(SM_CYSCREEN);
HWND hDesktopWnd = GetDesktopWindow();
HDC hDesktopDC = GetDC(hDesktopWnd);
HDC hCaptureDC = CreateCompatibleDC(hDesktopDC);
HBITMAP hCaptureBitmap =CreateCompatibleBitmap(hDesktopDC, 
nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC,hCaptureBitmap); 
BitBlt(hCaptureDC,0,0,nScreenWidth,nScreenHeight,
hDesktopDC,0,0,SRCCOPY);// |CAPTUREBLT); 
SaveBitmap("Screen Capture.bmp",hCaptureBitmap);<----- //Save Bmp 
//here to save the captured image to disk
ReleaseDC(hDesktopWnd,hDesktopDC);
DeleteDC(hCaptureDC);
DeleteObject(hCaptureBitmap);
#include <vector>
#include <fstream>
#include <cstring>
#include <windows.h>

bool HDCToFile(const char* FilePath, HDC Context, RECT Area, uint16_t BitsPerPixel = 24)
{
    uint32_t Width = Area.right - Area.left;
    uint32_t Height = Area.bottom - Area.top;

    BITMAPINFO Info;
    BITMAPFILEHEADER Header;
    memset(&Info, 0, sizeof(Info));
    memset(&Header, 0, sizeof(Header));
    Info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    Info.bmiHeader.biWidth = Width;
    Info.bmiHeader.biHeight = Height;
    Info.bmiHeader.biPlanes = 1;
    Info.bmiHeader.biBitCount = BitsPerPixel;
    Info.bmiHeader.biCompression = BI_RGB;
    Info.bmiHeader.biSizeImage = Width * Height * (BitsPerPixel > 24 ? 4 : 3);
    Header.bfType = 0x4D42;
    Header.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);


    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;
    }

    DeleteObject(Section);
    return false;
}

int main()
{
    HWND win = GetDesktopWindow();
    HDC dc = GetDC(win);
    HDCToFile("C:/.../Desktop/Foo.bmp", dc, {0, 0, 1366, 768});
    ReleaseDC(win, dc);
}

Edited 2 Years Ago by triumphost

Btw.. You can set: Info.bmiHeader.biSizeImage = Width * Height * (BitsPerPixel > 24 ? 4 : 3); to 0 instead. It'd auto calculate it for you. I just chose to show you how it actually does it (an approximation). The real calculation is done at line 38.. So it's better to set line 21 to 0 or remove it.

Edited 2 Years Ago by triumphost

This article has been dead for over six months. Start a new discussion instead.