调用100多次CreateCompatibleBitmap后,返回异常“存储空间不足,无法处理此命令”
HDC hScrDC = CreateDC( "DISPLAY ", NULL, NULL, NULL);
HBITMAP hBitmap=CreateCompatibleBitmap(hScrDC,800,600);
其他代码就不写了,太多。
hBitmap作为函数返回值return了,应该不会产生内存泄漏啊。
hScrDC 也每次都执行了DeleteDC(hScrDC);
而且都是差不多在执行了130次左右就出现此异常。
请大家帮帮忙
////////////以下是完整函数,实现屏幕截图
HBITMAP GetScreen::CopyScreenToBitmap(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;
///////////////////////////
TCHAR szBuf[80];
LPVOID lpMsgBuf;
DWORD dw = GetLastError();
///////////////////////////
// 创建一个与屏幕设备描述表兼容的位图
hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
///////////////////////////此处捕捉到异常“存储空间不足,无法处理此命令”/////////////////////////////////////////////////////////////////
// 把新位图选到内存设备描述表中
hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC,0,0, nWidth,nHeight,hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
return hBitmap;
}
[解决办法]
In general, do not call this function; the destructor will do it for you. The DeleteDC member function deletes the Windows device contexts that are associated with m_hDC in the current CDC object. If this CDC object is the last active device context for a given device, the device is notified and all storage and system resources used by the device are released.
An application should not call DeleteDC if objects have been selected into the device context. Objects must first be selected out of the device context before it it is deleted.
An application must not delete a device context whose handle was obtained by calling CWnd::GetDC. Instead, it must call CWnd::ReleaseDC to free the device context. The CClientDC and CWindowDC classes are provided to wrap this functionality.
[解决办法]
没看见在哪调用DeleteObject啊。
[解决办法]
大意是 不建议使用deletedc 原因讲得很清楚了 使用releasedc
[解决办法]
DeleteObject(hBitmap);
[解决办法]
deletedc 并没有 delete object 只是deletes the Windows device contexts
[解决办法]
hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
主要是这个没有释放
[解决办法]
CreateDC
DeleteDC
改为
GetDC(),ReleaseDC()
调用方记得DeleteObject返回的Hbitmap;