//我的程序需要定时刷新界面的一小块面积,该如何做?
在ontimer()中:
{
loadsmallbmp1(...);
CRect rtCal;
rtCal.SetRect(0,2,20,20);
pDlg->InvalidateRect(&rtCal,TRUE);
pDlg->UpdateWindow();
}updatewindow会导致onpaint被调用
在onpaint()中:
{
...
this->GetDC()->BitBlt(0, 0,100,100,&dcMemory1,0, 0, SRCCOPY);
this->GetDC()->BitBlt(100, 100,200,200,&dcMemory2,0, 0, SRCCOPY);
this->GetDC()->BitBlt(0,2,20,20,&dcMemory3,0, 0, SRCCOPY);
...
}
也就是说,一个小图片的更新会导致onpaint中所有内容都被重画一遍?该如何优化?

解决方案 »

  1.   

    InvalidateRect后不要跟UpdateWindow()
      

  2.   

    可以在那块区域上放一个static文本控件,图片显示在控件上。
    更新时,只需要
    GetDlgItem(IDC_STATIC_PIC)->Invalidate();
      

  3.   

    GetClipBox(&rtCal);
    InvalidateRect(&rtCal);
    看看效果怎么样。别调用UpdateWindow()。
      

  4.   

    UpdateWindow()是重绘整个窗口的,既然想部分重绘,就没有必要调用这个函数了。
      

  5.   

    UpdateWindow()是重绘整个窗口的的说法是错的。在onpaint()中应该这样处理
                    /**
    * 得到剪裁区
    */
    CPaintDC dc(this);  
    CRect rcClipAll;
    dc.GetClipBox(  rcClipAll ); /**
    * 如果剪裁区和绘图区有相交,才绘制,甚至如果你要更提高效率,可以只绘制相交取
    */
    CRect rcDraw(0,0,100,100);
    CRect rcInserect;
    if( rcInserect.IntersectRect( rcClipAll,rcDraw ) )
    {
    dc.BitBlt(rcDraw.left,rcDraw.top,rcDraw.Width(),rcDraw.Height() &dcMemory1,0, 0, SRCCOPY); 
    }
    楼主的代码的问题:
    1:多次 this- >GetDC()却没有ReleaseDC()是有大量的GDI资源泄露的。
    2:GetDC()返回的DC 是无法得到InvalidateRect传过来的更新区域的
      

  6.   

    重新发一下,代码编排不好看UpdateWindow()是重绘整个窗口的的说法是错的。 在onpaint()中应该这样处理 
           
           /**
           * 得到剪裁区
            */
            CPaintDC dc(this);  
            CRect rcClipAll;
            dc.GetClipBox(  rcClipAll );        /**
            * 如果剪裁区和绘图区有相交,才绘制,甚至如果你要更提高效率,可以只绘制相交取
             */
            CRect rcDraw(0,0,100,100);
            CRect rcInserect;
            if( rcInserect.IntersectRect( rcClipAll,rcDraw ) )
            {
                dc.BitBlt(rcDraw.left,rcDraw.top,rcDraw.Width(),rcDraw.Height() &dcMemory1,0, 0, SRCCOPY); 
            }
    楼主的代码的问题: 
    1:多次 this-  >GetDC()却没有ReleaseDC()是有大量的GDI资源泄露的。 
    2:GetDC()返回的DC 是无法得到InvalidateRect传过来的更新区域的 
      

  7.   

    UpdateWindow()函数使用来立即向窗口放松WM_PAINT消息,InvalidateRect调用后不一定立即更新窗口
    最好使在Timer函数中直接更新某块区域
      

  8.   

    lyg_zy 说的没错。
    好的办法应该是你在OnTimer中变换一块内存DC里面的内容,然后InvalidateRect呼叫OnPaint
    在OnPaint中再把这块内存DC的内容Bitblt到屏幕上
      

  9.   

    有必要那么麻烦吗????
    直接在定时器里做就完了
    在定时器里getdc,getrect
    不过最好先画在memdc里,再拷到屏幕dc
      

  10.   

    InvalidateRect 就可以了!
      

  11.   

    MFC Windows程序设计(第二版)里面有详细的方法
      

  12.   

    添加
    OnEraseBkgnd()
    {
    return;
    }