用VC进行屏幕截取编程_实用的vc编程小技巧
用VC进行屏幕截取编程由刀豆文库小编整理,希望给你工作、学习、生活带来方便,猜你可能喜欢“实用的vc编程小技巧”。
用VC进行屏幕截取编程
潘小龙 顾时明
屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如HYPERSNAP等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用.下面用VC来逐步介绍在Windows95下的实现过程.首先我们要确定屏幕截取的区域,用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把选定的屏幕区域拷贝到位图中.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
nX = 0;
if(nY
nY = 0;
if(nX2 > xScrn)
nX2 = xScrn;
if(nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2nY;
// 创建一个与屏幕设备描述表兼容的位图 hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中 BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
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 ,LPSTR 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
wBitCount = 1;
else if(iBits
wBitCount = 4;
else if(iBits
wBitCount = 8;
else if(iBits
wBitCount = 24;
//计算调色板大小
if(wBitCount
dwPaletteSize =(1
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.biCompreion
= 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, hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0,(UINT)Bitmap.bmHeight,(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize,(BITMAPINFOHEADER *)
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);}