CMemDC代码解

CMemDC是一个很经典的内存DC,实现了MFC的双缓冲绘图。主题实现思路是,将要绘制的背景绘制到内存中,然后在CMemDC析构的时候绘制到屏幕上。

class CMemDC : public CDC {
	private:
		CBitmap m_bitmap; 
		CBitmap* m_oldBitmap; 
		CDC* m_pDC; 
		CRect m_rect; 
		BOOL m_bMemDC; 
	public:
		//内存DC构造函数,根据传入的pDC判断是否为打印机的DC。
                //如果为打印机的DC(m_bMemDC为True),则创建内存m_bitmap内存DC。假如参数bCopyFirst为真,则直接画图。这时就不是双缓冲。假如
                //参数bCopyFirst为假,则等到CMemDC析构后才绘图,实现双缓冲。
                //如果为打印机DC(m_bMemDC为False),则说明传入DC非内存DC,简单复制即可,不需要双缓冲。
		CMemDC(CDC* pDC, CRect rect = CRect(0,0,0,0), BOOL bCopyFirst = FALSE) : CDC(), m_oldBitmap(NULL), m_pDC(pDC)
		{
			ASSERT(m_pDC != NULL); // If you asserted here, you passed in a NULL CDC.
			
			m_bMemDC = !pDC->IsPrinting();
			
			if (m_bMemDC){
				// Create a Memory DC
				CreateCompatibleDC(pDC);
				if ( rect == CRect(0,0,0,0) )
					pDC->GetClipBox(&m_rect);
				else
					m_rect = rect;

				m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
				m_oldBitmap = SelectObject(&m_bitmap);
				SetWindowOrg(m_rect.left, m_rect.top);
				if(bCopyFirst)
				{
					this->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
							m_pDC, m_rect.left, m_rect.top, SRCCOPY);
				}
			} 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;
			}
		}
		
		//析构函数,假如双缓冲模式,则绘制图。
		~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;}
	};



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值