Solved

c++ windows double buffering

Posted on 2003-11-25
9
1,285 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
I have drawing code all over the place in my application.  Is that a bad thing?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 48

Accepted Solution

by:
AlexFM earned 125 total points
Comment Utility
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
Comment Utility
>> 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
Comment Utility
why is it necessary for it to be placed in the message handler?  
0
 
LVL 48

Expert Comment

by:AlexFM
Comment Utility
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
Comment Utility
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

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
This article will show, step by step, how to integrate R code into a R Sweave document
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
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…

762 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

6 Experts available now in Live!

Get 1:1 Help Now