下边的这两个函数的主要功能是 打印当前屏幕, 可是我不停调用的时候发现, 每调一次, 都会吃掉我 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;
}
下边的这两个函数的主要功能是 打印当前屏幕, 可是我不停调用的时候发现, 每调一次, 都会吃掉我 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;
}
//先打印几次桌面, 后再起线程 进行文件压缩处理
BOOL CScreenCap::CopyScreen(LPBITMAPINFOHEADER &lpbi)
{
try
{
HBITMAP hbitmap ;
HBITMAP hbitmapOld ;
int cxPixInch ;
int cyPixInch ;
HDC hdc ;
//hdc = GetDC(NULL) ;
hdcMem = CreateCompatibleDC(NULL) ;
HDC CompatibleHDC = CreateCompatibleDC(hdc);
hbitmap = CreateCompatibleBitmap(hdc,GetDeviceCaps(hdc, HORZRES),GetDeviceCaps(hdc, VERTRES));
{
return FALSE ;
}
BitBlt(CompatibleHDC,0,0,GetDeviceCaps(hdc, HORZRES), GetDeviceCaps(hdc, VERTRES),hdc,0,0,SRCCOPY);
cyPixInch = GetDeviceCaps(hdc,LOGPIXELSY) ;
hbitmapOld = SelectBitmap(hdcMem, hbitmap);
//把DDB 转换成 DIB
lpbi = (LPBITMAPINFOHEADER)GlobalLock(MakeDDBToDIB(hbitmap, BI_RGB, 0, &sizeimage));
if ( !DeleteDC(hdc))
{
}
hdc = NULL ;
DeleteDC(hdcMem) ;
hdcMem = NULL ;
CompatibleHDC = NULL ;
hbitmap = NULL ;
DeleteObject(hbitmapOld) ;
hbitmapOld = NULL ;
}
catch(...)
{
return FALSE ;
}
}
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;
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 = CreateDC("DISPLAY", NULL, NULL, NULL) ;
hPal = SelectPalette(hdc,hPal,FALSE);
RealizePalette(hdc);
hDib = GlobalAlloc(GMEM_FIXED,dwLen);
{
SelectPalette(hdc,hPal,FALSE);
//ReleaseDC(0,hdc);
return NULL;
}
*lpbi = bi;
//调用 GetDIBits 计算图像大小
GetDIBits(hdc, bitmap, 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS );
//图像的每一行都对齐(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;
BOOL bgotbits = GetDIBits( hdc, bitmap,
0L, //扫描行起始处
(DWORD)bi.biHeight, //扫描行数
(LPBYTE)lpbi //位图数据地址
+ (bi.biSize + ncolors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, //位图信息地址
(DWORD)DIB_RGB_COLORS); //颜色板使用RGB
{
GlobalFree(hDib);
//CloseHandle(handle) ;
return NULL;
}
*sizeimage=bi.biSizeImage;
DeleteDC(hdc) ;
hdc = NULL ;
//CloseHandle(handle) ;
}