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;
}
//得到屏幕位图句柄以后,我们
//可以把屏幕内容粘贴到剪贴板上.
if (OpenClipboard(hWnd))//hWnd为程序窗口句柄
{
EmptyClipboard();//清空剪贴板
//把屏幕内容粘贴到剪贴板上, hBitmap为刚才的屏幕位图句柄
SetClipboardData(CF_BITMAP, hBitmap);
CloseClipboard();//关闭剪贴板
}
// 我们也可以把屏幕内容以位图格式存到磁盘文件上.
int SaveBitmapToFile(HBITMAP hBitmap, LPCTSTR lpFileName)//hBitmap 为刚才的屏幕位图句柄
{
//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,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;
else wBitCount=32;
//计算调色板大小
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 = SelectPalette(hDC,(HPALETTE)hPal,FALSE);
RealizePalette(hDC);
}
//获取该调色板下新的像素值
GetDIBits(hDC,hBitmap,0,(UINT)Bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwPaletteSize,
(BITMAPINFO*)lpbi,DIB_RGB_COLORS);
//恢复调色板
if(hOldPal)
{
SelectPalette(hDC, (HPALETTE)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 1;
}