现象:程序长时间运行报错.
错误指向:afxwin1.inl 558
_AFXWIN_INLINE CBitmap* CDC::SelectObject(CBitmap* pBitmap)
{ ASSERT(m_hDC != NULL); return (CBitmap*) SelectGdiObject(m_hDC, pBitmap->GetSafeHandle());}程序中有大量的绘制,如用CPen,CBrush,CFont等Graphics Object。使用BoundsChecker已经将Resource Leak的部分修改掉了。

解决方案 »

  1.   

    查看绘制代码中所有SelectObject的地方传入的pBitmap是否合法。
      

  2.   

    内存占用没有明显增长?纯属猜测。
    挂着BoundsChecker长时间跑。
      

  3.   

    以下是绘制基类的代码
    void CDrawBase::DrawMain(CDC *pDC, BOOL bSeeMark)
    {
    if (bSeeMark && !m_bCanDraw)
    return; CMemDC dc(pDC, &((CRect)m_rect));   //Call stack 就到这里,程序出错,请看MemDC的代码:
    dc.SetBkMode(TRANSPARENT);
    DrawBackGround(&dc);
    _DrawMain(&dc);
    }以下是CMemDC的部分代码(该代码是从codeproject上面Get的,成熟的,经得起考验的,问题不会在这里):
    CMemDC(CDC* pDC, const CRect* pRect = NULL) : CDC()
    {
    ASSERT(pDC != NULL);  // Some initialization
    m_pDC = pDC;
    m_oldBitmap = NULL;
    m_bMemDC = !pDC->IsPrinting();
    // Get the rectangle to draw
    if (pRect == NULL) {
    pDC->GetClipBox(&m_rect);
    } else {
    m_rect = *pRect;
    }

    if (m_bMemDC) {
    // Create a Memory DC
    CreateCompatibleDC(pDC);
    pDC->LPtoDP(&m_rect); m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height()); 
    m_oldBitmap = SelectObject(&m_bitmap);   //好,call stack到这里程序出错 

    SetMapMode(pDC->GetMapMode());
    pDC->DPtoLP(&m_rect);
    SetWindowOrg(m_rect.left, m_rect.top);
    } else {
    // Make a copy of the relevent parts of the current DC for printing
    m_bPrinting = pDC->m_bPrinting;
    m_hDC  = pDC->m_hDC;
    m_hAttribDC = pDC->m_hAttribDC;
    } // Fill background 
    FillSolidRect(m_rect, pDC->GetBkColor());
    }ok,最后程序执行_AFXWIN_INLINE CBitmap* CDC::SelectObject(CBitmap* pBitmap) ,断言,出错...
      

  4.   

    CDrawBase中的m_rect是什么类型?
      

  5.   

    m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height()); 判断下是否创建成功的操作。
      

  6.   

    出错的时候
    _AFXWIN_INLINE CBitmap* CDC::SelectObject(CBitmap* pBitmap) 
    { ASSERT(m_hDC != NULL); return (CBitmap*) SelectGdiObject(m_hDC, pBitmap->GetSafeHandle());} m_hDC 为 NULL 了
      

  7.   

    楼主的问题我曾经碰到过类似的,程序运行一个上午就崩溃了。
    后来解决了,是资源泄露的问题,画刷创建的问题。
    楼主可以参考我下面的帖子,或许会有所启发:
    http://topic.csdn.net/u/20080729/14/3bb57da8-a141-4b8a-baf2-3fb67df5c996.html
      

  8.   

    应该先判断是否为有效DC
    if(!pDC->GetSafeHdc())
    // 无效DCif(!CreateCompatibleDC(pDC))
    // 无效DC怀疑pDC本来就无效。
      

  9.   


    多谢捧场!
    最后一次程序报错的时候,pdc是有效的,只不过SelectObject的时候其m_hDC为null了。我一直断定它是GDI资源泄漏导致的。目前我已经找出一处问题,是HRGN h_rgn = CreatePolygonRgn(pts, 7, WINDING); 创建了一个区域,
    但是画完后没有DeleteObject,原来用ChecksBound查的时候没有动态的数据,不会CreatePolygonRgn,所以那时候没有检查出这个错.目前GDI资源不会不断增加了....还要测一天才能看到是否只有这个问题.....
      

  10.   

    还有,你们用的boundsChecker集成到VC 6  中不会报错吧。我的BC8.2装上之后,运行VC环境,就报错了,VC就运行不了。没办法,我只有把它卸载了后,先打开VC,再装boundsChecker,然后根据它的提示,去改源代码。你们有没有遇到过这样的问题。我的Vc打了sp5补丁
      

  11.   

    很久没用VC6了,以前安装BC的时候也没出过问题
      

  12.   

    没用过8.2,用的是7.2没有问题,Vc6.0打了sp2补丁
      

  13.   

    这个问题,只能说仔细检查创建/销毁是否对应,使用句柄前判断有效性,销毁句柄后赋值为NULL,便于判断。根据你的错误,应该是CreateCompatibleDC(pDC);出错了,导致创建DC失败,才有后面的断言;这里创建失败,只能是pDC出错了,那么要看你怎么调用DrawMain(CDC *pDC, BOOL bSeeMark)的了。
    建议你在DrawMain函数入口加一句
    ASSERT_VALID(pDC);可能就能抓住错误。