#include "stdafx.h"
#include "ScreenCapture.h"


CScreenCapture::CScreenCapture()
{
	m_cxScreen=::GetSystemMetrics(SM_CXSCREEN);
	m_cyScreen=::GetSystemMetrics(SM_CYSCREEN);
	
	m_bIsCapturing = false;
}

CScreenCapture::~CScreenCapture()
{
}


//功能:屏幕截屏,保存成BMP位图数据
//输入:截屏区域rcCapture
void CScreenCapture::ScreenGISArea(const CRect rcCapture)
{
	m_bIsCapturing = false;

	//功能:开始截屏
	BeginCapture();

	CRect CapRect = rcCapture;
//	CapRect.NormalizeRect();

	m_bIsCapturing = true;

	//屏幕截图
	HBITMAP hBmp = CopyScreenToBitmap(CapRect);  

	if(hBmp !=NULL)
	{
		SaveBitmap(hBmp);
	}

	m_bIsCapturing = false;
}



//功能:截屏给定区域,保存成BMP
//输入:截屏区域rect
HBITMAP CScreenCapture::CopyScreenToBitmap(CRect &rect) //lpRect 代表选定区域  
{  
	CDC tarDC,srcDC;
	CBitmap tarBmp,*pOldtarBmp,*pOldsrcBmp;
	if(m_bIsCapturing)
	{
		tarDC.CreateCompatibleDC(NULL);
		srcDC.CreateCompatibleDC(NULL);
		pOldsrcBmp=srcDC.SelectObject(&m_bkBmp);
	}
	else
	{
		srcDC.CreateDC("DISPLAY",NULL,NULL,NULL);
		tarDC.CreateCompatibleDC(&srcDC);
	}
	if (rect.left<0)
		rect.left=0;						
	if(rect.top<0)
		rect.top=0;
	if(rect.right>m_cxScreen)
		rect.right=m_cxScreen;
	if(rect.bottom>m_cyScreen)
		rect.bottom=m_cyScreen;
	tarBmp.CreateCompatibleBitmap(&srcDC,rect.Width(),rect.Height());
	pOldtarBmp=tarDC.SelectObject(&tarBmp);
	tarDC.BitBlt(0, 0, rect.Width(),rect.Height(),&srcDC,
		rect.left,rect.top,SRCCOPY);
	if(m_bIsCapturing)
		srcDC.SelectObject(pOldsrcBmp);
	tarDC.SelectObject(pOldtarBmp);

	return (HBITMAP)tarBmp.Detach();

}  


void CScreenCapture::SaveBitmap(HBITMAP hBmp)
{
	TCHAR szFilters[]= _T("Image Files (*.bmp)|*.bmp||");
	CFileDialog fd(FALSE, _T("bmp"), _T("*.bmp"),OFN_HIDEREADONLY, szFilters);

	if(IDOK==fd.DoModal())
	{
		CDC dc;
		dc.CreateCompatibleDC(NULL);
		CBitmap Bmp;
		Bmp.Attach(hBmp);
		BITMAP btm;
		Bmp.GetBitmap(&btm);
		BITMAPFILEHEADER   bmfHeader;    
		BITMAPINFOHEADER   bi;
		
		bi.biSize = sizeof(BITMAPINFOHEADER);    
		bi.biWidth = btm.bmWidth;    
		bi.biHeight = btm.bmHeight;  
		bi.biPlanes = 1;    
		bi.biBitCount = 32;    
		bi.biCompression = BI_RGB;    
		bi.biSizeImage = 0;  
		bi.biXPelsPerMeter = 0;    
		bi.biYPelsPerMeter = 0;    
		bi.biClrUsed = 0;    
		bi.biClrImportant = 0;
		
		DWORD dwBmpSize =((btm.bmWidth*bi.biBitCount+31)/32) 
			*4*btm.bmHeight;
		
		// Starting with 32-bit Windows, GlobalAlloc and LocalAlloc 
		//are implemented as wrapper functions that 
		// call HeapAlloc using a handle to the process's default heap. 
		//Therefore, GlobalAlloc and LocalAlloc 
		// have greater overhead than HeapAlloc.
		HANDLE hDIB = ::GlobalAlloc(GHND,dwBmpSize);  
		LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);    
		*lpbi = bi;
		
		// Gets the "bits" from the bitmap and copies them into a buffer 
		// which is pointed to by lpbi
		::GetDIBits(dc.operator HDC(),hBmp,0,
			(UINT)btm.bmHeight,lpbi,
			(BITMAPINFO*)lpbi,DIB_RGB_COLORS);    
		
		CString strName=fd.GetPathName();
		CFile bf;
		if(bf.Open(strName,CFile::modeCreate|CFile::modeWrite))
		{
			//Offset to where the actual bitmap bits start.
			bmfHeader.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+ 
				(DWORD)sizeof(BITMAPINFOHEADER); 
			
			//Size of the Data
			bmfHeader.bfSize=dwBmpSize; 
			
			//bfType must always be BM for Bitmaps
			bmfHeader.bfType=0x4D42; //BM  	
			
			bf.Write((LPSTR)&bmfHeader,sizeof(BITMAPFILEHEADER));
			bf.Write((LPSTR)&bi,sizeof(BITMAPINFOHEADER));
			bf.Write((LPSTR)lpbi,dwBmpSize);
		}
		
		//Unlock and Free the DIB from the heap
		GlobalUnlock(hDIB);    
		GlobalFree(hDIB);

		AfxMessageBox(_T("完成态势图保存!"));
	}
}



//功能:开始截屏
void CScreenCapture::BeginCapture()
{
	if(m_bkBmp.m_hObject!=NULL)m_bkBmp.DeleteObject();
	m_bkBmp.Attach(CopyScreenToBitmap(CRect(0,0,m_cxScreen,
		m_cyScreen)));
	
	CRect FullRect;
	FullRect.left=0;
	FullRect.top=0;
	FullRect.right=m_cxScreen;
	FullRect.bottom=m_cyScreen;
	
	WINDOWPLACEMENT WndPla;
	WndPla.flags=0;
	WndPla.length=sizeof(WINDOWPLACEMENT);
	WndPla.rcNormalPosition=FullRect;
	WndPla.showCmd=SW_SHOWNORMAL;
	
	SetWindowPlacement(NULL, &WndPla);
	//	SetWindowPos(&wndTopMost,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
	//	SetForegroundWindow();
}