You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
4.3 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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