Visual Studio Developer Center > Visual Studio vNext Forums > Visual C++ General > Invalidate make my screen flicker, and no solution can be found to help me

Answered Invalidate make my screen flicker, and no solution can be found to help me

  • Wednesday, September 17, 2008 8:46 AM
     
     
    My prog have bitmap that need to appear in certain conditions, and disappear when the condition fails. I can't make it with the background col cause the background have information to display.
    repainting all or double buffer - I don't think it will help cause the screen contain a lot of data, and the initial drawing takes time.
    tried also setredraw-false/true and it just stops responding at some point.
    can anyone have a new idea or can give me any tip to help me ?  

Answers

  • Wednesday, September 17, 2008 10:15 AM
     
     Answered
    One thing you can do to reduce flicker is handle WM_ERASEBKGND, and in the handler do nothing but return TRUE.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  
  • Thursday, September 18, 2008 3:38 PM
     
     Answered
    Aviadk:

    You call Invalidate(), or InvalidateRect(), and then the system sends WM_ERASEBKGND and WM_PAINT (in that order). A common cause of flicker is that the default OnEraseBkGnd() handler clears the screen too all white, and then your screen repaints.

    If you override OnEraseBkGnd() and just return TRUE, you disable this clearing of the screen.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  
  • Sunday, September 21, 2008 10:33 AM
     
     Answered
    Aviadk:

    You have to add the WM_ERASEBKGND handler using the message map. The resulting handler, OnEraseBkGnd() is not a method that you call yourself, but rather one that gets called automatically by Windows.

    You might seem to be missing some basic points about how Windows programming with MFC works.

    I guess if you call Invalidate() or InvalidateRect() with bErase equal to FALSE, then the WM_ERASEBKGND message does not get sent, but I always call them with the default bErase equal to TRUE, and then add the WM_ERASEBKGND handler in cases where I need it.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  
  • Sunday, September 21, 2008 12:13 PM
     
     Answered
    Aviadk:

    One last time. You do NOT call OnEraseBkGnd() in your own code. Windows calls it for you by sending the WM_ERASEBKGND message. You do understand about Windows messaging don't you?

    Your flicker problem may not have to do with WM_ERASEBKGND. But this is one common cause.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  

