In image processing and programming, double buffering is a basic technology. We know that if the form needs to perform complex graphic processing when responding to the wm_paint message, the form will flash due to frequent refresh during repainting. The effective solution to this problem is the dual-buffer technology.
When the form is refreshed, there is always an onerasebkgnd process to erase the original image. It uses the background color to fill the form drawing area, and then calls the new drawing Code Re-painting, this will cause the contrast of the image color. When wm_paint responds frequently, this contrast becomes more and more obvious. So we can see the flickering phenomenon.
We will naturally think that it is the most direct way to avoid filling the background color. But in that case, the form will become a mess. Because the original image is not cleared every time the image is drawn, the image remains, so the screen will often become messy when the screen weight is painted. Therefore, it is not enough to prohibit background re-painting. We had to re-plot it, but it was fast, so we thought of using the bitblt function. It supports the copying of graphic blocks at a fast speed. We can plot the image in the memory first, then use this function to copy the completed graph to the foreground, and disable background refresh. This eliminates the flash swap. The above is the basic idea of Double Buffer plotting.
Program by using the common graph method. Add the drawing code to the ondraw function of the video class. Here we draw a number of concentric circles, the Code is as follows:
[CPP]
View plain
Copy
Print
?
- cbcdoc * pdoc = getdocument ();
- assert_valid (pdoc);
- cpoint ptcenter;
- crect rect, ellipserect;
- getclientrect (& rect);
- ptcenter = rect. centerpoint ();
- for ( int I = 20; i> 0; I --)
- {
- ellipserect. setrect (ptcenter, ptcenter);
- ellipserect. inflaterect (I * 10, I * 10);
- PDC-> ellipse (ellipserect);
- }
Cbcdoc * pdoc = getdocument (); assert_valid (pdoc); cpoint ptcenter; crect rect, ellipserect; getclientrect (& rect); ptcenter = rect. centerpoint (); For (INT I = 20; I> 0; I --) {ellipserect. setrect (ptcenter, ptcenter); ellipserect. inflaterect (I * 10, I * 10); PDC-> ellipse (ellipserect );}
Compile and runProgramTo change the window size.
In the double buffering method, the first thing to do is to block background refreshing. Background refreshing is actually in response to the wm_erasebkgnd message. We can add a response to this message in the View class to see the missing
Save the following code:
[CPP]
View plain
Copy
Print
?
- BoolCmyview: onerasebkgnd (CDC * PDC)
- {
- ReturnCview: onerasebkgnd (PDC );
- }
Bool cmyview: onerasebkgnd (CDC * PDC) {return cview: onerasebkgnd (PDC );}
Is to call the onerasebkgnd function of the parent class. We can block this call and only directly return true.
The following describes the steps for drawing the memory buffer.
[CPP]
View plain
Copy
Print
?
-
- Cbitmap bit;
-
- Bit. loadbitmapa (idb_bitmap1 );
-
- Bitmap bm;
- Bit. getbitmap (& BM );
-
- CDC memdc;
-
- Memdc. createcompatibledc (PDC );
-
- Cbitmap * poldbitmap = memdc. SelectObject (& bit );
-
- Crect rect;
-
- Getclientrect (& rect );
-
- PDC-> setstretchbltmode (coloroncolor );// If this mode is not set, the image will be seriously distorted.
-
- PDC-> stretchblt (0, 0, rect. Width (), rect. Height (),
-
- & Memdc, 0, 0, BM. bmwidth, BM. bmheight, srccopy );
-
- Memdc. SelectObject (poldbitmap );
- Memdc. deletedc ();// Delete the DC
-
- BM. deleteobject ();// Delete a bitmap
cbitmap bit; bit. loadbitmapa (idb_bitmap1); bitmap bm; bit. getbitmap (& BM); CDC memdc; memdc. createcompatibledc (PDC); cbitmap * poldbitmap = memdc. selectObject (& bit); crect rect; getclientrect (& rect); PDC-> setstretchbltmode (coloroncolor ); // if this mode is not set, the image will be severely distorted. PDC-> stretchblt (0, 0, rect. width (), rect. height (), & memdc, 0, 0, BM. bmwidth, BM. bmheight, srccopy); memdc. selectObject (poldbitmap); memdc. deletedc (); // Delete dcbm. deleteobject (); // delete a bitmap
because of the complicated drawing operations, we can see that the copying operation is fast, which eliminates the flickering phenomenon.
Q: What is the difference between true and false returned by the onerasebkgnd function?
A:
wm_erasebkgnd
return values
An application shocould return Nonzero if it erases the background; otherwise, it shocould return zero.
A: True indicates that the background is refreshed. False indicates that the background needs to be refreshed in onpaint.
q: what is the difference between the background image in the draw dialog box in onerasebkgnd and the background image in the draw dialog box in onpaint? What is the difference between onerasebkgnd and ctlcolor?
A:
onerasebkgnd occurs when the window size changes. It draws the window background. onctlcolor is used when the window control needs to be drawn, it draws the
Control of the window.
A:
onerasebkgnd: called when the window background needs to be re-painted.
onpaint: At this time, onerasebkgnd has been called. Therefore, operations performed on the background in the response function will overwrite the operations performed in onerasebkgnd.
onctlcolor: A subwindow that responds when the window is to be drawn (for the first time). You can send an hbrush request to the parent window through wm_ctlcolor.