Click here to Skip to main content
12,767,912 members (42,775 online)
Click here to Skip to main content
Add your own
alternative version


88 bookmarked
Posted 9 Feb 2005

Flicker free resizable custom control

, 31 Oct 2005
Rate this:
Please Sign up or sign in to vote.
This dynamically reziable control does not flicker. The article describes the problem and the technique used to solve the flickering.

Sample Image


I had read every article on flicker-free drawing, yet I could not make it work for my resizable custom control. There are a couple of known issues, but there is also a rarely mentioned subtlety involved. In this article, I will discuss all the issues involved and how to approach them.

The sample included in this article is an implementation of an elliptical button control. The drawing is done using GDI+. The round button changes outer color as the mouse cursor rolls over. The inner color changes as the mouse is clicked on the button. The control stretches and shrinks as the dialog box is dragged.


Many articles on the subject suggest to:

  1. use double buffering
  2. override OnEraseBkgnd and return TRUE.

Well, I implemented both and it still flickered. The problem most visibly occurred during resizing, when the whole dialog was repainted. The issue was that the dialog box would erase my custom control as it erased its own background. Therefore, every time I resized the dialog, I would get a flicker due to the dialog box painting grey over my control before the control repainted itself.

Using the code

The clipping solution: tell the dialog to erase everything but the region occupied by the round control. The easiest way to accomplish this is to set the Windows style to WS_CLIPCHILDREN. You can do this programmatically in "OnInitDialog" method (or you can set this dialog property in Visual Studio's design view):

BOOL CNoFlickerDlg::OnInitDialog()

    // Tell the dialog NOT to erase children controls
    ModifyStyle(0, WS_CLIPCHILDREN);

    return TRUE;
    // return TRUE  unless you set the focus to a control

Since my control has a custom (round) region, it must be re-computed each time the control changes shape or size. In order for this to work correctly, the best place to call the ReCalculateDimensions function is from the dialog's OnEraseBkgnd, like so:

BOOL CNoFlickerDlg::OnEraseBkgnd(CDC* pDC)

    return CDialog::OnEraseBkgnd(pDC);

The reason you have to make the call here is important. The dialog will exclude the control region from its surface (that is being erased) based on what the control region is set to be. Therefore, by calling it right before CDialog::OnEraseBkgnd, you ensure that the control region is up to date right before it is clipped.

Double Buffering: Since all drawing is done in GDI+, I used a CachedBitmap class to help me with double buffering. The code comes down to the following few lines:

void CButtonControl::OnPaint()
    // device context for painting
    CPaintDC dc(this);

    Graphics graphics(dc.m_hDC);

    // Only redraw the control if the buffer is dirty
    if (m_bDirtyBuffer)
        m_bDirtyBuffer = FALSE;

    graphics.DrawCachedBitmap(m_pCachedBitmap, 0, 0);

As you can tell from the code above, the actual drawing is only done when m_bDirtyBuffer flag is set to true. Every other time, the painting is done using a cached bitmap. You set the flag to true whenever the control is resized (i.e., in OnSize method).

Finally, make sure that the control itself has OnEraseBkgnd method overridden and returns TRUE. This will make your controls flicker free!

Points of Interest

Download the demo and drag it by the corner. See the button change shape without any flicker.


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

Web Developer
Canada Canada
No Biography provided

You may also be interested in...


Comments and Discussions

GeneralDoing the same thing slightly differently... Pin
Jun Du31-Oct-05 16:44
memberJun Du31-Oct-05 16:44 
beerboy_229-Feb-05 23:46
memberbeerboy_229-Feb-05 23:46 
JanKotowski10-Feb-05 15:40
memberJanKotowski10-Feb-05 15:40 
Gast12814-Jul-14 23:13
memberGast12814-Jul-14 23:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    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 | Terms of Use | Mobile
Web02 | 2.8.170217.1 | Last Updated 31 Oct 2005
Article Copyright 2005 by JanKotowski
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid