rect.left = 0;
rect.top = 0;
rect.right = ClientWidth; //1000
rect.bottom = ClientHeight;//256
InvalidateRect(rect,1); //Refresh the area only but flickering occurred & buttons hidden if any other window appear.
//InvalidateRect(rect,0);// If any other window appear buttons are hidden.
Please find the attachment and replace the .cpp from Dave.rar.
You missed to add a note that you do this InvalidateRect inside WM_PAINT handler. That is definitely a bad idea, as you make the system never stop with refreshing. Please explain what you tried to achieve with that.
How can i draw an image without flickering?
You prepare your bitmap bits first, and only then you invalidate the paint area. The paint must be done in minimum of calculations, a single blit is preferable. The process of refreshing must be driven by some mechanism separate from WM_PAINT handler, thread maybe, or timer routine for example.
You may see flickering when Windows erases the client area, that is, sets all of the pixels in the client area to the window's class's background brush color. To prevent Windows from doing this, you need to capture the WM_ERASEBKGND message so that it does not reach the default window procedure. According to MFC documentation, you do this by overriding the OnEraseBkgnd() method. However, if another window is moved around on top of your window, Windows will still erase the other window with your window's class's background brush color. To prevent this, set your window's class's background brush to NULL_BRUSH when the window's class is created.
But since you are not creating your window's class from scratch, you may not be able to do this.
As Igor noted, you should be updating your image and calling the InvalidateRect() function from inside your OnTimer() method.
Also, the flickering could be caused by your monitor. I have two monitors. The test application, that I wrote and have since added a timer event to scroll the image vertically, flickers a little on one of my monitors but not on the other.
Last edited by Coder Dave; March 4th, 2013 at 02:15 AM.
Using the above code, I recover my project from flickering now. But I can't to display the dialog background now.
I think I understand your problem now. We do not want the dialog to redraw its background where the image is, since this causes flickering and is inefficient. However, we can not stop the dialog from redrawing the background behind the image without stopping it from redrawing the background all together. The solution is to write your own code to draw the background where the image is not present.
I have never used the CDialog class, so I do not know how much it is doing behind the scenes. If this was just a regular window that you created from scratch, you would draw the dialog background and the controls that go on top of it in the WM_PAINT event. Of course, you would still use BitBlt() in the WM_PAINT event to display the image.
Alternatively, you could create your bitmap so that it takes up the whole client area. Then, part of the bitmap would be used to draw your image and the other part would be used to draw your text and other controls. If you draw on the bitmap's compatible device context with the GDI functions, your text and controls will be drawn onto the bitmap. Then all you would need to do in your OnPaint() method is to use BitBlt() on the entire client area. Your OnEraseBkgnd() method should do nothing except return true.
Do not create a brush object in any event the will be called over and over again. Instead, create the brush in the create event and save the handle somewhere so that other events can access it. Delete the brush object in the destroy event. Also, your code above has an error. Since you do not set the brush handle to NULL after you delete it, the next time the code is executed, it will try to fill the rectangle with an invalid brush handle.
Last edited by Coder Dave; March 6th, 2013 at 11:08 PM.