Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

c++ windows double buffering

Posted on 2003-11-25
9
Medium Priority
?
1,390 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 

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 500 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

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

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.
Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
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 …
Starting up a Project

772 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