只刷新一个控件,用RedrawWindow很不划算啊,而且闪得厉害。请问如何只刷新一个控件?或是一个区域?

解决方案 »

  1.   

    http://www.qqgb.com/Program/VC/VCsystem/Program_252432.html
      

  2.   

    这个主要是因为你调用了系统的重绘函数,系统在重绘的时候会用背景刷先清除背景再绘制窗口内容,所以前后三个场景转换的时候有一个白屏,所以感觉闪。可以用如下方法解决,一是用双缓冲绘制图形,再一个重要的步骤是,因为windows窗口默认都会在OnPaint的时候先用背景画刷清除一下绘图区再绘制内容,所以要想避免闪烁必须将这个清除绘图区的步骤给去掉,所以这个需要在WM_ERASEBKGND消息处理函数里处理,在return CWnd::OnEraseBkgnd(pDC);之前直接return true;即可。
      

  3.   

    具体目的是这样的:有背景图的对话框,上面有静态文本控件用于显示进度(只有10%,20%...,100%几种值)。每修改一次文本内容,得刷新一次,否则字都堆在一起。用RedrawWindow闪烁明显,而且CPU开销很大。To Mackz:能否更详细点?
    To mengde007:似乎还是要刷新整个窗口。
    To xsc2001:谢谢,很详细。不过这里不绘制自己的图形,不需要双缓冲绘图吧?另外BOOL CPDlg::OnEraseBkgnd(CDC* pDC)
    {
    if(m_bmp.GetSafeHandle() && m_nType)
    {
    CRect rect;
    GetClientRect(rect); CDC bgDC;
    bgDC.CreateCompatibleDC(NULL);
    bgDC.SelectObject(&m_bmp); BITMAP bmp;
    m_bmp.GetBitmap(&bmp);
    int nWidth = bmp.bmWidth;
    int nHeight = bmp.bmHeight; switch(m_nType)
    {
    case BITMAP_CENTER:
    CPDlg5::OnEraseBkgnd(pDC);
    BITMAP bmp;
    m_bmp.GetBitmap (&bmp);
    pDC->BitBlt ((rect.Width() - bmp.bmWidth) / 2, (rect.Height() - bmp.bmHeight) / 2, bmp.bmWidth, bmp.bmHeight, &bgDC, 0, 0, SRCCOPY);
    return TRUE;
    case BITMAP_STRETCH:
    pDC->SetStretchBltMode(HALFTONE);
    pDC->StretchBlt(0, 0, rect.Width(), rect.Height(), &bgDC, 0, 0, nWidth, nHeight, SRCCOPY);
    return TRUE;
    default:
    CBrush bgBrush(&m_bmp);
    pDC->FillRect(rect,&bgBrush);
    return TRUE;
    }
    }
    else
    CPDlg::OnEraseBkgnd(pDC); return TRUE;
    }这里没有return CWnd::OnEraseBkgnd(pDC),可是依然闪烁啊。
      

  4.   

    得到控件句柄hWnd,然后UpdateWindow(hWnd)
      

  5.   

    To biweilun:这个没能解决字重叠的问题。具体情况请看5楼。
    概括一下就是不重叠,不刷新整个对话框(闪烁尽量不明显,CPU开销也小)
      

  6.   

    试试将绘图操作放到 CPDlg 的 OnPaint 中(不需要在其中调用 CPDlg5::OnEraseBkgnd(pDC)
    )。
      

  7.   


    void CPDlg::Refresh()
    {
    RECT   r;  
    SetRect(&r , 0 , 0 , 40 , 40 );
    InvalidateRect(&r,TRUE);
    UpdateWindow();
    }用SPY++可以接收到WM_PAINT消息,那么OnPaint函数中应该做些什么呢?
      

  8.   

    RECT   r;  
    SetRect(   &r,   20,   80,   150,  90   );
    RedrawWindow(&r);
    这样可以刷新指定区域了,可是这个坐标很难准确获得。
    MSDN上说void SetRect(int x1,int y1,int x2,int y2 )x1
        Specifies the x-coordinate of the upper-left corner.
    y1
        Specifies the y-coordinate of the upper-left corner.
    x2
        Specifies the x-coordinate of the lower-right corner.
    y2
        Specifies the y-coordinate of the lower-right corner. 我这里Static控件左上角坐标是(20,80),长130,高10
    按照VC里头显示的控件的坐标刷新,发现该刷新的没刷新,不该刷新的在刷新(闪烁)。
    这个坐标究竟如何确定?