Further discussions on flicker free drawing






4.59/5 (14 votes)
May 24, 2003
2 min read

204351
An article on how to solve flicker problems
Introduction
This article aims to show some useful codes for solving flicker problems in CTreeCtrl
, CListCtrl
and GDI+. And it could be viewed as an extend of Keith Rule's great article "Flicker Free Drawing In MFC".
Background
The only background to this article is that you have read the great article of Keith Rule. Thanks him for his nice code. We will use the class CMemDC
proposed by him.
CTreeCtrl
For a CTreeCtrl
derived class, if we want to avoid flicker, we could carry out the following steps.
- Add the file memdc.h in your project.
- Add the line
#include "memdc.h"
to stdafx.h or the desired .h file. - Add a public
CRect
variable likeCRect m_rectClient;
- Add a windows message handler for
WM_ERASEBKGND
,WM_SIZE
, andWM_PAINT
.
Then we should add the code as following:
BOOL CTreeCtrl::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default UNUSED_ALWAYS(pDC); //return CTreeCtrl::OnEraseBkgnd(pDC); return TRUE; } void CTreeCtrl::OnSize(UINT nType, int cx, int cy) { CTreeCtrl::OnSize(nType, cx, cy); GetClientRect(m_rectClient); } void CTreeCtrl::OnPaint() { CPaintDC dc(this); // Paint to a memory device context to reduce screen flicker. CMemDC memDC(&dc, &m_rectClient); ...... // Let the window do its default painting... CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 ); }
Then you would get flicker free effect.
CListCtrl
For a CListCtrl
derived class, all of the procedures are the same expect the OnSize
function should be modified as following to allow the CHeadCtrl
(if in report model) to display:
void CListCtrl::OnSize(UINT nType, int cx, int cy) { CListCtrl::OnSize(nType, cx, cy); GetClientRect(m_rectClient); CHeaderCtrl* pHC; pHC = GetHeaderCtrl(); if (pHC != NULL) { CRect rectHeader; pHC->GetItemRect( 0, &rectHeader ); m_rectClient.top += rectHeader.bottom; } }
Then you could get flicker free effect.
GDI+
I have found several articles talking about flicker free drawing in GDI+. However, I want to extend Keith Rule's code to do the same job and avoid to re-implement the double buffer mechanism with CashedBitmap. Thus I use the following method.
- Add the file memdc.h in your project.
- Add the line
#include "memdc.h"
to stdafx.h or the desired .h file. - Add a public
CRect
variable likeCRect m_rectClient;
Add a windows message handler forWM_ERASEBKGND
,WM_SIZE
, andWM_PAINT
.
Then we should add the code as following:
BOOL CView::OnEraseBkgnd(CDC* pDC) { // TODO: Add your message handler code here and/or call default UNUSED_ALWAYS(pDC); //return CView::OnEraseBkgnd(pDC); return TRUE; } void CView::OnSize(UINT nType, int cx, int cy) { CView::OnSize(nType, cx, cy); GetClientRect(m_rectClient); } void CView::OnPaint() { CPaintDC dc(this); // Paint to a memory device context to reduce screen flicker. CMemDC memDC(&dc, &m_rectClient); Graphics graphics(memDC); ...... }
Then you could get flicker free effect. This method could also do well in CScrollView
. Ok, finally, there is still an interesting question left for you: which method will be faster, this method or the double buffer implemented by CashedBitmap?
History
- Initial release 2003-05-24.