Flicker free drawing (2) | CodeGuru

Flicker free drawing (2)

This class was contributed by Andreas Leitner. This is a small class that makes it easy to create windows that are updated flicker-free. Once I had to code a window that displayed “hard to calculate” data. Since I needed to update the contents in constant time (say every second) I got this ugly flickering on […]

Written By
CodeGuru Staff
CodeGuru Staff
Mar 23, 1999
4 minute read
CodeGuru content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More

This class was contributed by Andreas Leitner.

This is a small class that makes it easy to create windows that are
updated flicker-free. Once I had to code a window that displayed “hard
to calculate” data. Since I needed to update the contents in constant time
(say every second) I got this ugly flickering on my machine.

There is an article dealing with the same problem on this site (Flicker
free drawing using memory DC by  Keith Rule
). The main difference
between our approaches is that Keith extends the class CDC and I extended
CWnd. I think both versions have got advantages and disadvantages. I
will try to point out the difference at the end of this article.

What I needed was a window that displayed its contents without flickering.
I archieve the flicker free mode with a well known trick: First paint everything
on a bitmap, then copy the bitmap into the the window. Since this aproach
is a bit slower than the common way, I decided that the end-user may decide
wether to use the fast mode (in case that his machine is good enough that
even this mode doesn’t flicker), or the flicker-free mode.

The new class is called CadvWnd (based
on CWnd):

The first 2 attributes that came on my mind were:

void SetFlickerFree(BOOL bFlickerFree);
BOOL IsFlickerFree();

I think it is rather easy to guess what those functions should do. What
I needed further was a sort of OnPaint function.
But since I will need this function-name for internal use I took an other
function (in fact two again to definitly force a difference between foreground
and background).

 virtual void InternalRedrawFG(CDC* pDC, CRect rcPaint);
 virtual void InternalRedrawBG(CDC* pDC, CRect rcPaint);

InternalRedrawFG should be overridded for
foreground drawing and InternalRedrawBG for
the background. Once the bitmap is painted it will be copied into the window
every time it needs to be updated. Of course the window checks messages
like WM_SIZE and recreates and repaints the bitmap. But how does the client
tell the window that the contents has changes and the bitmap needs to be
repainted or even recreated?

void ReCreateBitmap();
void SetContentsChanged(BOOL yes = TRUE);
BOOL IsContentsChanged();

ReCreateBitmap is the direct way to recreate
the bitmap (Mabe you as a client of the class will never need to call this
one:). More often you will have to call SetContentsChanged(TRUE).
When you do this, the next time the window will be repainted, the bitmap
also will be. Just call this function if the data changes on which the
window contents is based.

This class has even got a few extra features. I thought it is often
the case that you need a special background color so I made also this available
easy (of course you can add a mode for a background picture too). By now
there are two background modes: BM_DEF_WND_COL
and BM_CUST_COL. If you select SetBackgroundMode(
0, BM_DEF_WND_COL )
the window will behave like default, but if
you call SetBackgroundMode( RGB(255,0,0), BM_CUST_COL
)
the background will be painted red. Here come the function declarations:

const int GetBackgroundMode();
void SetBackgroundMode(COLORREF Color, int Mode = BM_CUST_COL); // To set the std mode just set col black and change the mode value 
COLORREF GetBackgroundColor();


 

 There is also a nice new function that you should override in
your derived class if you have child windows in your window.

virtual BOOL CreateChildren();

This function will be called in the right moment regardless if you create
this window through subclassing (often used in dialogs) or through a “create”
call (often used if you make it a child of another CWnd
(derived) class).

 


What do you need to derive a class from CadvWnd?


Be sure to include the header of

CadvWnd

in


your new class and derive it as public from it. A minimal implementation


just needs to override

InternalRedrawFG

as


shown in the following example.

#include "advWnd.h"
class CMyWnd : public CadcWnd
{
    public:
    virtual void InternalRedrawFG(CDC* pDC, CRect rcPaint)
    {
        pDC->TextOut( 10, 10, "Nonsense rulez ?!?");
    }
};


But what is the difference between CadvWnd and
CMemDC (by Keith Rule)?


As I mentioned at the begining Keith Rule deals also with the

flickering


topic in his artice called

“Flicker free drawing using memory DC“.

The main advantage of

CMemDC

in my


opinion is that you can use it everytime it comes to painting. CadvWnd


will cause you some problems using a

CView

derived


class, because here you have to override

OnDraw to

change the drawing behavior of your window. I think one would have


to derive

CView

from

CadvWnd

to solve this, but (to be honest) I never tried. Therefore the advantage


of

CadvWnd

is that you just override

InternalRedrawFG

and then can easiely switch between fast and flickering mode. (Which


is sure a nice option in the main settings dialog). You can use

InternalRedrawFG

just like OnPaint without any difference. Also in some cases

CadvWnd

is faster than the pure

CMemDC

implementation,


because

CadvWnd

only recreates the offscreen


bitmap when you force it too (via

SetContentsChanged

,


or

ReCreateBitmap

). This is an important issue


if you need a long time to caclulate the image. Plus

CadvWnd

offers a few other things that make life easier like the unified creation


method with

CreateChildren

and the additional


virtual function for background painting (inclusiv the extra background


mode with a predefined color).

Finaly here is the source. I used this class
a few times and saw no remaining bugs by now, if you see some (: please
mail me. Have fun!

CodeGuru Logo

CodeGuru covers topics related to Microsoft-related software development, mobile development, database management, and web application programming. In addition to tutorials and how-tos that teach programmers how to code in Microsoft-related languages and frameworks like C# and .Net, we also publish articles on software development tools, the latest in developer news, and advice for project managers. Cloud services such as Microsoft Azure and database options including SQL Server and MSSQL are also frequently covered.

Property of TechnologyAdvice. © 2026 TechnologyAdvice. All Rights Reserved

Advertiser Disclosure: Some of the products that appear on this site are from companies from which TechnologyAdvice receives compensation. This compensation may impact how and where products appear on this site including, for example, the order in which they appear. TechnologyAdvice does not include all companies or all types of products available in the marketplace.