Double buffering drawing technology under Win32

Source: Internet
Author: User

One: Double buffering principle

In order to solve the flicker problem caused by the window refresh frequency too fast, the double buffering technique is used to draw. The so-called double buffering technique is to load the resources into memory and then copy the memory data to the device DC (this is faster), avoiding drawing directly on the device DC (this is slower). A simple analogy: there is a painter in the street to do an instant art exhibition, on the same canvas according to the requirements of the audience to draw different images, whenever an audience to draw up what to see, the painter first on the canvas before all the things wiped clean, and then re-painting. Obviously there are some classic portraits that we all want to see, according to the old way, the painter will have to re-draw this image every time, but this kind of painting, painting the manner of wiping is very lengthy. So the painter thought of a way to put these classic portraits in advance with a piece or a few canvases to draw down, when someone needs to see, put these prepared canvas in front of the existing canvas, so as to meet the audience's real-time requirements. Then these pre-prepared canvas is equivalent to the memory DC, the resources in the memory DC, waiting to refresh the display, the memory DC on the things "paste" to the current window DC, you can reduce the delay caused by the flicker problem, this is the principle of double buffering.

See the following blog post for details. Here are two examples:

Two: examples

Example one: Loading bitmaps

Code:

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM WPARAM, LPARAM LPARAM) {intWmid, wmevent;    Paintstruct PS;     HDC hdc; Switch(message) { CaseWm_command:wmid=LoWord (WParam); Wmevent=HiWord (WParam); //Parse the menu selections:        Switch(wmid) { CaseIdm_about:dialogbox (HInst, Makeintresource (Idd_aboutbox), hWnd, about);  Break;  CaseIdm_exit:destroywindow (HWND);  Break; default:            returnDefWindowProc (hWnd, message, WParam, LParam); }         Break;  CaseWM_PAINT:HDC= BeginPaint (HWnd, &PS); //Todo:add Any drawing code here ...Mydraw (HDC); EndPaint (HWnd,&PS);  Break;  CaseWm_destroy:postquitmessage (0);  Break; default:        returnDefWindowProc (hWnd, message, WParam, LParam); }    return 0;}

The implementation of the Mydraw function:

Const intG_picheight =1024x768;Const intG_picwidth =675;voidMydraw (HDC &DC)    {rect rect;    Hbitmap Horgbitmap;    Hbitmap Holdbitmap; intDisheight, Diswidth; GetClientRect (G_hwnd,&rect);//Get client area sizeDisheight = rect.bottom-Rect.top; Diswidth= rect.right-Rect.left; //Loading PicturesHorgbitmap = (HBITMAP):: LoadImage (HInst, _t ("test2.bmp"), Image_bitmap, G_picwidth, G_picheight, lr_loadfromfile); HDC MDc=:: CreateCompatibleDC (DC);//Create a compatible DC (memory DC) for the current contextHoldbitmap = (HBITMAP):: SelectObject (MDc, Horgbitmap);//to load a bitmap into a memory DC//Copy Memory DC data block to current DC, auto stretch:: StretchBlt (DC,0,0, Diswidth, Disheight, MDc,0,0, G_picwidth, G_picheight, srccopy); //recovering memory raw data:: SelectObject (MDc, Holdbitmap); //Remove resources to prevent leaks::D eleteobject (HORGBITMAP); ::D Eletedc (mDc);}

Results:

Resize the window to find flicker-free behavior.

Example two: Draw various lines and curves. This is a slightly more complicated example, I usually do a demo. You can familiarize yourself with some of the operations of the Windows drawing.

Code:

voidCrtview_win32dlgdlg::onpaint () {if(Isiconic ()) {/******** This segment of code ignores *********/    }    Else{cdialog::onpaint ();//Call the default control drawing for the base classCRect Ctrlrect; CStatic*pdegreepicctrl = (CStatic *) GetDlgItem (idc_stc_degreepic); Pdegreepicctrl->getclientrect (&ctrlrect);//get static control dimensionsCDC*PDC = PDEGREEPICCTRL->GETWINDOWDC ();//Get control DCCDC dcmemory; DCMEMORY.CREATECOMPATIBLEDC (PDC);//Creating a Memory DCCBitmap*poldmapmemory;        CBitmap mapmemory; Mapmemory.createcompatiblebitmap (PDC, Ctrlrect.width (), Ctrlrect.height ());//creates a compatible bitmap for the control DC. is actually the same area as the control DC sizePoldmapmemory = Dcmemory.selectobject (&mapmemory);//load compatible bitmaps, you can draw on the memory DC only after you have a "tablecloth" sizeDRAWDEGREEPICBKGRD (&dcmemory);//drawing on the memory DCPdc->bitblt (0,0, Ctrlrect.width (), Ctrlrect.height (), &dcmemory,0,0, srccopy);//Copy the contents of the memory DC onto the control DCDcmemory.selectobject (poldmapmemory);//restore the original memory DC::D eleteobject (mapmemory);//Delete a compatible bitmap resource::D Eletedc (dcmemory);//Remove Memory DCReleaseDC (PDC);//releasing the control DC    }}

voidCrtview_win32dlgdlg::D rawdegreepicbkgrd (CDC *PDC)    {CRect stcrect, picrect; CStatic*pdegreepicctrl = (CStatic *) GetDlgItem (idc_stc_degreepic); Pdegreepicctrl->getclientrect (&stcrect); if(Stcrect.width () >stcrect.height ()) {        intdiff = (stcrect.width ()-stcrect.height ())/2; Picrect.left= Stcrect.left +diff; Picrect.right= Stcrect.right-diff; Picrect.top=Stcrect.top; Picrect.bottom=Stcrect.bottom; } Else {        intdiff = (stcrect.height ()-stcrect.width ())/2; Picrect.left=Stcrect.left; Picrect.right=Stcrect.right; Picrect.top= Stcrect.top +diff; Picrect.bottom= Stcrect.bottom-diff; } CBrush*Poldbrush; /************** Draw Round ***************/CBrush NewBrush1; Newbrush1.createsolidbrush (RGB (0,255,0)); Poldbrush= Pdc->selectobject (&newBrush1); PDC->ellipse (&picrect); /************** Painting Origin point ***************/CRect Orgrect (stcrect.width ()/2-2, Stcrect.height ()/2-2, Stcrect.width ()/2+2, Stcrect.height ()/2+2);    CBrush NewBrush2; Newbrush2.createsolidbrush (RGB (255,0,0)); Poldbrush= Pdc->selectobject (&NEWBRUSH2); PDC->ellipse (&orgrect); PDC-SelectObject (Poldbrush); /************* Picture Scale ***************/CPoint Center (stcrect.width ()/2, Stcrect.height ()/2); DoubleRadias = (Double) Picrect.width ()/2; CPen Newpen (Ps_solid,1, RGB (255,0,0)); CPen*poldpen = Pdc->selectobject (&Newpen);     CPoint StartPoint, EndPoint;  for(intI=0; i< the; i=i+5) {        DoubleCosval =cos (Degreetoradian (i)); DoubleSinval =sin (Degreetoradian (i)); Startpoint.x= Center.x +int(Radias * cosval);//The x-coordinate of the point on the circle corresponding to the current angleStartpoint.y = Center.y-int(Radias * sinval);//The y-coordinate of the point on the circle corresponding to the current angle         if(i%Ten==0) {Endpoint.x= Startpoint.x-int(Ten*cosval); Endpoint.y= Startpoint.y +int(Ten*sinval); } Else{endpoint.x= Startpoint.x-int(5*cosval); Endpoint.y= Startpoint.y +int(5*sinval); } PDC-MoveTo (StartPoint); PDC-LineTo (EndPoint); } PDC-SelectObject (Poldpen);}

Effect:

Three: summary

In these two examples, each redraw is re-applied to the memory DC and then copied to the window DC. Although this is tedious, it does not affect the effect, and does not cause flicker if the background is not erased (such as calling Invalidate (FALSE)) in response to a OnPaint message. But the best way, is the beginning of the article, only draw once, the memory of the DC handle to save, each time in the OnPaint inside the redraw, call BitBlt copy directly. However, be aware of the destruction of these handle objects to avoid memory leaks.

The following articles can also be seen:

1 http://baike.baidu.com/view/1149326.htm

2 http://blog.csdn.net/xsc2001/article/details/5378601

3 http://www.cppblog.com/wrhwww/archive/2011/03/01/140913.html

4 http://www.cnblogs.com/afarmer/archive/2012/03/31/2427315.html

5 http://www.programlife.net/mfc-draw-pictures-with-memory-dc-buffer.html

6 http://blog.csdn.net/zxzerster/article/details/5659775

7 http://blog.csdn.net/yiruirui0507/article/details/6153607

8 http://blog.csdn.net/zicheng_lin/article/details/7179278

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.