CMemDCを利用して図を描く2つの方法


方法1:VS 2010にクラスCMemDCがあり、MFCの下で図面の点滅を解決することができる.
MSDN時計を見てみましょう.
 
 
CMemDC Class
A helper class for a memory device context. The memory device context supports offscreen drawing.
 
 
ライブラリでの宣言は次のとおりです.
 
 
class CMemDC
{
public:
AFX_IMPORT_DATA static BOOL m_bUseMemoryDC;
 
CMemDC(CDC& dc, CWnd* pWnd);
CMemDC(CDC& dc, const CRect& rect);
 
virtual ~CMemDC();
 
CDC& GetDC() { return m_bMemDC ? m_dcMem : m_dc; }
BOOL IsMemDC() const { return m_bMemDC; }
BOOL IsVistaDC() const { return m_hBufferedPaint != NULL; }
 
protected:
CDC&     m_dc;
BOOL     m_bMemDC;
HANDLE   m_hBufferedPaint;
CDC      m_dcMem;
CBitmap  m_bmp;
CBitmap* m_pOldBmp;
CRect    m_rect;
};
 
 
使用方法:
 
// 1、 WM_ERASEBKGND , FALSE, 。 
BOOL CDemoView::OnEraseBkgnd(CDC* pDC)  
{ 
 	 return FALSE; 
} 
// 2、 CMemDC。 
 
 
void CDemoView::OnDraw(CDC* pDC)
{
CGestureDemoDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
 
CMemDC dcMem(*pDC, this);
CDC& dc = dcMem.GetDC();
//do anything with graphic object dc;
......
}
 
 
:ネット でCMemDCを してCDCを するもう つの は の りである.
 

MemDC.h


 
#ifndef _MEMDC_H_
#define _MEMDC_H_
//////////////////////////////////////////////////
//CMemDC - memory DC
//
//Author: Keith Rule
//Email:  [email protected]
//Copyright 1996-1999, 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
//
//This class implements a memory Device Context which allows
//flicker free drawing.
class CMemDC : public CDC {
protected:
   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.
 
   void Construct(CDC* pDC)
   {
        ASSERT(pDC != NULL); 
        //Some initialization
        m_pDC = pDC;
        m_oldBitmap = NULL;
        m_bMemDC = !pDC->IsPrinting();
        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());
            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());
    }
//TRK begin
public:
   CMemDC(CDC* pDC                  ) : CDC() { pDC->GetClipBox(&m_rect); Construct(pDC); }
   CMemDC(CDC* pDC, const RECT& rect) : CDC() { m_rect = rect           ; Construct(pDC); }
//TRK end
 
   virtual ~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 accidently 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
 
 
のクラスは のとおりです.
 
/////////////////////////////////////////////////////////// 
//  How to use: 
/////////////////////////////////////////////////////////// 
// 1、 WM_ERASEBKGND , FALSE, 。 
BOOL CDemoView::OnEraseBkgnd(CDC* pDC)  
{ 
 	 return FALSE; 
} 
/////////////////////////////////////////////////////////// 
// 2、 CMemDC。 
 void CDemoView::OnDraw(CDC* pDC) 
 { 
	 CFont  font; 
	 font.CreateFontIndirect(&m_lf); 
	 CMemDC  pMemDC(pDC); 
	 CFont* oldfont = pMemDC->SelectObject(&font); 
   //..Draw something here. 
	 pMemDC->SelectObject(oldfont); 
 } 
/////////////////////////////////////////////////////////// 
//  include ! 
///////////////////////////////////////////////////////////