WEB开发网
开发学院软件开发VC 用VC进行屏幕截取编程 阅读

用VC进行屏幕截取编程

 2010-04-03 20:35:53 来源:WEB开发网   
核心提示:屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如HYPERSNAP等可以用来截取你所喜欢的屏幕画面,但是如果能把这个功能加到自己的程序中,就更能利用它强大的作用.下面用VC来逐步介绍在Windows95下的实现过程.首先我们要确定屏幕截取的区域,用LPRECT结构来定义.可以截取一个窗口,或整个屏幕.以下代码把

屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如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 < 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 = 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 < = 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 = 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);
}

Tags:VC 进行 屏幕

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接