MFC double-buffered drawing (2015.09.24)

Source: Internet
Author: User

Problem Introduction:

Recently, when trying to write a snake game, there is a problem: when the system sends a WM_PAINT message to the window at a faster frequency, the call to the OnPaint () function will flicker when it draws a graphic in the window.

Problem Analysis:

This is true when we put the drawing process in the OnPaint () function (in the OnDraw () function, because OnDraw () is called by OnPaint (), and the window needs to be redrawn due to the frequent receipt of the system's WM_PAINT messages. The redraw process begins with erasing the contents of the window (redrawing the window with the brush of the current background color), and then redraws the contents of the window in the window client area according to the drawing statement. Due to the fast frequency, the current window will produce the background color and the window content of the repeated alternating, the color difference caused by the flicker effect.

Problem solving:

Double-buffered drawing: Double-buffering creates an object in memory that is consistent with the screen drawing area, drawing the graphic to the object in memory, and then copying the graphics on the object to the screen at once.

First send the drawing code in the original OnPaint () function:

1 voidCmainwindow::onpaint ()2 {3CCLIENTDC DC ( This);4 5CPen White_pen (Ps_solid,1, RGB (255,255,255));6CPen *poldpen = DC. SelectObject (&white_pen);7CBrush White_brush (RGB (255,255,255));8CBrush *poldbrush = DC. SelectObject (&White_brush);9 Ten     //Draw Background Onedc. Rectangle (&m_rcback); A      -     //Draw Scoreboard - DC. Selectstockobject (Gray_brush); thedc. Rectangle (&m_rcscoreboard); -  -     //Draw Wall - DC. Selectstockobject (Black_brush); +  -     inti; +      for(i =0; i < map_size_cx; ++i) A     { atdc. Rectangle (m_rcgamemap[i][0]); -dc. Rectangle (M_rcgamemap[i][map_size_cy-1]); -     } -      for(i =1; I < map_size_cy-1; ++i) -     { -dc. Rectangle (m_rcgamemap[0][i]); indc. Rectangle (M_RCGAMEMAP[MAP_SIZE_CX-1][i]); -     } to  + DC. SelectObject (Poldpen); - DC. SelectObject (Poldbrush); the}

Because of the flashing problem of the above code into the OnEraseBkgnd () function (and added a WM_ERASEBKGND message map, as the name implies, the system notifies the client area to erase the message), and let OnPaint () do nothing, the code is as follows:

1 void Cmainwindow::onpaint () {};

1BOOL Cmainwindow::onerasebkgnd (CDC *PDC)2 {3 CRect rect;4 CDC Dcmem;5GetClientRect (&rect);;6 CBitmap bmp;7 8 Dcmem.createcompatibledc (PDC);9 bmp. CreateCompatibleBitmap (PDC, rect. Width (), Rect. Height ());TenCBitmap *poldbit = Dcmem.selectobject (&bmp); OneDcmem.fillsolidrect (Rect, RGB (255,255,255)); A  -     // -     //Draw the     // -CPen White_pen (Ps_solid,1, RGB (255,255,255)); -CPen *poldpen = Dcmem.selectobject (&white_pen); -CBrush White_brush (RGB (255,255,255)); +CBrush *poldbrush = Dcmem.selectobject (&White_brush); -  +     //Draw Background ADcmem.rectangle (&m_rcback); at  -     //Draw Scoreboard - Dcmem.selectstockobject (gray_brush); -Dcmem.rectangle (&m_rcscoreboard); -  -     //Draw Wall in Dcmem.selectstockobject (black_brush); -      to     inti; +      for(i =0; i < map_size_cx; ++i) -     { theDcmem.rectangle (m_rcgamemap[i][0]); *Dcmem.rectangle (M_rcgamemap[i][map_size_cy-1]); $     }Panax Notoginseng      for(i =1; I < map_size_cy-1; ++i) -     { theDcmem.rectangle (m_rcgamemap[0][i]); +Dcmem.rectangle (M_RCGAMEMAP[MAP_SIZE_CX-1][i]); A     } the  +Pdc->bitblt (0,0, Rect. Width (), Rect. Height (), &dcmem,0,0, srccopy); -  $ Dcmem.deletedc (); $ bmp. DeleteObject (); -     return TRUE; -}

Comparing the two codes above, the difference is that the former (OnPaint () function) directly paints the client area object (DC), while the latter (OnEraseBkgnd () function) first opens up a buffer (DCMEM) based on the current client area size in memory. Use Dcmem This object to replace the DC for the same drawing operation (there are similar member functions), in-memory drawing is completed, and then through the following statements in-memory drawing graphics directly to the window client area, because it is a direct step to complete so as to avoid the original erase and redraw process, also solved the flicker problem.

1 pdc->bitblt (0000, srccopy);

Summarize:

When the window client area needs to draw complex graphics, if the memory conditions allow the best to take a double-buffered drawing method, on the one hand can solve the problem of flashing window drawing, on the other hand, because the reduction of the window repeated erasure process, but also to a certain extent, reduce the response time, is a space for time to exchange practices.

Reference:

①:http://blog.csdn.net/aaahuanian/article/details/7844522

MFC double-buffered drawing (2015.09.24)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.