Click here to Skip to main content
Licence 
First Posted 22 May 2002
Views 120,957
Bookmarked 52 times

GDI+ Double-Buffering Helper Class

By | 22 May 2002 | Article
A templated helper class that performs GDI+ initialization/deinitialization, and takes care of double-buffering/caching

Introduction

(or why did I write this?)

I just got tired of having to do all the silly GDI+ initialization/deinitialization and double-buffering stuff, every time I wanted to use it. Pain in the behindment. So this class basically takes all that work away. All you do is implement a Draw function that takes a Graphics object, and the class does all the other GDI+ related stuff.

Usage

Ok. To use this puppy, all you've got to do is this:

  1. Derive your class from CGdiPlusHelper, and (unless you've got some weird special needs), leave the tUseDoubleBuffering template argument alone. Double buffering REALLY speeds up the drawing speed, and helps eliminate flicker.
  2. Do NOT implement the WM_PAINT message. Instead, implement a function with the following prototype:
    void Draw(Graphics* g, int nWidth, int nHeight);

    This will be your main drawing function. You can use the passed in Graphics object to do all your drawing.

  3. CHAIN_MSG_MAP the CGdiPlusHelper class, preferably as far in front of your MSG_MAP as possible. Oh, if you want to force a redraw on the window, call SetDirty and only then Invalidate. Otherwise, in double-buffered mode, it'll just reuse the same cached bitmap as before.

Note that the header file will automatically link in GdiPlus.lib, include GdiPlus.h, and

using namespace GdiPlus;

it. i.e., You're all set to go to use GDI+ by just including this file.

Requirements

You need to install WTL7 and Microsoft Platform SDK to get WTL (although I THINK you only need it for the demo.) and GDI+.

Version History:

  • 5/23/2002: Original article submission

Credits

Thanks to Alex Farber and his great article, which really contains all the CachedBitmap etc. stuff I used.

I also loosely based the drawing algorithm in the demo on Mazdak's article.

Speaking of Copyright

(you knew it was coming...)

The code is completely, utterly, and absolutely free. Feel free to use it in private or commercial applications, modify it, sit on it, or print it out and use it for toilet paper. God knows I've ignored enough copyrights from CodeProject to have the nerve to make my own. :) One thing though -- if this code messes up your computer or puts your project seven months behind schedule, it's not my fault. None of it is my fault. Not even that "format c:" somewhere in there. Er, just kidding. :) Oh yeah, needless to say, you can't claim this code as your own. (i.e., I'd hate for someone to reprint this code, and copyright the hell out of it. Not sure if that's possible anyhow, but it would suck. Greatly.)

P.S. Probably a pointless thing to say, but if you're going to rate the article badly, at least take the time to write a comment saying how I could improve it, or what you find inadequate about it...

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Eugene Polonsky

Web Developer

United States United States

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionDeleting all bitmaps on 'SetDirty' ? PinmemberLex197213:49 8 Dec '06  
GeneralTo avoid flicker try this that will work fine Pinmembervmonster3:12 27 Jan '05  
Laugh | :laugh:
CQTTDemoView:
- Override OnEraseBackground to return TRUE.
 
- Override OnDraw:
where:
 
to:
QBufferDC bufferDC ( pDC );
Graphics g ( bufferDC.GetSafeHdc () );
 

QBufferDC:
- On the constructor class QBufferDC:
where:
// Get the clipping boundary of the mother DC, in logical coordinates
CRect rcClip;
VERIFY ( pDC->GetClipBox ( rcClip ) != ERROR );
 
// Transform to device coordinates (pixels), and normalize
pDC->LPtoDP ( rcClip);
rcClip.NormalizeRect ();
 
