参考:MFC异常“所需资源不可用”
vc中DC资源的正确利用
VC资源分配、释放表
mfc程序长时间运行后报错:a required resource was unavailable、
现象:软件在运行很长一段时间后,弹出“所需资源不可用”,也或者是菜单栏、Ribbon变白、软件界面不再响应鼠标消息,但在任务管理器中发现软件不占用CPU,也没有“无响应”标识,呈现类似死锁状态。
可能原因:GDI相关资源耗尽
说明:什么是GDI?
GDI:graphics device interface 图形设备接口
GDI好比画图时用的所有工具
处理方法:
查找OnTimer()、OnPaint()、OnEraseBkgnd()、OnCtlColor()这些方法中资源分配后是否释放。
1、DC资源【 什么是DC?CDC?HDC?】
资源 | 分配函数 | 清除函数 | 需要手动清除 |
DC | CreateDC | DeleteDC | Yes |
CreateCompatibleDC | DeleteDC | Yes | |
GetDC | ReleaseDC | Yes | |
GetWindowDC | ReleaseDC | Yes | |
BeginPaint | EndPaint | Yes |
举例:在OnTimer()中连续执行如下语句:
HDC hDC = GetDC()->m_hDC;
m_table.Refresh(hDC);
这样会造成dc资源的耗尽,原因是GetDC() 返回CDC*,要把CDC*所指的资源及时删除,才能连续使用。修改如下:
CDC * pDC = GetDC();
HDC hDC = pDC->m_hDC;
m_table.Refresh(hDC);
pDC->DeleteDC();
2、Brushes资源【画刷】
资源 | 分配函数 | 作用 | 清除函数 | 需要手动清除 |
Brushes | CreateBrushIndirect | 通过LOGBRUSH结构体来取画刷 | DeleteObject | Yes |
CreateDIBPatternBrush | 通过与设备无关位图创建一个画刷 | DeleteObject | Yes | |
CreateHatchBrush | 创建一种带阴影的画刷 | DeleteObject | Yes | |
CreatePatternBrush | 得到位图画刷 | DeleteObject | Yes | |
CreateSolidBrush | 单色的画刷 | DeleteObject | Yes |
例如:在OnCtlColor()中里返回的画刷的句柄,因为是局部变量而没有被释放
HBRUSH ConsoleTest::OnCtlColor(CDC* pDC,CWnd* pWnd,UINT nCtlColor)
{
COLORREF bkcolor(RGB(80, 112, 149));
LOGBRUSH logBrush;
logBrush.lbHatch = 0;
logBrush.lbStyle = BS_SOLID;
logBrush.lbColor = bkcolor;
HBRUSH m_hBrush = (HBRUSH)::CreateBrushIndirect(&logBrush);
return m_hBrush;
}
修改为成员变量:
在 ConsoleTest.h 中定义:
LOGBRUSH logBrush;
HBRUSH m_hBrush;
在 ConsoleTest.app 中 初始化的函数:
COLORREF bkcolor(RGB(80, 112, 149));
logBrush.lbHatch = 0;
logBrush.lbStyle = BS_SOLID;
logBrush.lbColor = bkcolor;
m_hBrush = (HBRUSH)::CreateBrushIndirect(&logBrush);
在 ConsoleTest.app 中 OnCtlColor():
HBRUSH ConsoleTest::OnCtlColor(CDC* pDC,CWnd* pWnd,UINT nCtlColor)
{
return m_hBrush;
}