Thread: Screenshots

  1. #1
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145

    Screenshots

    Not sure whether this goes in GD or tech board. Anyway...

    I'm working on a game, DirectDraw (fullscreen). I want to take a screenshot of some frames, however it doesn't work using PrintScreen (Ctrl+PS, Shift+PS, tried all combos...) nor any screenshot capture programs I've tried. I believe that DirectInput, which I'm also using, somehow prevents PrintScreen commands.
    I have another DX program without DInput and PrintScreen works with it.
    Does anyone have any idea how I could take a snapshot?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #2
    5|-|1+|-|34|) ober's Avatar
    Join Date
    Aug 2001
    Posts
    4,429
    with a camera?

    :: ducks for cover ::

  3. #3
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    It shouldn't be too hard to copy the pixel data to a file and add the appropriate bitmap header.
    Use google to find the documentation of the .bmp format.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  4. #4
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    Magos,
    Here's the code I use. It's almost straight out of MSDN, just a few modifications that I made (like the typedef, etc.). All you have to do is add the files to your project, include the header file in you main file and whenever you want to take a screenshot (like when a state in your DirectInput code is updated) pass your backbuffer into the SaveScreen function.

    Of course, you could modify it to use unique filenames, like with an incrimental counter that adds a number to the end of the filename or something, but I didn't have a need for it so I never implemented it.
    Hope this helps,

    Jason

    Code:
    //in the header file, screencapture.h
    #pragma once
    
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    typdef LPDIRECTDRAWSURFACE7 lpdds7;
    
    void SaveScreen(lpdds7 sfHDC);
    PBITMAPINFO MakeBI(lpdds7 sfHDC);
    Code:
    //in the source file, screencapture.cpp
    #include "ScreenCapture.h"
    
    HBITMAP NewBmp=NULL, OldBmp=NULL;
    HDC hdcCom=NULL;
    
    void SaveScreen(lpdds7 sfHDC)
    {
    	HANDLE hf;
    	BITMAPFILEHEADER hdr;
    	PBITMAPINFOHEADER pbih;
    	LPBYTE lpBits;
    	DWORD dwTotal;
    	DWORD cb;
    	BYTE *hp;
    	DWORD dwTmp;
    	PBITMAPINFO pbiTest=MakeBI(sfHDC);
    	pbih=(PBITMAPINFOHEADER) pbiTest;
    	lpBits=(LPBYTE)GlobalAlloc(GMEM_FIXED,pbih->biSizeImage);
    	GetDIBits(hdcCom,NewBmp,0,(WORD)pbih->biHeight,lpBits,pbiTest,DIB_RGB_COLORS);
    	hf=CreateFile("screen.bmp",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
    	hdr.bfType=0x4d42;
    	hdr.bfSize=(DWORD)(sizeof(BITMAPFILEHEADER)+pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD)+pbih->biSizeImage);
    	hdr.bfReserved1=0;
    	hdr.bfReserved2=0;
    	hdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+pbih->biSize+pbih->biClrUsed*sizeof(RGBQUAD);
    	WriteFile(hf,(LPVOID)&hdr,sizeof(BITMAPFILEHEADER),(LPDWORD)&dwTmp,NULL);
    	WriteFile(hf,(LPVOID)pbih,sizeof(BITMAPINFOHEADER)+pbih->biClrUsed*sizeof(RGBQUAD),(LPDWORD)&dwTmp,NULL);
    	dwTotal=cb=pbih->biSizeImage;
    	hp=lpBits;
    	WriteFile(hf,(LPSTR)hp,(int)cb,(LPDWORD)&dwTmp,NULL);
    	CloseHandle(hf);
    	AddDebugLogEntry("Screen capture recorded.",0,1);
    	GlobalFree((HGLOBAL)lpBits);
    	SelectObject(hdcCom,OldBmp);
    	DeleteObject(NewBmp);
    	NewBmp=NULL;
    	DeleteDC(hdcCom);
    	hdcCom=NULL;
    }
    
    PBITMAPINFO MakeBI(lpdds7 sfHDC)
    {
    	BITMAP bmp;
    	PBITMAPINFO pbmi;
    	WORD cClrBits;
    	HDC hdc;
    	sfHDC->GetDC(&hdc);
    	NewBmp=CreateCompatibleBitmap(hdc,800,600);
    	hdcCom=CreateCompatibleDC(hdc);
    	OldBmp=(HBITMAP)SelectObject(hdcCom,NewBmp);
    	BitBlt(hdcCom,0,0,800,600,hdc,0,0,SRCCOPY);
    	sfHDC->ReleaseDC(hdc);
    	hdc=NULL;
    	GetObject(NewBmp,sizeof(BITMAP),(LPSTR)&bmp);
    	cClrBits=(WORD)(bmp.bmPlanes*bmp.bmBitsPixel);
    	if(cClrBits==1)
    		cClrBits=1;
    	else if(cClrBits<=4)
    		cClrBits=4;
    	else if(cClrBits<=8)
    		cClrBits=8;
    	else if(cClrBits<=16)
    		cClrBits=16;
    	else if(cClrBits<=24)
    		cClrBits=24;
    	else cClrBits=32;
    	if(cClrBits!=24)
    		pbmi=(PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*(1<<cClrBits));
    	else
    		pbmi=(PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER));
    	pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
    	pbmi->bmiHeader.biWidth=bmp.bmWidth;
    	pbmi->bmiHeader.biHeight=bmp.bmHeight;
    	pbmi->bmiHeader.biPlanes=bmp.bmPlanes;
    	pbmi->bmiHeader.biBitCount=bmp.bmBitsPixel;
    	if(cClrBits<24)
    		pbmi->bmiHeader.biClrUsed=(1<<cClrBits);
    	pbmi->bmiHeader.biClrImportant=BI_RGB;
    	pbmi->bmiHeader.biSizeImage=((pbmi->bmiHeader.biWidth*cClrBits+31)&~31)*pbmi->bmiHeader.biHeight;
    	pbmi->bmiHeader.biClrImportant=0;
    	return(pbmi);
    }

  5. #5
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    Oops. Sorry I just realized this wasn't commented **hides in shame**. If you want I can comment it to help you understand it better. Just let me know.

    ***EDIT**** also you need to include ddraw.h in the header.
    Last edited by jdinger; 02-14-2003 at 02:30 PM.

  6. #6
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    Thanks for the code. Don't bother posting the comments, I figured it out how it worked (actually, I made some modifications, shortening the code... ).

    Anyway, it worked perfectly on the first run. That rarely happens .
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  7. #7
    Used Registerer jdinger's Avatar
    Join Date
    Feb 2002
    Posts
    1,065
    Originally posted by Magos
    Thanks for the code. Don't bother posting the comments, I figured it out how it worked (actually, I made some modifications, shortening the code... ).

    Anyway, it worked perfectly on the first run. That rarely happens .
    hehe...Glad to help. I just noticed that I left some stuff in that is specific to my engine like:

    Code:
    AddDebugLogEntry("Screen capture recorded.",0,1);
    Glad to see you were able to clean it up and get it to work without any trouble.

  8. #8
    doesn't GDI have a function that will take a screenshot?

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screenshots
    By Dae in forum Windows Programming
    Replies: 4
    Last Post: 07-08-2009, 01:21 AM
  2. New screenshots from engine
    By VirtualAce in forum Game Programming
    Replies: 48
    Last Post: 11-30-2004, 09:30 PM
  3. screenshots of your games
    By stallion in forum Game Programming
    Replies: 94
    Last Post: 03-26-2003, 08:56 PM
  4. Screenshots in RealOne
    By harryP in forum A Brief History of Cprogramming.com
    Replies: 6
    Last Post: 10-05-2002, 01:30 PM
  5. Screenshots of Upcoming "Mists of Avalon"
    By harry_p in forum C++ Programming
    Replies: 62
    Last Post: 08-02-2002, 11:37 AM