Flicker free drawing of any control

There are two articles dealing with this subject on this site, but i guess sometimes it's needed to free one single control from flickering, and it's not needed to use a complete new window-class. I will show you a really small solution of the flickering-problem, which uses the CMemDC-class from the article by Keith Rule. To make a control flicker free you have to go three steps, as described now.

1. Override the OnEraseBkgnd()-routine of the control

Flickering apears, because the complete control is erased and it needs some time to fill the control-area with some text/graphics or whatever. There is a really short moment, when nothing can bee seen, because the background was erased but nothing is written yet. That's why we don't erase the background of the control anymore. to do this, we have to override the OnEraseBkgnd()-routine of the control like this:

   BOOL CRecordList::OnEraseBkgnd(CDC* pDC) 
   {
      return FALSE;
   }

2. Override the OnPaint()-routine of the control

The second thing to do, is to override the OnPaint()-routine. The trick is, to paint the complete control into a memory device-context and copy it in the original DC via BitBlt(). The CMemDC-class does this work for you. Because we don't erase the background anymore (see above), we need to erase the memory-device-context with the background-color of the control. A typical OnPaint() should look like this:

   void CRecordList::OnPaint()
   {
      CPaintDC dc(this);
      CMemDC memDC(&dc);

      CRect clip;
      memDC.GetClipBox(&clip);
      memDC.FillSolidRect(clip, GetSysColor(COLOR_WINDOW));

      DefWindowProc(WM_PAINT, (WPARAM)memDC->m_hDC, (LPARAM)0);
   }

3. Override the EraseBkgnd()-routine of the control's parent

Imagine the following situation. You have a dialog with the flicker free control in it. And now the user resizes the window. What happens? First of all, the background of the dialog is erased and after that all controls of the window are redrawn. But when the background is erased and THAN the controls are redrawn, we still have flickering! That why we have to exclude the controls area out of the clipping-box of the control's parent. And here's how we do it:

   BOOL CListBar::OnEraseBkgnd(CDC *pDC)
   {
      CRect clip;
      m_Control->GetWindowRect(&clip);		// get rect of the control

      ScreenToClient(&clip);
      pDC->ExcludeClipRect(&clip);

      pDC->GetClipBox(&clip);
      pDC->FillSolidRect(clip, GetSysColor(COLOR_BTNFACE));

      return FALSE;
   }

That's it. You can make near every control flicker free in this way, but for some of the controls, you have to change the routines above slightly. Like for the ListCtrl in Report-mode, because the columne-header-area have to be excluded of the clip-box, like this:

   void CRecordList::OnPaint()
   {
      CPaintDC dc(this);

      CRect headerRect;
      GetDlgItem(0)->GetWindowRect(&headerRect);
      ScreenToClient(&headerRect);
      dc.ExcludeClipRect(&headerRect);

      CMemDC memDC(&dc);
      .
      .
      .
   }



Comments

  • How to make using Win32 SDK

    Posted by Legacy on 01/09/2004 12:00am

    Originally posted by: Dinesh Goyal

    How to make a dialog's control flicker free using Win32 SDK, rather than using MFC.

    Reply
  • How ,we can have MSCHART FLICKER FREE

    Posted by Legacy on 09/11/2003 12:00am

    Originally posted by: Arbind Yadav

    HI ALL

    I have MS CHART.On refreshing of chart ,flickering occurs.
    How,we can prevent it from flickering

    Reply
  • To prevent the header control from flickering.

    Posted by Legacy on 04/29/2003 12:00am

    Originally posted by: Cho Byong Sok


    Thanks.

    This is great !!!.

    My List view doesn't flicker any more.

    To add one thing, I think it is better to use

    the WS_CLIPCHILDREN style than ExcludeClipRect

    to prevent the header control from flickering

    for the ListCtrl in REPORT mode.

    Reply
  • small change

    Posted by Legacy on 08/07/2001 12:00am

    Originally posted by: IntellArt

    I had the same problem with the scrollbar's dissaperence on 
    
    a CListCtrl and a CWnd, my solution was to exclude the
    controls rect from the cliping region not only on
    OnEraseBkgnd but also on OnPaint, the code looks like this:

    void CMyDialog::OnPaint()
    {
    CPaintDC dc(this);

    CRect rectList;
    m_myList.GetWindowRect(&rectList);

    ScreenToClient(&rectList);
    dc.ExcludeClipRect(&rectList);

    CMemDC memDC( &dc);
    ......

    }

    This should also solve the other problem with the
    CListCtrl drawing two times, because excluding its rect the
    list will not receive the drawing message for the second time.

    It worked for me , anyway thanks for the code to Thomas Jansen.

    Reply
  • Another approach.

    Posted by Legacy on 11/02/1999 12:00am

    Originally posted by: Philip McGahan

    Get a pointer to the control.
    Disable the control.
    Draw the control.
    Enable the control.
    Invalidate the control.


    CWnd* pControl = GetDlgItem(IDC_MY_CONTROL);

    pControl->SetRedraw(FALSE;

    paint the control

    pControl->SetRedraw();
    pControl->Invalidate();

    Reply
  • The OnPaint() erases scrollbar's in a list box

    Posted by Legacy on 08/11/1999 12:00am

    Originally posted by: Veregon

    Anyway to fix this?

    Reply
  • Are you trying to print more than one LC at once

    Posted by Legacy on 05/18/1999 12:00am

    Originally posted by: Gregory Goeppel

    In response to....
    lc still points to the original listctrl. How to fix that?

    This print code only supports printing one list control
    at a time or one list control on a page. Are you trying to
    print more than one list control on the same page?
    Also how many columns are you trying to print?
    I haven't run across this problem in my tests. My program
    requires up to 14 columns.

    Reply
  • good but...

    Posted by Legacy on 02/08/1999 12:00am

    Originally posted by: YanRong

    This idea is very good. and I do follow the steps describe above.
    My control is derived from CListCtrl,and I add many items in the
    control,the problem to me is when i scroll the bar, it seems control
    redraws two times,and when you don't do this,it' right.I use the
    textcallback method to display string in the control.Can anyone
    here help me? thanks a lot!

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

  • Live Event Date: December 18, 2014 @ 2:00 p.m. ET / 11:00 a.m. PT The Internet of Things (IoT) incorporates physical devices into business processes using predictive analytics. While it relies heavily on existing Internet technologies, it differs by including physical devices, specialized protocols, physical analytics, and a unique partner network. To capture the real business value of IoT, the industry must move beyond customized projects to general patterns and platforms. Check out this upcoming webcast …

Most Popular Programming Stories

More for Developers

RSS Feeds