Solved

c++ windows double buffering

Posted on 2003-11-25
9
1,286 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
  • 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
 

Author Comment

by:saloknairb
ID: 9826703
I have drawing code all over the place in my application.  Is that a bad thing?
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
How to split this in C++ 4 94
array220 challenge 8 56
base64 decode encode 12 122
index Out OF Range Exception error 4 54
This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
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 …
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

895 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

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now