Thread: Capturing and saving a screenshot with GDI

  1. #1
    Registered User
    Join Date
    Nov 2010
    Location
    In my house
    Posts
    32

    Capturing and saving a screenshot with GDI

    I don't know much about the GDI, but I heard it can take screenshots so I attempted to find a bit of code to do so. Problem is, after alot of debugging, I still have no idea why it isn't working.

    Whats suppose to happen: Screenshot of the desktop.
    What does happen: fully blank image filled with black.

    Its probably just a simple error that I overlooked, but I can't seem to find it.

    Heres the code.
    Code:
    	HDC Screenshot = GetDC(NULL);
    
    	int ResX = GetSystemMetrics(SM_CXSCREEN);
    	int ResY = GetSystemMetrics(SM_CYSCREEN);
    
    	HDC MemDesktop = CreateCompatibleDC(Screenshot);
    	HBITMAP tmpbitmap = CreateCompatibleBitmap(MemDesktop, ResX, ResY);
    
    	HBITMAP bitmap = (HBITMAP)SelectObject(MemDesktop, tmpbitmap);
    
    	BitBlt(MemDesktop, 0,0, ResX, ResY, Screenshot, 0,0, SRCCOPY);
    
    	BITMAPINFO BitInfo;
    
    	memset(&BitInfo, 0, sizeof(BITMAPINFO));
    
    	BitInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    	BitInfo.bmiHeader.biWidth = ResX;
    	BitInfo.bmiHeader.biHeight = ResY;
    	BitInfo.bmiHeader.biPlanes = 1;
    	BitInfo.bmiHeader.biBitCount = 16;
    	BitInfo.bmiHeader.biCompression = BI_RGB; //BI_JPEG;
    	BitInfo.bmiHeader.biSizeImage = (BitInfo.bmiHeader.biWidth * BitInfo.bmiHeader.biHeight) * 2;
    
    	void *bits = malloc(BitInfo.bmiHeader.biSizeImage);
    	GetDIBits(MemDesktop, bitmap, 0, BitInfo.bmiHeader.biHeight, bits, &BitInfo, DIB_PAL_COLORS);
    	HANDLE bmfile = CreateFile("image.bmp", GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    
    	BITMAPFILEHEADER bitheader;
    
    	bitheader.bfReserved1 = 0;
    	bitheader.bfReserved2 = 0;
    	bitheader.bfType = 0x4d42;
    	bitheader.bfOffBits = sizeof(BITMAPINFOHEADER) + sizeof(BITMAPFILEHEADER);
    	bitheader.bfSize = bitheader.bfOffBits + BitInfo.bmiHeader.biSizeImage;
    
    	DWORD bytes;
    	WriteFile(bmfile, &bitheader, sizeof(BITMAPFILEHEADER), &bytes, NULL);
    	WriteFile(bmfile, &BitInfo.bmiHeader, sizeof(BITMAPINFOHEADER), &bytes, NULL);
    	WriteFile(bmfile, bits, BitInfo.bmiHeader.biSizeImage, &bytes, NULL);
    
    	CloseHandle(bmfile);
    	free(bits);
    	DeleteDC(MemDesktop);
    	DeleteDC(Screenshot);
    	DeleteObject(bitmap);
    	DeleteObject(tmpbitmap);

  2. #2
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    I don't actually know the solution but a couple of suggestions:

    Try saving a bitmap straight from your screenshot DC? It wouldn't surprise me somewhere if Microsoft documentation said that you're not supposed to do this (in which case, don't) but as far as I can remember there isn't anything like this.

    Try calling CreateCompatibleBitmap with screenshot as the first argument instead. I have had problems in games where doing it otherwise has often made the bitmap monochrome.

    This is assuming that your bitmap writing code is correct, which I don't know anything about so I can't really check.

  3. #3
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    In addition to the above:
    Due to the extremely bad variable names, you're getting the bits of the wrong HBITMAP. tempbitmap and bitmap need to have their names switched
    The second SelectObject needs to be moved to just after the BitBlt
    You need to ReleaseDC Screenshot not DeleteDC it
    You want DIB_RGB_COLORS instead
    Don't delete the objects that are returned from SelectObject, put them back when you've finished and leave them

    In short, that code is worth exactly what you paid for copying it. I don't know if you read Italian, I certainly don't but I can tell all the code in the subsequent posts were corrections.
    Last edited by adeyblue; 05-05-2011 at 10:52 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Here is a Screenshot of my GUI for my RPG
    By eaane74 in forum Game Programming
    Replies: 33
    Last Post: 12-16-2007, 10:23 PM
  2. take screenshot
    By MeGaBiTe1 in forum Windows Programming
    Replies: 2
    Last Post: 09-02-2004, 10:33 PM
  3. get screenshot
    By Draco in forum Windows Programming
    Replies: 4
    Last Post: 04-30-2004, 06:31 AM
  4. screenshot
    By Draco in forum Windows Programming
    Replies: 2
    Last Post: 04-25-2004, 09:46 AM
  5. dvd screenshot
    By ichijoji in forum Tech Board
    Replies: 1
    Last Post: 03-27-2004, 03:07 PM