---- 屏幕截取是令人比较感兴趣的事情.虽然现在有不少应用程序如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); 
}
posted on 2008-10-13 23:38  一个人的天空@  阅读(347)  评论(0编辑  收藏  举报