Solved

c++ windows double buffering

Posted on 2003-11-25
9
1,303 Views
Last Modified: 2012-06-22
I have a project....  It does lots of drawing with GDI functions, and sometimes looks kinda of flickery...

So I am hoping for a way to add double buffering to my program with a very small amount of code.  Ya know.. to get rid of the evil flickers..  An example would be great.
0
Comment
Question by:saloknairb
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
9 Comments
 
LVL 48

Expert Comment

by:AlexFM
ID: 9822737
Conversion of drawing code in MFC SDI project.

Step 1. Drawing without double buffering.

void CSampleView::OnDraw(CDC* pDC)
{
    CSampleDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    pDC->Rectangle(10, 10, 200, 200);   // any drawing code
}

2. Step 2. Create Draw finction which draws to device context.

void CSampleView::OnDraw(CDC* pDC)
{
    CSampleDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    Draw(pDC);
}

void CSampleView::Draw(CDC *pDC)
{
    pDC->Rectangle(10, 10, 200, 200);
}

Step 3. Overwrite OnEraseBkgnd anc convert OnDraw by the following way:

void CSampleView::OnDraw(CDC* pDC)
{
    CSampleDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc);

    CDC memDC;
    CBitmap bmp;
    CRect rect;

    GetClientRect(&rect);
    memDC.CreateCompatibleDC(pDC);
    bmp.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height());
    memDC.SelectObject(&bmp);

    memDC.FillSolidRect(&rect, RGB(255, 255, 255));  // background

    // draw to memory DC
    Draw(&memDC);

    // draw from memory DC to the screen
    pDC->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
}

void CSampleView::Draw(CDC *pDC)
{
    pDC->Rectangle(10, 10, 200, 200);   // any drawing code
}

BOOL CSampleView::OnEraseBkgnd(CDC* pDC)
{
    return TRUE;      
}

Now you have flicker-free drawing code. If you don't use MFC, you can do the same using API.
0
 

Author Comment

by:saloknairb
ID: 9826581
Yeah, I dont use MFC...   So, could you tell me how exactly I can do this using API?  I understand what the code is doing.  Just dont know where to implement it.    
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9826693
This is code fragment from Windows Hello World application generated by Application Wizard:

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
// TODO: Add any drawing code here...

DrawText(hdc, szHello, strlen(szHello), &rt, DT_CENTER);

EndPaint(hWnd, &ps);
break;

Let's convert it to using memory DC:
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:saloknairb
ID: 9826703
I have drawing code all over the place in my application.  Is that a bad thing?
0
 
LVL 48

Accepted Solution

by:
AlexFM earned 125 total points
ID: 9826798
Oops, I pressed Submit. Anyway, I continue:

case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    // TODO: Add any drawing code here...
    RECT rt;
    GetClientRect(hWnd, &rt);
    Draw(hdc, rt);
    EndPaint(hWnd, &ps);
    break;

...

void Draw(HDC hdc, RECT rect)
{
    // create memory DC and bitmap
    HDC hmemDC = CreateCompatibleDC(hdc);
    HBITMAP bmp = CreateCompatibleBitmap(hdc, rect.right, rect.bottom);
    SelectObject(hmemDC, bmp);

    // *************************************
    // draw to memory DC - set your drawing code here

    // background
    HBRUSH brush = CreateSolidBrush(RGB(255, 255, 255));
    FillRect(hmemDC, &rect, brush);

    // text
    TCHAR szHello[MAX_LOADSTRING];
    LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
    DrawText(hmemDC, szHello, strlen(szHello), &rect, DT_CENTER);
    // *************************************

    // draw from memory DC to window DC
    BitBlt(hdc, 0, 0, rect.right, rect.bottom, hmemDC, 0, 0, SRCCOPY);

    // cleanup
    DeleteObject(brush);
    DeleteObject(bmp);
    DeleteObject(hmemDC);
}


In MyRegisterClass function replace line:

wcex.hbrBackground      = (HBRUSH)(COLOR_WINDOW+1);

with:
wcex.hbrBackground = NULL;    // don't redraw background
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9826810
>> I have drawing code all over the place in my application.  Is that a bad thing?

All drawing code should be placed in WM_PAINT message handler or called from it.
0
 

Author Comment

by:saloknairb
ID: 9829741
why is it necessary for it to be placed in the message handler?  
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9830055
When window is shown, restored, or user moves another window above this window, it should be redrawn. In this case Windows sends WM_PAINT message to the window asking it to redraw itself. This ia a reason all drawing code should be placed to WM_PAINT message handler.
The only exception is application which shows animation or movie updating the screen with high frequency.
0
 

Author Comment

by:saloknairb
ID: 9834852
Thank you so much!!  See....  I never knew that.  I had drawing code all over the damn place.     No wonder I was having trouble with windows clipping against mine and stuff.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
detecting  the added row index in a datagridview 3 94
Advice in Xamarin 21 121
Visual Studio hangs on running project 6 84
Cannot locate cell 15 43
In this post we will learn how to connect and configure Android Device (Smartphone etc.) with Android Studio. After that we will run a simple Hello World Program.
Although it can be difficult to imagine, someday your child will have a career of his or her own. He or she will likely start a family, buy a home and start having their own children. So, while being a kid is still extremely important, it’s also …
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

739 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question