首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

调用100多次CreateCompatibleBitmap后,返回错误“存储空间不足,无法处理此命令”

2012-01-12 
调用100多次CreateCompatibleBitmap后,返回异常“存储空间不足,无法处理此命令”HDChScrDCCreateDC( DISPL

调用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;

热点排行