1. Why does the displayed image FLASH [/B]
Most of our drawing processes are stored in the ondraw or onpaint functions. ondraw calls onpaint for screen display. When the window needs to be re-painted for any reason, the display area is always cleared with the background color before onpaint is called. The background color is often in a large contrast with the drawing content, in this way, the background color and the display image appear alternately in a short period of time, so that the [/B] display window looks like a flash. If you set the background to null, no matter how you redraw the image, [/B] will flash. Of course, this will make the display of the [/B] window messy, because there is no background color to clear the original drawing [/B, new images are superimposed. Some people may say that the blinking [/B] is because the drawing speed is too slow or the graphic display is too complex. In fact, this is not true for [/B, the effect of drawing display speed on flickering [/B] is not [/B] fundamental. For example, in ondraw (CDC * PDC), write as follows:
PDC-> moveTo (0, 0 );
PDC-> lineto (100,100 );
This drawing process should be very simple and fast, but you will still see flashes when pulling the window changes [/B]. In fact, in principle, the more complex the drawing process is, the slower the drawing process is. [/B] The less the drawing process should be, because the larger the ratio of the time used for drawing to the time used for clearing the screen with the background, the more obvious the person will feel for blinking [/B. For example, if the screen time is 1 s, the drawing time is also 1 s, so that the continuous re-painting within 10 s will flash five times [/B; if the screen time is 1 s without changing [/B], and the drawing time is 9 s, the continuous re-painting within 10 s will only Flash [/B] once. This can also be tested by writing in ondraw (CDC * PDC) as follows:
For (INT I = 0; I <100000; I ++)
{
PDC-> moveTo (0, I );
PDC-> lineto (1000, I );
}
The program is a bit extreme, but it can explain the problem.
Some people may want to talk about it again. Why does a simple image look like a complex one? This is because the area occupied by complex images is large, and the contrast caused by the re-painting is relatively large, so I feel that the flash is a little more powerful, but the frequency of blinking [/B] is lower. Why is the animation repainting frequency high, but it does not look like [/B] flashing? Here, I will emphasize again, what is blinking [/B? Blinking [/B] is the contrast. The larger the contrast, the more powerful the blinking [/B. Because the animation has very little difference between two consecutive frames, it does not look like a [/B] Flash. If you do not use the [/B] letter, you can add a pure white frame in the middle of each frame of the animation. It is strange not to use the [/B] Flash.
2. How to Avoid blinking [/B]
After you know why the image FLASH [/B], you can do it right. The first step is to remove the background rendering [/B] process provided by MFC. There are many implementation methods:
* When the window is formed, you can pay NULL for the registration background of the window.
* You can also modify the background after the formation.
Static cbrush brush (RGB (255, 0, 0 ));
Setclasslong (this-> m_hwnd, gcl_hbrbackground, (long) (hbrush) brush );
* You can also load onerasebkgnd (CDC * PDC) to return true directly.
The background is gone, and the result graph display does not [/B] Flash, but the display is also messy as mentioned above. How can I [/B] Do it? This requires the dual-Cache method. In addition to displaying images on the screen, the dual-buffer mode also displays images in the memory [/B]. We can first draw the image to be displayed in the memory [/B, and then overwrite the images in the memory to the screen one by one point at a time (this process is very fast, because it is a very regular memory copy ). In this way, when drawing in the memory, the background color with any contrast is not cleared [/B], because [/B] is not displayed. When it is attached to the screen, because the final image in the memory is slightly different from the screen display image (if there is no motion, of course there is no difference), it does not look like [/B] will flash.
3. How to implement dual Buffering
The implementation program is provided first, and then explained again, also in ondraw (CDC * PDC:
CDC memdc; // define a display device object
Cbitmap membitmap; // defines a bitmap object.
// Create a memory display device compatible with Screen Display
Memdc. createcompatibledc (null );
// At this time, no [/B] drawing is available, because there is no place to draw
// A bitmap compatible with screen display is created below. The size of the bitmap can be set to the size of the window.
Membitmap. createcompatiblebitmap (PDC, nwidth, nheight );
// Select the bitmap to the memory display device.
// Only the memory display device with the bitmap selected can draw a local image and draw it to the specified bitmap.
Cbitmap * poldbit = memdc. SelectObject (& membitmap );
// Use the background color to clear the bitmap. Here, I use white as the background color.
// You can also use your own color
Memdc. fillsolidrect (255,255,255, nwidth, nheight, RGB ));
// Drawing
Memdc. moveTo (......);
Memdc. lineto (......);
// Copy the image in the memory to the screen for display
PDC-> bitblt (0, 0, nwidth, nheight, & memdc, 0, srccopy );
// Cleanup after drawing is complete
Membitmap. deleteobject ();
Memdc. deletedc ();
See annotations.
4. How to Improve the drawing efficiency
In fact, the [/B] graph drawn in ondraw (CDC * PDC) is not displayed in [/B]. For example, you have drawn two rectangles in ondraw, in one re-painting, although the two rectangles are being drawn, the [/B] function is executed, but it is likely that there is only one display, this is because MFC sets the cropping area to improve the repainting efficiency. The purpose of the cropping area is: only the plotting process in this area will be truly valid, and those outside the area will be invalid, even if [/B] executes the drawing function outside the zone, it is not displayed in [/B. In most cases, the re-painting of a window is mostly due to partial occlusion of the window or scrolling of the window. The changed area is not [/B] but only a small part of the entire image, this part needs to be changed in the cutting area of the PDC. Because the display (display to memory or video memory) is much more time-consuming than the calculation of the drawing process, only the display part should be displayed after the cropping area, greatly improving the display efficiency. However, this cropping area is set by MFC, which has improved the display efficiency. How can we further improve the efficiency when drawing Complex Images [/B? Then, only the plotting process outside the cropping area is removed. You can first use PDC-> getclipbox () to get the cropping area, and then determine whether your image is in this area during the drawing. If it is in, if the image is not [/B], the image is not [/B.
If your drawing process is not [/B] complex, this may not improve the drawing efficiency [/B.
For specific procedures, you can refer to the following source code:
5. Non-blinking [/B] background image rendering [/B] Code Implementation
//////////// No blinking [/B] background image rendering [/B] //// //
/// Program Design: icemen (warm ice)
//////////////////////////////////////// //////
Bool cstrucview: onerasebkgnd (CDC * PDC)
{Int nwidth;
Int nheight;
// Cview: onerasebkgnd (PDC );
Cstrucdoc * pdoc = getdocument ();
Assert_valid (pdoc );
Crect rect;
Getwindowrect (& rect );
Nwidth = rect. Width ();
Nheight = rect. Height ();
CDC memdc;
Cbitmap membitmap;
Memdc. createcompatibledc (null );
Membitmap. createcompatiblebitmap (PDC, nwidth, nheight );
Cbitmap * poldbit = memdc. SelectObject (& membitmap );
Memdc. fillsolidrect (255,255,255, nwidth, nheight, RGB ));
//////////////////////////////////////// ///////////////
//// The background color is displayed //////////////
//// The following figure shows the background image //////////////
//////////////////////////////////////// ///////////////
Getclientrect (rect );
Bitmap bm;
CDC dcmem;
Verify (m_bmp .getobject (sizeof (BM), (lpvoid) & BM ));
Dcmem. createcompatibledc (PDC );
Cbitmap * poldbmp = (cbitmap *) dcmem. SelectObject (& m_bmp );
Memdc. bitblt (rect. Right-BM. bmwidth)/2,
(Rect. Bottom-BM. bmheight)/2,
BM. bmwidth, BM. bmheight, & dcmem, 0,0, srccopy );
Dcmem. SelectObject (poldbmp );
//////////////////////////////////////// ///////////////
//// The above is the background image //////////////
//////////////////////////////////////// ///////////////
PDC-> bitblt (0, 0, nwidth, nheight, & memdc, 0, srccopy );
Membitmap. deleteobject ();
Memdc. deletedc ();
Return true;
}
//////////// No blinking [/B] background image rendering [/B] //// //
//////////////////////////////////////// /////
Note: m_bmp is defined in strucview. h In the program and is a bitmap Resource class.
Protected:
Cbitmap m_bmp;
Add the following sections. Of course, you can add loadbitmap or file resources at any time!
Cstrucview: cstrucview ()
{
Verify (m_bmp .loadbitmap (idb_bitmap3 ));
}