Skip to main content
GameDev.net gamedev.net
🔒 Locked

Multi-monitor screenshots

Started by Wampus Mar 9, 2006 at 12:54 PM 0 replies 1.4k views
Original Post
Wampus
Wampus
I'm trying to set up a quick app that will take a screenshot of each monitor, saving each one to a new file. I've tried it and while debugging, it saves the primary monitor's display fine, but the second monitor turns up the right size, but all grey. This is my first attempt at using EnumDisplayMonitors, and I was wondering if any of you could point me to where I was going wrong.
[source lang=cpp]
#include <windows.h>
#include <tchar.h>
#include <atlimage.h>
#include <string>
using namespace std;


void  SaveBitmap(char *szFilename,HBITMAP hBitmap) {
	HDC        hdc=NULL;
	FILE*      fp=NULL;
	LPVOID     pBuf=NULL;
	BITMAPINFO bmpInfo;
	BITMAPFILEHEADER  bmpFileHeader; 
	do { 
		hdc=GetDC(NULL);
		ZeroMemory(&bmpInfo,sizeof(BITMAPINFO));
		bmpInfo.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
		GetDIBits(hdc,hBitmap,0,0,NULL,&bmpInfo,DIB_RGB_COLORS); 
		if(bmpInfo.bmiHeader.biSizeImage<=0)
			bmpInfo.bmiHeader.biSizeImage=bmpInfo.bmiHeader.biWidth*abs(bmpInfo.bmiHeader.biHeight)*(bmpInfo.bmiHeader.biBitCount+7)/8;
		if((pBuf = malloc(bmpInfo.bmiHeader.biSizeImage))==NULL){
			MessageBox( NULL, "Unable to Allocate Bitmap Memory", "Error", MB_OK|MB_ICONERROR);
			break;
			}            
		bmpInfo.bmiHeader.biCompression=BI_RGB;
		GetDIBits(hdc,hBitmap,0,bmpInfo.bmiHeader.biHeight,pBuf, &bmpInfo, DIB_RGB_COLORS);       
		if((fp = fopen(szFilename,"wb"))==NULL){
			MessageBox( NULL, "Unable to Create Bitmap File", "Error", MB_OK|MB_ICONERROR);
			break;
			} 
		bmpFileHeader.bfReserved1=0;
		bmpFileHeader.bfReserved2=0;
		bmpFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+bmpInfo.bmiHeader.biSizeImage;
		bmpFileHeader.bfType='MB';
		bmpFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); 
		fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
		fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
		fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,fp); 
	}while(false); 
	if(hdc)     ReleaseDC(NULL,hdc); 
	if(pBuf)    free(pBuf); 
	if(fp)      fclose(fp);
}



BOOL CALLBACK MyGrabEnumProc(
	HMONITOR hMonitor,  // handle to display monitor
	HDC hdc1,     // handle to monitor DC
	LPRECT lprcMonitor, // monitor intersection rectangle
	LPARAM data       // data
	) {
	int         nX, nY, nX2, nY2;       // coordinates of rectangle to grab     
	int         nWidth, nHeight;        // DIB width and height     
	int         xScrn, yScrn;           // screen resolution    
	HGDIOBJ     hOldBitmap , hBitmap;

	HDC hMemDC = CreateCompatibleDC(hdc1);
	nX = lprcMonitor->left;     
	nY = lprcMonitor->top;     
	nX2 = lprcMonitor->right;     
	nY2 = lprcMonitor->bottom;      // get screen resolution   
	xScrn = GetDeviceCaps(hdc1, HORZRES);     
	yScrn = GetDeviceCaps(hdc1, VERTRES);    

	nWidth = nX2 - nX;     
	nHeight = nY2 - nY;      
	   
	// create a bitmap compatible with the screen DC     	   
	hBitmap = CreateCompatibleBitmap(hdc1, nWidth, nHeight);      

	// select new bitmap into memory DC     
	hOldBitmap =   SelectObject (hMemDC, hBitmap);      
	   
	// bitblt screen DC to memory DC     
	BitBlt(hMemDC, 0, 0, nWidth, nHeight, hdc1, 0, 0, SRCCOPY);    
	// Note: I also tried this as
	//BitBlt(hMemDC, 0, 0, nWidth, nHeight, hdc1, nX, nY, SRCCOPY); 
	// as lprcMonitor is twice as wide the second time as it is the first time    

	// select old bitmap back into memory DC and get handle to     
	// bitmap of the screen          
	hBitmap = SelectObject(hMemDC, hOldBitmap);      
	   
	// clean up        
	DeleteDC(hMemDC);      
	   
	// save the bitmap  
	SaveBitmap("c:/file.bmp", (HBITMAP)hBitmap); 
        // Todo:  save each monitor to new filename 

	return 1;
	}


int WINAPI _tWinMain(HINSTANCE hInst, HINSTANCE, LPTSTR, int)
{
	HDC hdc = GetDC(NULL);
	EnumDisplayMonitors(hdc, NULL, (MONITORENUMPROC)MyGrabEnumProc, NULL);
	ReleaseDC(NULL, hdc);

	return 0;
}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.