现在的位置: 首页 > 综合 > 正文

利用CMemDC画图的两种方法

2017年12月18日 ⁄ 综合 ⁄ 共 3926字 ⁄ 字号 评论关闭

方法一: 在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:  keithr@europa.com

// 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头文件! 
/////////////////////////////////////////////////////////// 

 

 

抱歉!评论已关闭.