截图 c++


HBITMAP CopyScreenToBitmap(LPRECT lpRect) //lpRect 代表选定区域
{
 HDC hScrDC, hMemDC;
 // 屏幕和内存设备描述表
 HBITMAP hBitmap, hOldBitmap;
 // 位图句柄
 int nX, nY, nX2, nY2;
 // 选定区域坐标
 int nWidth, nHeight;
 // 位图宽度和高度
 int xScrn, yScrn;
 // 屏幕分辨率

 // 确保选定区域不为空矩形
 if (IsRectEmpty(lpRect))
 return NULL;
 //为屏幕创建设备描述表
 hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
 //为屏幕设备描述表创建兼容的内存设备描述表
 hMemDC = CreateCompatibleDC(hScrDC);
 // 获得选定区域坐标
 nX = lpRect->left;
 nY = lpRect->top;
 nX2 = lpRect->right;
 nY2 = lpRect->bottom;
 // 获得屏幕分辨率
 xScrn = GetDeviceCaps(hScrDC, HORZRES);
 yScrn = GetDeviceCaps(hScrDC, VERTRES);
 //确保选定区域是可见的
 if (nX <0)
 nX = 0;
 if (nY <0)
 nY = 0;
 if (nX2 > xScrn)
 nX2 = xScrn;
 if (nY2 > yScrn)
 nY2 = yScrn;
 nWidth = nX2 - nX;
 nHeight = nY2 - nY;
 // 创建一个与屏幕设备描述表兼容的位图
 hBitmap = CreateCompatibleBitmap
 (hScrDC, nWidth, nHeight);
 // 把新位图选到内存设备描述表中
 hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
 // 把屏幕设备描述表拷贝到内存设备描述表中
 BitBlt(hMemDC, 0, 0, nWidth, nHeight,
 hScrDC, nX, nY, SRCCOPY);
 //得到屏幕位图的句柄
 hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
 //清除
 DeleteDC(hScrDC);
 DeleteDC(hMemDC);
 // 返回位图句柄
 return hBitmap;
}

//得到屏幕位图句柄以后,我们
//可以把屏幕内容粘贴到剪贴板上.
void OpClip(HBITMAP hBitmap, HWND jhWnd)
{
 if(OpenClipboard(jhWnd))
  //hWnd为程序窗口句柄
  //清空剪贴板
  EmptyClipboard();
 //把屏幕内容粘贴到剪贴板上,
 //hBitmap 为刚才的屏幕位图句柄
 SetClipboardData(CF_BITMAP, hBitmap);
 //关闭剪贴板
 CloseClipboard();
}

//我们也可以把屏幕内容以位图格式存到磁盘文件上.

//hBitmap 为刚才的屏幕位图句柄
int SaveBitmapToFile(HBITMAP hBitmap , LPSTR lpFileName)

 //lpFileName 为位图文件名
 HDC hDC;
 //设备描述表
 int iBits;
 //当前显示分辨率下每个像素所占字节数
 WORD wBitCount;
 //位图中每个像素所占字节数
 //定义调色板大小, 位图中像素字节大小 ,
 //位图文件大小 , 写入文件字节数
 DWORD dwPaletteSize=0,
 dwBmBitsSize,
 dwDIBSize, dwWritten;
 BITMAP Bitmap;
 //位图属性结构
 BITMAPFILEHEADER bmfHdr;
 //位图文件头结构
 BITMAPINFOHEADER bi;
 //位图信息头结构
 LPBITMAPINFOHEADER lpbi;
 //指向位图信息头结构
 HANDLE fh, hDib, hPal;
 HPALETTE hOldPal=NULL;
 //定义文件,分配内存句柄,调色板句柄

 //计算位图文件每个像素所占字节数
 hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
 iBits = GetDeviceCaps(hDC, BITSPIXEL) *
 GetDeviceCaps(hDC, PLANES);
 DeleteDC(hDC);
 if (iBits <= 1)
 wBitCount = 1;
 else if (iBits <= 4)
 wBitCount = 4;
 else if (iBits <= 8)
 wBitCount = 8;
 else if (iBits <= 24)
 wBitCount = 24;
 //计算调色板大小
 if (wBitCount <= 8)
 dwPaletteSize = (1 <<wBitCount) *
 sizeof(RGBQUAD);

 //设置位图信息头结构
 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
 bi.biSize = sizeof(BITMAPINFOHEADER);
 bi.biWidth = Bitmap.bmWidth;
 bi.biHeight = Bitmap.bmHeight;
 bi.biPlanes = 1;
 bi.biBitCount = wBitCount;
 bi.biCompression = BI_RGB;
 bi.biSizeImage = 0;
 bi.biXPelsPerMeter = 0;
 bi.biYPelsPerMeter = 0;
 bi.biClrUsed = 0;
 bi.biClrImportant = 0;

 dwBmBitsSize = ((Bitmap.bmWidth *
 wBitCount+31)/32)* 4
 *Bitmap.bmHeight ;
 //为位图内容分配内存
 hDib = GlobalAlloc(GHND,dwBmBitsSize+
 dwPaletteSize+sizeof(BITMAPINFOHEADER));
 lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
 *lpbi = bi;
 // 处理调色板
 hPal = GetStockObject(DEFAULT_PALETTE);
 if (hPal)
 {
 hDC = GetDC(NULL);

 hOldPal = (HPALETTE)SelectPalette(hDC, (HPALETTE)hPal, FALSE);
 RealizePalette(hDC);
 }

 // 获取该调色板下新的像素值
 GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
 (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
 +dwPaletteSize,
 (tagBITMAPINFO *)
 lpbi, DIB_RGB_COLORS);
 //恢复调色板
 if (hOldPal)
 {
 SelectPalette(hDC, hOldPal, TRUE);
 RealizePalette(hDC);
 ReleaseDC(NULL, hDC);
 }
 //创建位图文件
 fh = CreateFile(lpFileName, GENERIC_WRITE,
 0, NULL, CREATE_ALWAYS,
 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
 if (fh == INVALID_HANDLE_VALUE)
 return FALSE;
 // 设置位图文件头
 bmfHdr.bfType = 0x4D42; // "BM"
 dwDIBSize = sizeof(BITMAPFILEHEADER)
 + sizeof(BITMAPINFOHEADER)
 + dwPaletteSize + dwBmBitsSize;
 bmfHdr.bfSize = dwDIBSize;
 bmfHdr.bfReserved1 = 0;
 bmfHdr.bfReserved2 = 0;
 bmfHdr.bfOffBits = (DWORD)sizeof
 (BITMAPFILEHEADER)
 + (DWORD)sizeof(BITMAPINFOHEADER)
 + dwPaletteSize;
 // 写入位图文件头
 WriteFile(fh, (LPSTR)&bmfHdr, sizeof
 (BITMAPFILEHEADER), &dwWritten, NULL);
 // 写入位图文件其余内容
 WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
 &dwWritten, NULL);
 //清除
 GlobalUnlock(hDib);
 GlobalFree(hDib);
 CloseHandle(fh);

 return 0;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值