意图:
由于程序重绘过程中,有时候是不需要全部绘制的,因此使用了一个CBitmap的对象m_pBmpMainGraphic,当程序第一次重绘时,绘制到这个m_pBmpMainGraphic上,之后,如果不需要完全重绘(m_bNeedReDraw为FALSE),则直接从m_pBmpMainGraphic贴图到目的DC.贴图时使用了BitBlt函数。问题:
现在的问题是,程序大多数情况下运行是正常的,但不知道进行某项操作(也有可能压根就没操作,它只是在画),会变得一团黑,甚至不画。自己的程序自己看老感觉没什么问题,于是将几行关键的代码发出来,请大家指教和指正。注:特意看过GDI资源,没有出现只增不减的情况,就是说,应该不是GDI资源泄漏导致的。可能是哪个地方处理的不当。
void C****::ClearMemGraphics()
{
if (m_pBmpMainGraphic != NULL)
{
delete m_pBmpMainGraphic;
m_pBmpMainGraphic = NULL;
}
}void C****::OnDraw(CDC* pDCDes)
{
if(m_bNeedReDraw)
{
// 清除上次的内存图片
ClearMemGraphics();
}
if (m_pBmpMainGraphic == NULL)
{
m_pBmpMainGraphic = new CBitmap();
// m_rect为这个区域的RECT.
m_pBmpMainGraphic->CreateCompatibleBitmap(pDCDes, m_rect.right-m_rect.left, m_rect.bottom-m_rect.top);
} CDC memDC;
memDC.CreateCompatibleDC(pDCDes);
memDC.SetBkMode(TRANSPARENT);
m_pOldBmpMainGraphic = memDC.SelectObject(m_pBmpMainGraphic);
if (!m_bNeedReDraw)
{
pDCDes->BitBlt(0,0,m_rect.right-m_rect.left,m_rect.bottom-m_rect.top,
&memDC,0,0,SRCCOPY);
if (m_pOldBmpMainGraphic)
{
memDC.SelectObject(m_pOldBmpMainGraphic);
}
return;
}
// 以下为需要重绘时的绘制过程,整过过程都是在memDC中做,绘制完后,再Bitblt到目的DC。
//
//
pDCDes->BitBlt(0,0,m_rect.right-m_rect.left,m_rect.bottom-m_rect.top,
&memDC,0,0,SRCCOPY);
if (m_pOldBmpMainGraphic)
{
pDC->SelectObject(m_pOldBmpMainGraphic);
} m_bNeedReDraw = FALSE;
}
由于程序重绘过程中,有时候是不需要全部绘制的,因此使用了一个CBitmap的对象m_pBmpMainGraphic,当程序第一次重绘时,绘制到这个m_pBmpMainGraphic上,之后,如果不需要完全重绘(m_bNeedReDraw为FALSE),则直接从m_pBmpMainGraphic贴图到目的DC.贴图时使用了BitBlt函数。问题:
现在的问题是,程序大多数情况下运行是正常的,但不知道进行某项操作(也有可能压根就没操作,它只是在画),会变得一团黑,甚至不画。自己的程序自己看老感觉没什么问题,于是将几行关键的代码发出来,请大家指教和指正。注:特意看过GDI资源,没有出现只增不减的情况,就是说,应该不是GDI资源泄漏导致的。可能是哪个地方处理的不当。
void C****::ClearMemGraphics()
{
if (m_pBmpMainGraphic != NULL)
{
delete m_pBmpMainGraphic;
m_pBmpMainGraphic = NULL;
}
}void C****::OnDraw(CDC* pDCDes)
{
if(m_bNeedReDraw)
{
// 清除上次的内存图片
ClearMemGraphics();
}
if (m_pBmpMainGraphic == NULL)
{
m_pBmpMainGraphic = new CBitmap();
// m_rect为这个区域的RECT.
m_pBmpMainGraphic->CreateCompatibleBitmap(pDCDes, m_rect.right-m_rect.left, m_rect.bottom-m_rect.top);
} CDC memDC;
memDC.CreateCompatibleDC(pDCDes);
memDC.SetBkMode(TRANSPARENT);
m_pOldBmpMainGraphic = memDC.SelectObject(m_pBmpMainGraphic);
if (!m_bNeedReDraw)
{
pDCDes->BitBlt(0,0,m_rect.right-m_rect.left,m_rect.bottom-m_rect.top,
&memDC,0,0,SRCCOPY);
if (m_pOldBmpMainGraphic)
{
memDC.SelectObject(m_pOldBmpMainGraphic);
}
return;
}
// 以下为需要重绘时的绘制过程,整过过程都是在memDC中做,绘制完后,再Bitblt到目的DC。
//
//
pDCDes->BitBlt(0,0,m_rect.right-m_rect.left,m_rect.bottom-m_rect.top,
&memDC,0,0,SRCCOPY);
if (m_pOldBmpMainGraphic)
{
pDC->SelectObject(m_pOldBmpMainGraphic);
} m_bNeedReDraw = FALSE;
}
谢谢你的提醒,因为是MFC,CDC变量自己析构的时候,会DeleteDC,所以才没有DeleteDC,减少一行代码,反正析构的时候,它也会再去判断一次。如果是SDK,肯定是要自己DeleteDC。因此上面的代码,是没有GDI资源泄漏的。但手动加入也无妨,因为析构的时候,不会DeleteDC两次。
{
pDCDes->BitBlt(0,0,m_rect.right-m_rect.left,m_rect.bottom-m_rect.top,
&memDC,0,0,SRCCOPY);
if (m_pOldBmpMainGraphic)
{
memDC.SelectObject(m_pOldBmpMainGraphic);
}
return;
}
------------------
会不会因为这里return,下面的没有执行
{
m_pBmpMainGraphic = new CBitmap();
// m_rect为这个区域的RECT.
m_pBmpMainGraphic->CreateCompatibleBitmap(pDCDes, m_rect.right-m_rect.left, m_rect.bottom-m_rect.top); m_bNeedReDraw = TRUE; //初建的位图肯定要绘制的吧?
}
你说的没错,我先加上。再结合zzz3265的建议。看看