意图: 
   由于程序重绘过程中,有时候是不需要全部绘制的,因此使用了一个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;
}
   

解决方案 »

  1.   

    CreateCompatibleBitmap, BitBlt... 等函数都加上返回值判断, 出现异常就用断言
      

  2.   

    只看到CreateCompatibleDC ,没看到DelteDc,居然还有红色字体在哪里说没有GDI资源泄漏。
      

  3.   

    CreateCompatibleDC用的是CDC类, 可以的...
      

  4.   


    谢谢你的提醒,因为是MFC,CDC变量自己析构的时候,会DeleteDC,所以才没有DeleteDC,减少一行代码,反正析构的时候,它也会再去判断一次。如果是SDK,肯定是要自己DeleteDC。因此上面的代码,是没有GDI资源泄漏的。但手动加入也无妨,因为析构的时候,不会DeleteDC两次。
      

  5.   

    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;
        }
    ------------------
    会不会因为这里return,下面的没有执行
      

  6.   

    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);      m_bNeedReDraw = TRUE; //初建的位图肯定要绘制的吧?
    }
      

  7.   

    !m_bNeedReDraw,不需要重新绘图 ,因此BitBlt完后 ,就操作完了,这里没有问题的。
      

  8.   


    你说的没错,我先加上。再结合zzz3265的建议。看看