64,654
社区成员
发帖
与我相关
我的任务
分享
// 获取HDC的数据
BOOL GetHDCData(HDC hdc,const RECT &rcDC,std::vector<BYTE> &vtBuf)
{
BOOL bRes = FALSE;
HBITMAP hBmp = NULL;
HDC hdcMem = NULL;
__try
{
//Initilaize the bitmap information
BITMAPINFO bmpInfo = {0};
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInfo.bmiHeader.biWidth = rcDC.right - rcDC.left;
bmpInfo.bmiHeader.biHeight = rcDC.bottom - rcDC.top;
bmpInfo.bmiHeader.biPlanes = 1;
bmpInfo.bmiHeader.biBitCount = 24;
//Create the compatible DC to get the data
hdcMem = CreateCompatibleDC(hdc);
if(hdcMem == NULL)
{
//ASSERT(FALSE);
//RETAILMSG(TRUE,(TEXT("CreateCompatibleDC failed! Error Code:0x%x\r\n"),GetLastError()));
__leave;
}
//Get the data from the memory DC
BYTE *pData = NULL;
hBmp = CreateDIBSection(hdcMem,&bmpInfo,DIB_RGB_COLORS,reinterpret_cast<VOID **>(&pData),NULL,0);
if(hBmp == NULL)
{
//ASSERT(FALSE);
//RETAILMSG(TRUE,(TEXT("CreateDIBSection failed! Error Code:0x%x\r\n"),GetLastError()));
__leave;
}
HGDIOBJ hOldObj = SelectObject(hdcMem, hBmp);
//Draw to the memory DC
SIZE sizeImg = {bmpInfo.bmiHeader.biWidth,bmpInfo.bmiHeader.biHeight};
SIZE sizeDC = {rcDC.right - rcDC.left,rcDC.bottom - rcDC.top};
StretchBlt(hdcMem,
0,
0,
sizeImg.cx,
sizeImg.cy,
hdc,
rcDC.left,
rcDC.top,
sizeDC.cx,
sizeDC.cy,
SRCCOPY);
vtBuf.resize(sizeImg.cx * sizeImg.cy * 3);
memcpy(&vtBuf[0],pData,vtBuf.size());
SelectObject(hdcMem, hOldObj);
bRes = TRUE;
}
__finally
{
if(hBmp != NULL)
{
DeleteObject(hBmp);
}
if(hdcMem != NULL)
{
DeleteDC(hdcMem);
}
}
return bRes;
}
// 保存HDC为BMP文件
BOOL WriteBmp(const TSTRING &strFile,HDC hdc,const RECT &rcDC)
{
std::vector<BYTE> vtData;
if(GetHDCData(hdc,rcDC,vtData) == FALSE)
{
return FALSE;
}
SIZE sizeImg = {rcDC.right - rcDC.left,rcDC.bottom - rcDC.top};
BITMAPINFOHEADER bmInfoHeader = {0};
bmInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bmInfoHeader.biWidth = sizeImg.cx;
bmInfoHeader.biHeight = sizeImg.cy;
bmInfoHeader.biPlanes = 1;
bmInfoHeader.biBitCount = 24;
//Bimap file header in order to write bmp file
BITMAPFILEHEADER bmFileHeader = {0};
bmFileHeader.bfType = 0x4d42; //bmp
bmFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmFileHeader.bfSize = bmFileHeader.bfOffBits + ((bmInfoHeader.biWidth * bmInfoHeader.biHeight) * 3); ///3=(24 / 8)
HANDLE hFile = CreateFile(strFile.c_str(),GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile == INVALID_HANDLE_VALUE)
{
return FALSE;
}
DWORD dwWrite = 0;
WriteFile(hFile,&bmFileHeader,sizeof(BITMAPFILEHEADER),&dwWrite,NULL);
WriteFile(hFile,&bmInfoHeader, sizeof(BITMAPINFOHEADER),&dwWrite,NULL);
WriteFile(hFile,&vtData[0], vtData.size(),&dwWrite,NULL);
CloseHandle(hFile);
return TRUE;
}
// 截屏
HDC hdc = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
RECT rcSave = {0,0,GetDeviceCaps(hdc,HORZRES),GetDeviceCaps(hdc,VERTRES)};
WriteBmp(TEXT("D:\\Temp\\ScreenCapture.BMP"),hdc,rcSave);
DeleteDC(hdc);
HBITMAP CopyScreenToBitmap(int &nWidth, int &nHeight)
{
//屏幕和内存设备描述表
HDC hScrDC, hMemDC;
//位图句柄
HBITMAP hBitmap,hOldBitmap;
//屏幕分辨率
int xScrn,yScrn;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
//获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//存储屏幕的宽度
nWidth = xScrn;
nHeight = yScrn;
//创建一个与屏幕设备描述表兼容的 位图
hBitmap = CreateCompatibleBitmap(hScrDC, xScrn,yScrn);
//把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
//把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, xScrn, yScrn, hScrDC, 0, 0, SRCCOPY);
//得到屏幕位图句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
//返回位图句柄
return hBitmap;
}
void CJiepingDlg::OnButDisp()
{
// TODO: Add your control notification handler code here
HBITMAP bmp;
int nWidth,nHeight;
//zhuapingg
bmp = CopyScreenToBitmap(nWidth, nHeight);
//将抓取的屏幕压缩先是到窗体上
CDC *pDC = new CClientDC(this);
CDC srcDC;
CRect rect;
this->GetClientRect(&rect);
// GetClientRect(&rect);
rect.DeflateRect(0,20);
//绘制显示区域矩形
CPen pen;
pen.CreatePen(PS_SOLID, 2, RGB(0,255,255));
pDC->SelectObject(&pen);
pDC->Rectangle(rect);
//、显示屏幕
srcDC.CreateCompatibleDC(pDC);
srcDC.SelectObject(bmp);
//压缩显示抓取的位图
pDC->StretchBlt(rect.left+2,rect.top+2,rect.right-rect.left-4,rect.bottom-rect.top-4,&srcDC,0,0,nWidth,nHeight,SRCCOPY);
pen.DeleteObject();
DeleteObject(bmp);
srcDC.DeleteDC();
delete pDC;
}