Skip to main content
Email Password   helpLost your password?

Sample Image
A simple animation example which is used to show CMemDC in several mode

Introduction

Removing flicker from an MFC application is well-covered territory. You can find the topic addressed in books, and on-line. However, the techniques presented are somewhat complicated and are usually difficult to add to an existing application. One often-presented technique is called double buffering. Double buffering allows the new screen to be drawn in off-screen memory, and then the completed screen is bit-blited back onto the physical screen.

This article presents a class called CMemDC that encapsulates most of the issues associated with writing to off-screen buffers. Adding CMemDC to an existing application or MFC Active X control is nearly trivial.

Modifying an MFC Application to use CMemDC

Compile your code after you've made these changes and you will notice that the flicker you had seen before is gone.

Modifying a MFC Active X Control to use CMemDC

To add CMemDC support you follow the instruction for adding the support to an application, however you make one small change in the OnDraw function.

void CParticleTestCtlCtrl::OnDraw(CDC* pdc, const CRect& rcBounds, 
                                  const CRect& rcInvalid)
{
    CMemDC pDC(pdc, &rcBounds);
    // TODO: add draw code for native data here

    // - use pDC as the device context to draw 

}

The only substantial difference is that the rcBounds is passed to the CMemDC constructor.

Source Code

#ifndef _MEMDC_H_
#define _MEMDC_H_
 
//////////////////////////////////////////////////

// CMemDC - memory DC

//

// Author: Keith Rule

// Email:  keithr@europa.com

// Copyright 1996-2002, Keith Rule

//

// You may freely use or modify this code provided this

// Copyright is included in all derived versions.

//

// History - 10/3/97 Fixed scrolling bug.

//               Added print support. - KR

//

//       11/3/99 Fixed most common complaint. Added

//            background color fill. - KR

//

//       11/3/99 Added support for mapping modes other than

//            MM_TEXT as suggested by Lee Sang Hun. - KR

//

//       02/11/02 Added support for CScrollView as supplied

//             by Gary Kirkham. - KR

//

// This class implements a memory Device Context which allows

// flicker free drawing.

 
class CMemDC : public CDC {
private:       
    CBitmap    m_bitmap;        // Offscreen bitmap

    CBitmap*       m_oldBitmap; // bitmap originally found in CMemDC

    CDC*       m_pDC;           // Saves CDC passed in constructor

    CRect      m_rect;          // Rectangle of drawing area.

    BOOL       m_bMemDC;        // TRUE if CDC really is a Memory DC.

public:
    
    CMemDC(CDC* pDC, const CRect* pRect = NULL) : CDC()
    {
        ASSERT(pDC != NULL); 
 
        // Some initialization

        m_pDC = pDC;
        m_oldBitmap = NULL;
        m_bMemDC = !pDC->IsPrinting();
 
        // Get the rectangle to draw

        if (pRect == NULL) {
             pDC->GetClipBox(&m_rect);
        } else {
             m_rect = *pRect;
        }
 
        if (m_bMemDC) {
             // Create a Memory DC

             CreateCompatibleDC(pDC);
             pDC->LPtoDP(&m_rect);
 
             m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), 
                                                  m_rect.Height());
             m_oldBitmap = SelectObject(&m_bitmap);
 
             SetMapMode(pDC->GetMapMode());
 
             SetWindowExt(pDC->GetWindowExt());
             SetViewportExt(pDC->GetViewportExt());
 
             pDC->DPtoLP(&m_rect);
             SetWindowOrg(m_rect.left, m_rect.top);
        } else {
             // Make a copy of the relevent parts of the current 

             // DC for printing

             m_bPrinting = pDC->m_bPrinting;
             m_hDC       = pDC->m_hDC;
             m_hAttribDC = pDC->m_hAttribDC;
        }
 
        // Fill background 

        FillSolidRect(m_rect, pDC->GetBkColor());
    }
    
    ~CMemDC()      
    {          
        if (m_bMemDC) {
             // Copy the offscreen bitmap onto the screen.

             m_pDC->BitBlt(m_rect.left, m_rect.top, 
                           m_rect.Width(),  m_rect.Height(),
                  this, m_rect.left, m_rect.top, SRCCOPY);            
             
             //Swap back the original bitmap.

             SelectObject(m_oldBitmap);        
        } else {
             // All we need to do is replace the DC with an illegal

             // value, this keeps us from accidentally deleting the 

             // handles associated with the CDC that was passed to 

             // the constructor.              

             m_hDC = m_hAttribDC = NULL;
        }       
    }
    
    // Allow usage as a pointer    

    CMemDC* operator->() 
    {
        return this;
    }       
 
    // Allow usage as a pointer    

    operator CMemDC*() 
    {
        return this;
    }
};
 
#endif
You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralSetProcessDefaultLayOut LAYOUT_RTL Pin
Farid Z
19:36 27 Oct '09  
NewsMFC Feature Pack for Visual C++ 2008 Pin
mykel
8:54 20 Oct '09  
GeneralRe: MFC Feature Pack for Visual C++ 2008 Pin
Keith Rule
11:01 20 Oct '09  
GeneralRe: MFC Feature Pack for Visual C++ 2008 Pin
mykel
1:22 21 Oct '09  
GeneralThanks Pin
xsm_126
22:48 12 Jun '09  
Answer... Pin
Member 4263302
21:06 22 Feb '09  
QuestionCDialog Based application with memdc.h and MSFlexgrid Control Pin
tmg51281
4:03 17 Feb '09  
GeneralThanks~!! Pin
Member 3775361
15:09 12 Feb '09  
GeneralVery good job !!! Pin
raymondnana
4:24 29 Jan '09  
Generalcool... Pin
auralius
19:11 21 Dec '08  
GeneralCMemDC & Dialog Menu Pin
Steven Pence
10:38 8 Dec '08  
GeneralHow to use in Controls? Pin
blamond
12:14 30 Apr '08  
GeneralRe: How to use in Controls? Pin
blamond
9:52 6 May '08  
Generalchild windows Pin
toddma
11:16 9 Nov '07  
GeneralThanks for some greate time / pain saving! Pin
SoftwareGeek
1:08 8 Nov '07  
GeneralNice work, but... Pin
SimpleProgrammer
6:51 15 Aug '07  
GeneralRe: Nice work, but... Pin
brian.lee
21:47 5 Sep '07  
GeneralNot recognising CDC members Pin
facelaunch
7:53 3 Aug '07  
QuestionStill flickering Pin
facelaunch
10:13 3 Aug '07  
AnswerRe: Still flickering Pin
facelaunch
10:55 3 Aug '07  
GeneralRe: Not recognising CDC members Pin
GuptaP
9:25 16 Aug '07  
GeneralRe: Not recognising CDC members Pin
JDENISW
9:55 14 Jun '09  
QuestionDisplay non-solid-color background in scroll-view correctly Pin
chen_zd
3:45 11 Jun '07  
GeneralThank u. Pin
Murali_mom
22:16 30 May '07  
GeneralHowto use SetViewportExt with CMemDC Pin
Pospiech
4:17 13 May '07  


Last Updated 25 Mar 2002 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009