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