下邊的這兩個函數的主要功能是 打印當前屏幕, 可是我不停調用的時候發現, 每調一次, 都會喫掉我 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;
}