Realization of non-flashbrush screen technology
Author: tree love mail mailbox: spily365@163.com
During the process of implementing the drawing, the displayed graph will always flash, the author has been tortured for a long time, by requiring to ask the master, searching information, the problem has been basically solved, and the document is now organized for everyone. 1. Show Why is the graph flashing? Our drawing process is mostly in the onDraw or onpaint function, and OnDRAW is called by OnPaint when the screen is displayed. When the window needs to be redrawged due to any reason, always clear the display area with the background color, and then call onpaint, and the background color is often contrary to the drawing content, so that the alternation of the background color and display graphic in a short time , Make the display window look flashing. If you set the background brush into null, it will not flash anyway. Of course, this will make the display of the window into a group, because there is no background color to clear the original graphics when redraw, and a new graphic is superimposed. Some people will say that the flash is because the speed of the drawing is too slow or the displayed graphic is too complicated. In fact, it is not pair, the display speed of the drawing is not fundamentally. For example, in OnDRAW (CDC * PDC): PDC-> MoveTo (0); PDC-> LineTo (100, 100); this drawing process should be very simple, very fast, but pull the window changes See the flash. In fact, in the truth, the more complex the process of the drawing, the less smooth, because the time to draw the time with the background clearance screen, the more unacceptable to the flicker, the more it will be. For example: clear screen time is 1s drawing time is 1S, so it is 5 times in continuous heavy painting within 10s; if the screen time is 1S constant, the drawing time is 9S, so the continuous scriptures within 10s Will only flash once. This can also be trial, written in OnDraw (CDC * PDC): for (int i = 0; i <100000; i ) {PDC-> Moveto (0, i); PDC-> LineTo (1000, i); } Oh, the program is a bit variance, but it can explain the problem. Speaking here, some people have to say, why is a simple graphic look so flashes? This is because the complex graphic is large, and the contrast caused by heavy draws is relatively large, so it feels powerful, but the flashing frequency is low. Then why is the animation of heavy call frequencies, but it doesn't flash? Here, I have to emphasize again, what is it? Flashing is contrary, the greater the contrast, the worse the flashes. Because the difference between the two consecutive frames of the animation is small, it looks not flashing. If you don't believe, you can add a pure white frame in the middle of each frame of the animation, not flashing. 2, how to avoid flashing after knowing the reason for the graphic display, it is good to do. First of all, it is certainly the background drawing process provided by the MFC. There are many ways to achieve, * You can pay NULL * on the background of the registration class of the window to the window, or modify the background STATIC CBRUSH Brush (RGB (255, 0)); setClasslong (this-> m_hwnd, GCL_HBRBACKGROUND, (HBRUSH) Brush); * To be easily returned to TRUE, you can return to True, and the graphic display does not flash, but the display is also the same as before. Becoming a mess. How to do? This is to use a dual cache method. The double buffer is in addition to the display on the screen, there are graphics in memory.
We can draw the graphics you want to display first in memory, and then once again overwise the graphics in the memory into the screen in one point (this process is very fast because it is a very standard memory copy). In this way, when drawing in memory, whenever the contrast, large background colors will not flash, because it is invisible. When attached to the screen, because the final graphic and screen display in memory is very small (if there is no exercise, there is no difference), which does not flash. 3, how to implement the double buffer first give the implementation program, then explain, in OONDRAW (CDC * PDC): CDC MEMDC; // First define a display device object cbitmap membitmap; // Define a bitmap object / / Subsequently established a screen display compatible memory display device MEMDC.CREATECOMPALEDC (NULL); // Can't draw it, because there is no place to draw ^ _ ^ // below to create a bitmap with the screen display, as for bitmap Size, you can use the size of the size MEMBITMAP.CREATECOMPAMPAMPATIBLEBITMAP (PDC, NWIDTH, NHEIGHT); // Over the bitmap to the memory display device // Only the memory display device selected in the bitmap is placed, painted CBITMAP * POLDBIT = MEMDC.SelectObject (& Membitmap); // First use the background color to clear the bitmap, here I use white as background // You can also use the color you should use MEMDC.FILLIDRECT (0, 0, NWIDTH, NHEIGHT, RGB (255, 255, 255)); // Draw Memdc.moveto (...); MEMDC.LINETO (...); // copy the graph in the memory to display PDC-> Bitblt (0, 0, NWIDTH, NHEIGHT, & MEMDC, 0, 0, Srcopy); // After cleaning MEMBITMAP.DELETEOBJECT (); MEMDC.DELETEDC (); Prohibiting the original image can be reloaded OnraseBkgn () Function, let it return to True. Such as Bool CMywin :: OneRaseBkGnd (CDC * PDC) {Return True; // Return CWnd :: OneRaseBkGnd (PDC); // comment out the original statement of the system. } The above annotations should be exhausted, and there is not much to talk nonsense. 4, how to improve the efficiency of the drawing In fact, the map drawn in the OnDraw (CDC * PDC) is not all displayed, for example: you have drawn two rectangles in the onDraw, although two rectangles in one redraw The drawing function is executed, but it is likely to have only one display, because the MFC itself sets the cropped zone in order to improve the efficiency of the redraw. The role of the cropped area is: Only the drawing process in this area will be truly valid. It is invalid in the area, even if the drawing function is executed outside the area, it will not be displayed. Because most cases of windows re-draws because the window portion is blocked or the window is scrolling, the changed area is not a whole graph, and this part needs to be changed. The cut zone in the PDC. Because the display (memory or memory is called) is much more time consuming than the calculation of the drawing process, it is only the part of the cut zone, which is only displayed, greatly increased the display efficiency. But this cut zone is MFC setting, which has increased display efficiency for us, how to further improve efficiency during the drawing of complex graphics? Then there is only the drawing process outside the cropped area. You can get a crop zone with PDC-> getClipbox (), and then judge whether your graph is in this area when drawing, if you are in painting, you don't paint.