Invalidate太恐怖了,它会导致整个客户区重画,不闪才怪。把OnPaint中刷新数据那部分代码拿出来,放到OnTimer中就好了。

解决方案 »

  1.   

    1、用InvalidateRect(yourrect);
    2、在OnPaint中用双缓冲来做。即把东西画到一个内存DC上,再BitBlt到paintDC上。
    3、处理WM_ERASEBKGND
      

  2.   

    我已经试了Invalidate的方法,但是还是能明显感觉到闪烁。
    另外,我不太明白zeroweb的后面两种方法
      

  3.   

    你的程序如果不是对位图操作,而是简单的更新控件(例如按钮标题、Edit文字等),那么zeroweb(我不想再做软件了)的后两种方法没有必要。第一种方法也是多此一举——因为你根本不需要对话框重绘,你只是想让某个控件改变而已——那就只让控件改变好了。
    当然,如果你的确是对位图进行操作的话,那么zeroweb(我不想再做软件了)的三种方法需要同时使用——这是GDI绘图最基本的技术。
    总之,避免闪烁只有一个原则:不要惊动无关的“人”,不要让用户看到你“绘制的过程”(双缓冲)。谁需要更新,就只画谁;那部分需要更新,就只画那部分。
      

  4.   

    为了画的最少……
    void CEMapThumbnailView::RedrawRectTracker()
    {
    CRect rectOutside,rectInside;
    m_RectTracker.GetTrueRect(rectOutside);
    rectInside=m_RectTracker.m_rect;
    rectInside.InflateRect(1,1);
    CRect rectTemp;
    //left
    rectTemp.SetRect(rectOutside.left,rectOutside.top,rectInside.left,rectOutside.bottom);
    InvalidateRect(rectTemp,TRUE);
    //right
    rectTemp.SetRect(rectInside.left,rectOutside.top,rectOutside.right,rectOutside.bottom);
    InvalidateRect(rectTemp,TRUE);
    //top
    rectTemp.SetRect(rectOutside.left,rectOutside.top,rectOutside.right,rectInside.top);
    InvalidateRect(rectTemp,TRUE);
    //bottom
    rectTemp.SetRect(rectOutside.left,rectInside.bottom,rectOutside.right,rectOutside.bottom);
    InvalidateRect(rectTemp,TRUE);
    UpdateWindow();
    }