All Replies

  • Wednesday, September 17, 2008 9:25 AM
     
     Proposed Answer
    Please Elaborate your question little bit More .And for Repaint your App instead of Invalidate() use InvalidateRect() and handle WM_ERASEBKGND  inside your app.

    Thanx

    Rupesh Shukla
    • Edited by Pintu Shukla Wednesday, September 17, 2008 9:31 AM
    • Proposed As Answer by Pintu Shukla Monday, September 22, 2008 7:10 AM
    •  
  • Wednesday, September 17, 2008 10:15 AM
     
     Answered
    One thing you can do to reduce flicker is handle WM_ERASEBKGND, and in the handler do nothing but return TRUE.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  
  • Thursday, September 18, 2008 3:04 PM
     
     
    I tried InvalidateRect(), but without using WM_ERASEBKGND - should it come before  ?
    My program draw "map" that displays rectangle with certain information, and when the mouse is on top of some of the rectangle a bitmap of an arrow appear on other rectangle, and when the mouse moves out of the rectangle the arrow should disappear.
    When it occur the screen flick for a second, and since we moving the mouse on and off those specific rectangle the flicker happens quit often, and it's really bothering.
    Thanks
  • Thursday, September 18, 2008 3:38 PM
     
     Answered
    Aviadk:

    You call Invalidate(), or InvalidateRect(), and then the system sends WM_ERASEBKGND and WM_PAINT (in that order). A common cause of flicker is that the default OnEraseBkGnd() handler clears the screen too all white, and then your screen repaints.

    If you override OnEraseBkGnd() and just return TRUE, you disable this clearing of the screen.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  
  • Thursday, September 18, 2008 5:28 PM
     
     Proposed Answer
    An application sends the WM_ERASEBKGND message when the window background must be erased (for example, when a window is resized). The message is sent to prepare an invalidated portion of a window for painting.

    Remember one thing that default implementation of WM_ERASEBKGND message handler erases invalidated areas .After that,  WM_PAINT comes in the picture.If you return 1 (TRUE) from WM_ERASEBKGND you tell system to not to erase background .and for more detail regarding WM_PAINT and Wm_ERASEBKGND have a look in MSDN and same time just have a look for what is the difference between Invalidate() and InvalidateRect() also. Hope i am pretty clear now.

    Thanx


    Rupesh Shukla
    • Proposed As Answer by Pintu Shukla Monday, September 22, 2008 7:10 AM
    •  
  • Sunday, September 21, 2008 8:34 AM
     
     
    It's seem that It's not helping, or that I did it wrong
    I tried with :
        InvalidateRect(&rect,OnEraseBkgnd(NULL));  
        UpdateWindow();
    and also with OnEraseBkgnd(NULL) before, or the bool in InvalidateRect as false, and as true, all the possible scenarios.
    I also tried using WM_ERASEBKGND , but it's nor recognized by my compiler as I wrote it - using it as an function that gets bool, or putting bool into it, placing it inside InvalidateRect...
    for override I tried :
    BOOL CMMUView::OnEraseBkgnd(CDC* pDC)
    {
     // TODO: Add your message handler code here and/or call default
     return true;
     return CView::OnEraseBkgnd(pDC);
    }
    when CMMUView is the class that handling this redrawing.
    hope you can help me more,
    Thanks
    • Edited by Aviadk Sunday, September 21, 2008 9:36 AM
    •  
  • Sunday, September 21, 2008 10:33 AM
     
     Answered
    Aviadk:

    You have to add the WM_ERASEBKGND handler using the message map. The resulting handler, OnEraseBkGnd() is not a method that you call yourself, but rather one that gets called automatically by Windows.

    You might seem to be missing some basic points about how Windows programming with MFC works.

    I guess if you call Invalidate() or InvalidateRect() with bErase equal to FALSE, then the WM_ERASEBKGND message does not get sent, but I always call them with the default bErase equal to TRUE, and then add the WM_ERASEBKGND handler in cases where I need it.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  
  • Sunday, September 21, 2008 12:03 PM
     
     
    I added WM_ERASEBKGND using class wizard, and used OnEraseBkgnd(NULL) to call before\after InvalidateRect(&rect,True);
    I think one of the problems is that I'm calling them when I'm in OnMouseMove(), in the main screen.
    Am I still getting it wrong ?
  • Sunday, September 21, 2008 12:13 PM
     
     Answered
    Aviadk:

    One last time. You do NOT call OnEraseBkGnd() in your own code. Windows calls it for you by sending the WM_ERASEBKGND message. You do understand about Windows messaging don't you?

    Your flicker problem may not have to do with WM_ERASEBKGND. But this is one common cause.


    David Wilkinson | Visual C++ MVP
    • Marked As Answer by Yan-Fei Wei Monday, September 22, 2008 3:34 AM
    •  
  • Sunday, September 21, 2008 2:07 PM
     
     
    Is this the meaning : ?
     CWnd *pCalc;
     pCalc = FindWindow(NULL,NULL);

        pCalc->SendMessage(WM_ERASEBKGND);
        InvalidateRect(&rect,true);

    cause it's not helping...
  • Sunday, September 21, 2008 3:31 PM
     
     
    Just check david last post or read the complete thread once again.There is no need to call WM_ERASEBKGND inside your code window will do this for you. See Just check out all of these possibilities inside your code one more reason can be that you are loading a lots of resource on your window this also create such type of problem . So just check out all of these things and let us know the result then only can tell you exact reason of your proble,.

    Thanx

    Rupesh Shukla
  • Monday, September 22, 2008 7:04 AM
     
     
    I Think my First answer was quit clear anyway not a problem :X

    Thanx

    Rupesh Shukla
  • Sunday, September 28, 2008 8:02 AM
     
     
    Hi,
    I tried to override OnEraseBkGnd() by placing it in my main class, which inherits from CWnd;
    When I'm debugging I can see that it never get in there, only to the original OnEraseBkGnd();
    I used exactly with the same API , including using it as protected.
    Any suggestions to solve it ?

    Pibtu - If the prob is caused from loading a lots of resource on my wnd, can I do anything to solve it ?
    Thanks,
  • Sunday, September 28, 2008 11:40 AM
     
     
    Aviadk:

    You have to handle WM_ERASEBKGND in the class whose window is flickering. In MFC this is normally a CView-derived class.

    Note that OnEraseBkGnd() is not a virtual method -- you must add it via the message map mechanism, or your "override" will not be called.


    David Wilkinson | Visual C++ MVP
  • Sunday, September 28, 2008 3:02 PM
     
     

    Pibtu - If the prob is caused from loading a lots of resource on my wnd, can I do anything to solve it ?
    Thanks,


    Spelling Mistake .See i don't know whether you had followed my suggestion . Because i am unable to find that any of my suggestion helped you .Anyway as i said my first suggestion was enough to solve your problem .Anyway will suggest you open your class wizard Select Now from Message Map tab Select Proper Dialog class name from class name option .Now from Messages Select WM_ERASEBKGND and double click on the message Now from Member Function select OnEraseBkgnd() and click on Edit code. Now your class will implement all the basic stuff for WM_ERASEBKGND inside your project and at proper position .After that do what ever you want as you have lots of suggestion in this thread. And Are you really loading heavy Resource at your Dialog . Then load all the resource at run time instead of design time and Don't forget to Invalidate your window.

    Thanx
     

    Rupesh Shukla
    • Edited by Pintu Shukla Sunday, September 28, 2008 3:03 PM
    •  
  • Friday, September 04, 2009 11:10 PM
     
     
    Please excuse my ignorance. I draw my graphics on an object of System.Windows.Forms.Panel. None of the events in this class (as shown in the Visual Studio (Visual C# 2008 Express Edition) IDE) has a name that resembles ERASEBKGND. Also, none of the methods I can see are called OnEraseBkGnd(). It looks to me that I am way on left field (perhaps in another universe). The closest event name I see is "BackgrounImageChanged". Can you point me toward the direction of what you are talking about?

    Thanks for your help.
    Mike
  • Saturday, September 05, 2009 2:26 AM
     
     
    Yes, you are using C#.

    This thread was about native C++ with MFC.

    Another universe indeed.

    David Wilkinson | Visual C++ MVP
  • Saturday, September 05, 2009 2:44 AM
     
     
    This is my laugh of the day.

    Aviadk, that's what you get for posting a C# question in a C++ forum!