使用双缓冲技术防止刷新时的闪烁问题:(会发生内存泄漏、4K)
OnDraw函数代码:
CRect rect;
GetClientRect(rect);
CDC MemDC; 
CBitmap MemBitmap;
MemDC.CreateCompatibleDC(NULL);
MemBitmap.CreateCompatibleBitmap(pdc,rect.Width(),rect.Height());
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
MemDC.FillSolidRect(0,0,rcBounds.Width(),rcBounds.Height(),RGB(255,255,255));
//画图
pdc->BitBlt(0,0,rcBounds.Width(),rcBounds.Height(),&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(pOldBit);
MemBitmap.DeleteObject();
MemDC.DeleteDC();

解决方案 »

  1.   

    另画图函数可有泄漏?
    ShowJpgGif(CDC* pDC, CString strPath, int x, int y, bool showflag)
    {   
    IStream   *pStm;       
    CFileStatus   fstatus;       
    CFile   file;       
    LONG   cb;       
    //´ò¿ªÎļþ²¢¼ì²âÎļþµÄÓÐЧÐÔ   
    if   (file.Open(strPath,CFile::modeRead)&&   
    file.GetStatus(strPath,fstatus)&&     
    ((cb   =   fstatus.m_size)   !=   -1))       
    {       
    HGLOBAL   hGlobal   =   GlobalAlloc(GMEM_MOVEABLE,   cb);       
    LPVOID   pvData   =   NULL;       
    if   (hGlobal   !=   NULL)       
    {       
    pvData   =   GlobalLock(hGlobal);   
    if   (pvData   !=   NULL)       
    {       
    file.ReadHuge(pvData,   cb);       
    file.Close();
    GlobalUnlock(hGlobal);       
    CreateStreamOnHGlobal(hGlobal,   TRUE,   &pStm);  
    IPicture   *pPic;     
    //load   image   from   file   stream   
    if(SUCCEEDED(OleLoadPicture(pStm,fstatus.m_size,TRUE,IID_IPicture,(LPVOID*)&pPic)))     
    {     
    OLE_XSIZE_HIMETRIC   hmWidth;       
    OLE_YSIZE_HIMETRIC   hmHeight;       
    pPic->get_Width(&hmWidth);       
    pPic->get_Height(&hmHeight);       
    double   fX,fY;       
    //get   image   height   and   width   
    fX   =   (double)pDC->GetDeviceCaps(HORZRES)*(double)hmWidth/((double)pDC->GetDeviceCaps(HORZSIZE)*100.0);       
    fY   =   (double)pDC->GetDeviceCaps(VERTRES)*(double)hmHeight/((double)pDC->GetDeviceCaps(VERTSIZE)*100.0);       
    //use   render   function   display   image   
    if(FAILED(pPic->Render(*pDC,x,y,(DWORD)fX,(DWORD)fY,0,hmHeight,hmWidth,-hmHeight,NULL)))       
    {   
    pPic->Release(); 
    pPic=NULL;
    pStm->Release();
    pStm=NULL;
    FreeResource(hGlobal);
    return   false;   
    }   
    pPic->Release(); 
    pPic=NULL;
    pStm->Release();
    pStm=NULL;
    FreeResource(hGlobal);
    }
    else
    {
    pPic->Release(); 
    pPic=NULL;
    pStm->Release();
    pStm=NULL;
    FreeResource(hGlobal);
    }
    }     
    }  
    }   
    else   
    {   
    try
    {
    file.Close();
    }
    catch (...)
    {
    }
    CString strout;
    strout.Format("ÕÒ²»µ½Í¼Æ¬Îļþ: %s",strPath);
    AfxMessageBox(strout);
    return   false;   
    }   //´ò¿ªÎļþ½áÊø   
           
    return   true;   
    }
      

  2.   

    创建匹配是否应该写成
    MemBitmap.CreateCompatibleBitmap(&MemDC,rect.Width(),rect.Height());
      

  3.   

    参考:http://blog.gkong.com/more.asp?name=exjeffhn&id=1604
      

  4.   

    创建匹配是否应该写成
    MemBitmap.CreateCompatibleBitmap(&MemDC,rect.Width(),rect.Height());不能写成MEMDC
      

  5.   

    FreeResource(hGlobal);  不添加的话,4K的泄漏会产生
      

  6.   

    有吗?刚我试了下,OnDraw没问题啊.
      

  7.   

    难道问题出在画图程序 ShowJpgGif 里面?代码是从网上COPY过来的,已经进行了一些修补,
      

  8.   

    OnDraw我测试没问题.你那ShowJpgGif函数换了,看看情况.
    个人觉得检查溢出最简单的方法就是排除法.
      

  9.   

    ShowJpgGif里的资源释放太混乱了吧
      

  10.   

    请教正确释放顺序另经过测试屏蔽调用SHOWJPGGIF函数的地方只测试ONDRAW 
    void CEightLightCtrl::OnDraw(
    CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
    {
    // TODO: Replace the following code with your own drawing code.
    CRect rect;
    GetClientRect(rect); CDC MemDC; 
    CBitmap MemBitmap;
    MemDC.CreateCompatibleDC(pdc);//NULL);
    MemBitmap.CreateCompatibleBitmap(pdc,rect.Width(),rect.Height());
    CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
    MemDC.FillSolidRect(0,0,rcBounds.Width(),rcBounds.Height(),RGB(255,255,255));
    pdc->BitBlt(0,0,rcBounds.Width(),rcBounds.Height(),&MemDC,0,0,SRCCOPY);
    MemDC.SelectObject(pOldBit);

    MemBitmap.DeleteObject();
    MemDC.DeleteDC();
    }
    依然会发生泄漏,问题就应该出在这里,
      

  11.   

    我建立的那工程中rcBounds都是用常数代替的,没发现内存泄漏,你逐条//测试吧.
      

  12.   

    泄露不在 OnDraw 中,查找别的地方吧。
      

  13.   

    问个弱智的问题:你是如何判断有内存泄露的?" shawnwan() ( ) 信誉:100    Blog   加为好友  2007-6-11 15:29:55  得分: 0  
    另外大致明白了一个问题,之所以为4K的增长显示,是因为分配内存的页面大小最少为4K"你该不会是从任务管理器里面发现内存使用量上升了4K,就认为是有4K的泄露把?PS:你裤衩比我多,相信不太可能是这样,我也只是做个猜测!!!如果不是这样,就当是我帮你顶了!
      

  14.   

    应该不在OnDraw里!
    顶下!
      

  15.   

    在win98,wince下,双缓冲之后要这么释放:MemDC.DeleteDC();//先删DC
    MemBitmap.DeleteObject();//再删Bitmap
      

  16.   

    WIN 2000  、WIN XP呢
      

  17.   

    读取图片的时候,可以不使用GlobalAlloc,FreeResource,避免内存泄漏.可以这样来:
      

  18.   

    CComQIPtr<IPicture> spIPicture;
    CFile file;
    if (file.Open(pszPathName, CFile::modeRead | CFile::shareDenyWrite))
    {
    CArchive ar(&file, CArchive::load | CArchive::bNoFlushOnDelete);                CArchiveStream arStream(&ar);                HRESULT hr = OleLoadPicture((IStream*)&arStream, 0, FALSE, IID_IPicture, (void**)&spIPicture);
    ASSERT(SUCCEEDED(hr) && spIPicture);
    }一样是可以读取JPG和GIF的第一帧图像.
    之后使用spIPicture的Render函数把图像读取到双缓冲DC上
      

  19.   

    怎样来? 
     LiveALearn(研究GDI)  
    请指教
      

  20.   

    郁闷,问题依然存在啊,难道真的不是ONDRAW 和 SHOWJPGGIF的问题,,我做的是一个OCX控件,没有用到NEW和MALLOC啊。
      

  21.   

    你可以不忙调用ONDRAW 和 SHOWJPGGIF,控件无显示,裸跑一下,看看有无内存泄漏.
      

  22.   

    另外你把OnDraw内的局部变量CDC MemDC; CBitmap MemBitmap;
    改为类的成员变量,以免OnDraw调用过于频繁,无谓的构造析构
      

  23.   

    1)用什么来检测出来的?
    2)如想确定是否OnDrow(),可以写个简单函数代替。看看有没有泄漏就是了
      

  24.   

    如果你是在wince下面编程的话,当调用CDC::GetDC, 再CDC::ReleaseDC释放CDC的时候本来就有内存泄露,这是微软的问题。不过泄露每次只有4k,使用纯API来写::GetDC(HWND hWnd); ::ReleaseDC(HWND hWnd, HDC hDC);可以避免。