if ( m_bufferBitmap.ReserveBitmap ( pDC, rcClip.Size () ) )
{
...
...
 
#ifdef QBUFFER_DEMO
// In demo mode, change the color slightly so we can see which parts are updated
if ( m_bDemoMode )
col ^= RGB ( rand () % 32, rand () % 32, rand () % 32 );
#endif
 
// Get the mother DC's clipping boundary in logical coordinates and fill it.
VERIFY ( pDC->GetClipBox ( rcClip ) != ERROR );
 
// Transform to device coordinates (pixels), and normalize
pDC->LPtoDP ( rcClip );
 
if ( mapmode != MM_TEXT )
{
// Other mapping modes may lead to roundof errors, causing artefacts
// on the screen. To compensate, we inflate the bounding rectangle with two pixels.
CSize szPixels ( 2, 2 );
DPtoLP ( &szPixels );
rcClip.InflateRect ( szPixels.cx, szPixels.cy );
}
 
// DAKOT removed:
//FillSolidRect ( rcClip, col );
 
// Initialize accumulation of boundary information
SetBoundsRect ( NULL, DCB_ENABLE | DCB_ACCUMULATE | DCB_RESET );
 
// DAKOT added here:
FillSolidRect ( rcClip, col );
}
 
to:
// Get the clipping boundary of the mother DC, in logical coordinates
CRect rcClip, rcBitmap;
VERIFY ( pDC->GetClipBox ( rcClip ) != ERROR );
 
// Transform to device coordinates (pixels), and normalize
rcBitmap.CopyRect ( &rcClip );
pDC->LPtoDP ( rcBitmap );
rcBitmap.NormalizeRect ();
 
if ( m_bufferBitmap.ReserveBitmap ( pDC, rcBitmap.Size () ) )
{
...
...
 
#ifdef QBUFFER_DEMO
// In demo mode, change the color slightly so we can see which parts are updated
if ( m_bDemoMode )
col ^= RGB ( rand () % 32, rand () % 32, rand () % 32 );
#endif
 
/************ COMMENTED by VMONSTER
// Get the mother DC's clipping boundary in logical coordinates and fill it.
VERIFY ( pDC->GetClipBox ( rcClip ) != ERROR );
 
// Transform to device coordinates (pixels), and normalize
pDC->LPtoDP ( rcClip );
 
if ( mapmode != MM_TEXT )
{
// Other mapping modes may lead to roundof errors, causing artefacts
// on the screen. To compensate, we inflate the bounding rectangle with two pixels.
CSize szPixels ( 2, 2 );
DPtoLP ( &szPixels );
rcClip.InflateRect ( szPixels.cx, szPixels.cy );
}
************/
 
// DAKOT removed:
//FillSolidRect ( rcClip, col );
 
// Initialize accumulation of boundary information
SetBoundsRect ( NULL, DCB_ENABLE | DCB_ACCUMULATE | DCB_RESET );
 
// DAKOT added here:
FillSolidRect ( rcClip, col );
}
Laugh | :laugh:
GeneralRe: To avoid flicker try this that will work fine Pinmembervmonster4:47 27 Jan '05  
GeneralCPU usage Pinmembersmesser16:17 24 May '04  
GeneralRe: CPU usage PinmemberNick Z.9:36 14 Mar '05  
GeneralRe: CPU usage Pinmembersmesser9:39 14 Mar '05  
GeneralRe: CPU usage PinmemberNick Z.10:31 14 Mar '05  
GeneralMFC 6.0 support Pinmemberkc.5:10 5 Aug '03  
GeneralRe: MFC 6.0 support Pinmembercadinfo5:10 2 Sep '03  
GeneralRe: MFC 6.0 support PinsussCraig Muller12:25 17 Oct '03  
AnswerRe: MFC 6.0 support Pinmembersevenfish15:01 26 Jun '07  
GeneralI still get flicker when I resize window. Pinmemberrobspychala13:31 11 Jan '03  
GeneralRe: I still get flicker when I resize window. Pinmemberrobspychala17:29 13 Jan '03  
GeneralRe: I still get flicker when I resize window. Pinmembermartybeavis12:05 5 Nov '03  
Generalnice really, but... PinsussAnonymous7:52 30 Oct '02  
GeneralRe: nice really, but... PinmemberEugene Polonsky7:59 30 Oct '02  
GeneralNice article PinadminChris Maunder17:02 23 May '02  
GeneralRe: Nice article PinmemberPaul Selormey0:07 24 May '02  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120528.1 | Last Updated 23 May 2002
Article Copyright 2002 by Eugene Polonsky
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid