截屏吃内存的问题 高手请进

来源:互联网 发布:unix高级编程 编辑:程序博客网 时间:2024/05/01 04:27

下边的这两个函数的主要功能是 打印当前屏幕, 可是我不停调用的时候发现, 每调一次, 都会吃掉我 2MB左右的内存, 检查了一下 所有的资源都释放了,找不到原因了, 请各位帮忙看一下.

 

//打印屏幕
//先打印几次桌面, 后再起线程 进行文件压缩处理
BOOL CScreenCap::CopyScreen(LPBITMAPINFOHEADER &lpbi)
{
 try
 {
  HBITMAP  hbitmap ;
  HBITMAP  hbitmapOld ;  
  int cxPixInch   ;  
  int cyPixInch   ;  

  //进行屏幕截取
  HDC hdc ;
  //hdc = GetDC(NULL) ;  

  HDC hdcMem ;
  hdcMem = CreateCompatibleDC(NULL) ; 

  hdc = CreateDC("DISPLAY", NULL, NULL, NULL);
  HDC CompatibleHDC = CreateCompatibleDC(hdc);
  hbitmap = CreateCompatibleBitmap(hdc,GetDeviceCaps(hdc, HORZRES),GetDeviceCaps(hdc, VERTRES));

  if ( NULL == hbitmap)
  {
   return FALSE ;
  }

  SelectObject(CompatibleHDC, hbitmap);
  BitBlt(CompatibleHDC,0,0,GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES),hdc,0,0,SRCCOPY);

  cxPixInch   =   GetDeviceCaps(hdc,LOGPIXELSX)   ;
  cyPixInch   =   GetDeviceCaps(hdc,LOGPIXELSY)   ;


  hbitmapOld   =   SelectBitmap(hdcMem,   hbitmap);

  SelectBitmap(hdcMem,   hbitmapOld);  

  DWORD sizeimage ;
  //把DDB 转换成 DIB
  lpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDDBToDIB(hbitmap, BI_RGB, 0, &sizeimage));

  ReleaseDC(NULL, hdc) ;
  
  if ( !DeleteDC(hdc))
  {

   DWORD dw = ::GetLastError() ;

   int i = 0 ;
   
  }
  hdc = NULL ;

  ReleaseDC(NULL, hdcMem) ;
  DeleteDC(hdcMem) ;
  hdcMem = NULL ;

  DeleteDC(CompatibleHDC) ;
  CompatibleHDC = NULL ;

  DeleteObject(hbitmap) ;
  hbitmap = NULL ;
  DeleteObject(hbitmapOld) ;
  hbitmapOld = NULL ;
 }
 catch(...)
 {
  return FALSE ;
 }

 return TRUE ;
}

//DDB to DIB
HANDLE CScreenCap::MakeDDBToDIB(HBITMAP bitmap, DWORD dwCompression, HPALETTE hPal, DWORD* sizeimage)
{
 BITMAP            bm;
 BITMAPINFOHEADER    bi;
 LPBITMAPINFOHEADER     lpbi;
 DWORD            dwLen;
 HANDLE            hDib;
 HANDLE            handle;
 HDC             hdc;

 //不支持BI_BITFIELDS类型
 if( dwCompression == BI_BITFIELDS )
 {
  return NULL;
 }

 //如果调色板为空,则用默认调色板
 if (hPal==NULL)
 {
  hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE );
 }

 //获取位图信息
 GetObject(bitmap,sizeof(bm),(LPSTR)&bm);

 //初始化位图信息头
 bi.biSize        = sizeof(BITMAPINFOHEADER);
 bi.biWidth        = bm.bmWidth;
 bi.biHeight         = bm.bmHeight;
 bi.biPlanes         = 1;
 bi.biBitCount        = bm.bmPlanes * bm.bmBitsPixel;
 bi.biCompression    = dwCompression;
 bi.biSizeImage        = 0;
 bi.biXPelsPerMeter    = 0;
 bi.biYPelsPerMeter    = 0;
 bi.biClrUsed        = 0;
 bi.biClrImportant    = 0;

 //计算信息头及颜色表大小
 int ncolors = (1 << bi.biBitCount);
 if( ncolors> 256 )
 {
  ncolors = 0;
 }
 dwLen  = bi.biSize + ncolors * sizeof(RGBQUAD);

 hdc = GetDC(NULL);
 hdc = CreateDC("DISPLAY", NULL, NULL, NULL) ;
 hPal = SelectPalette(hdc,hPal,FALSE);
 RealizePalette(hdc);

 //为信息头及颜色表分配内存
 hDib = GlobalAlloc(GMEM_FIXED,dwLen);

 if (!hDib)
 {
  SelectPalette(hdc,hPal,FALSE);
  //ReleaseDC(0,hdc);
  return NULL;
 }

 lpbi = (LPBITMAPINFOHEADER)hDib;
 *lpbi = bi;
 //调用 GetDIBits 计算图像大小
 GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight,
  (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS );

 bi = *lpbi;
 //图像的每一行都对齐(32bit)边界
 if (bi.biSizeImage == 0)
 {
  bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
   * bi.biHeight;
  if (dwCompression != BI_RGB)
  {
   bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  }
 }

 //重新分配内存大小,以便放下所有数据
 dwLen += bi.biSizeImage;
 if (handle = GlobalReAlloc(hDib, dwLen, GMEM_MOVEABLE))
 {
  hDib = handle;
 }
 else
 {
  GlobalFree(hDib);
  //重选原始调色板
  SelectPalette(hdc,hPal,FALSE);
  //CloseHandle(handle) ;
  return NULL;
 }

 //获取位图数据
 lpbi = (LPBITMAPINFOHEADER)hDib;

 //最终获得的DIB
 BOOL bgotbits = GetDIBits( hdc, bitmap,
  0L,                      //扫描行起始处
  (DWORD)bi.biHeight,      //扫描行数
  (LPBYTE)lpbi             //位图数据地址
  + (bi.biSize + ncolors * sizeof(RGBQUAD)),
  (LPBITMAPINFO)lpbi,      //位图信息地址
  (DWORD)DIB_RGB_COLORS);  //颜色板使用RGB

 if( !bgotbits )
 {
  GlobalFree(hDib);

  SelectPalette(hdc,hPal,FALSE); 
  //CloseHandle(handle) ;
  return NULL;
 }

 SelectPalette(hdc,hPal,FALSE); 
 *sizeimage=bi.biSizeImage;

 ReleaseDC(NULL, hdc) ;
 DeleteDC(hdc) ;
 hdc = NULL ;
 //CloseHandle(handle) ;

 return hDib; 
}