First, let's talk about the cause of flickering. When the window needs to be re-painted for any reason, the background color or background image is used to clear the display area before the image is displayed, in this way, the background color and the display image appear in turn in a short period of time, making the display window appear flashing. If you set the background fl to null, no matter how you duplicate the drawing, it will not flash, but it will make the display of the window messy, because there is no background color to clear the original image during the re-painting, and a new image is superimposed.
The general solution is to use dual buffering to create a memory image, draw the background and image to the image first, and then display the drawn image to the window, in this way, no flashes will occur. In fact, the image display process is hidden. It was originally at the front-end. You can see that the background is first painted on the canvas, and then the image is painted, now we have finished the painting in the background and show it to you.
It seems that the solution is to draw images at a time. In fact, the key is not to overlap any background and images during painting. It has little to do with whether to draw images at a time. The computer's drawing speed is still very fast. If you don't believe it, you can try setting the background to null so that the background will not flash. Then, you can call bitblt repeatedly to fill the entire window with a small image, it will not flash, but if you change the cycle step to overlap the image, it will start to flash.
Knowing the cause of flickering, it is not difficult to find a solution without double buffering. Calling excludecliprect can exclude the area of painting, draw the image first, excludecliprect the area of the image, and then draw the background, it is equivalent to sticking a canvas with a hole dug to a window, so that no overlap will be drawn and no flashes will be generated.
API code. A 300*200 image is always displayed in the lower right corner of the window. The background is Black:
Case wm_paint:
{
Paintstruct pS;
Rect RC;
HDC hmemdc;
Getclientrect (hwnd, & rc );
Beginpaint (hwnd, & PS );
Hmemdc = createcompatibledc (PS. HDC );
SelectObject (hmemdc, hbmp );
Bitblt (PS. HDC, RC. Right-300, RC. Bottom-200, 300,200, hmemdc, srccopy );
Excludecliprect (PS. HDC, RC. Right-300, RC. Bottom-200, RC. Right, RC. Bottom );
Fillrect (PS. HDC, & rc, (hbrush) getstockobject (black_brush ));
Deletedc (hmemdc );
Endpaint (m_hwnd, & PS );
Return 0;
}
Sometimes, due to the refresh area issue, the window may be adjusted, but the wm_paint Code does not work. In this case, you need to respond to the wm_size message and notify the screen to update it:
Case wm_size:
Invalidaterect (hwnd, null, false );
Break;
This method is also applicable to displaying multiple images. As long as an image is drawn, excludecliprect can drop the image area. However, if the image overlaps, the order of drawing is reversed, that is, the image that is built on the top needs to be drawn first, and the background is refreshed for the entire window.