VC++ CMemDC类的扩展(新版)

上一版本链接:https://blog.csdn.net/u012156872/article/details/103755254,测试过程中发现存在问题,于是进行了功能补充。

源码实现(CSWMemDC.h):

#pragma once

namespace sw {
	class CMemDC : public CDC
	{
	public:
		CMemDC(CDC& dc, CWnd* pWnd, BOOL bAutoDraw = TRUE) :
			m_dc(dc), m_bMemDC(FALSE), m_hBufferedPaint(NULL), m_hOldBmp(NULL), m_hBmp(NULL), m_pWnd(pWnd), m_bAutoDraw(bAutoDraw)
		{
			ASSERT_VALID(pWnd);

			pWnd->GetClientRect(m_rect);
			m_rect.right += pWnd->GetScrollPos(SB_HORZ);
			m_rect.bottom += pWnd->GetScrollPos(SB_VERT);

			HDC hdcPaint = NULL;
			m_hBufferedPaint = NULL;// BeginBufferedPaint(dc.GetSafeHdc(), m_rect, BPBF_TOPDOWNDIB, NULL, &hdcPaint);

			if (m_hBufferedPaint != NULL && hdcPaint != NULL)
			{
				m_bMemDC = TRUE;
				this->Attach(hdcPaint);
			}
			else
			{
				if (this->CreateCompatibleDC(&m_dc))
				{
					m_bMemDC = TRUE;
					BITMAPINFO bi;
					bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
					bi.bmiHeader.biBitCount = 32;
					bi.bmiHeader.biHeight = m_rect.Height();
					bi.bmiHeader.biWidth = m_rect.Width();
					bi.bmiHeader.biPlanes = 1;
					bi.bmiHeader.biCompression = BI_RGB;
					bi.bmiHeader.biXPelsPerMeter = 0;
					bi.bmiHeader.biYPelsPerMeter = 0;
					bi.bmiHeader.biClrUsed = 0;
					bi.bmiHeader.biSizeImage = ((m_rect.Width() * 32 + 31) & (~31)) >> 3 * m_rect.Height();
					PVOID pvBits = NULL;
					m_hBmp = ::CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pvBits, 0, 0);//创建32位位图  
					m_hOldBmp = (HBITMAP)this->SelectObject((HBITMAP)m_hBmp);
				}
			}
		}

		CMemDC(CDC& dc, const CRect& rect, BOOL bAutoDraw = TRUE) :
			m_dc(dc), m_bMemDC(FALSE), m_hBufferedPaint(NULL), m_hOldBmp(NULL), m_rect(rect), m_hBmp(NULL), m_pWnd(NULL), m_bAutoDraw(bAutoDraw)
		{
			ASSERT(!m_rect.IsRectEmpty());

			m_pWnd = dc.GetWindow();
			HDC hdcPaint = NULL;
			m_hBufferedPaint = NULL;// BeginBufferedPaint(dc.GetSafeHdc(), m_rect, BPBF_TOPDOWNDIB, NULL, &hdcPaint);

			if (m_hBufferedPaint != NULL && hdcPaint != NULL)
			{
				m_bMemDC = TRUE;
				this->Attach(hdcPaint);
			}
			else
			{
				if (this->CreateCompatibleDC(&m_dc))
				{
					m_bMemDC = TRUE;
					BITMAPINFO bi;
					bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
					bi.bmiHeader.biBitCount = 32;
					bi.bmiHeader.biHeight = m_rect.Height();
					bi.bmiHeader.biWidth = m_rect.Width();
					bi.bmiHeader.biPlanes = 1;
					bi.bmiHeader.biCompression = BI_RGB;
					bi.bmiHeader.biXPelsPerMeter = 0;
					bi.bmiHeader.biYPelsPerMeter = 0;
					bi.bmiHeader.biClrUsed = 0;
					bi.bmiHeader.biSizeImage = ((m_rect.Width() * 32 + 31) & (~31)) >> 3 * m_rect.Height();
					PVOID pvBits = NULL;
					m_hBmp = ::CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, &pvBits, 0, 0);//创建32位位图  
					m_hOldBmp = (HBITMAP)this->SelectObject((HBITMAP)m_hBmp);
				}
			}
		}

		virtual ~CMemDC()
		{
			if (m_hBufferedPaint != NULL)
			{
				this->Detach();
				EndBufferedPaint(m_hBufferedPaint, TRUE);
			}
			else if (m_bMemDC)
			{
				if (m_bAutoDraw)
				{
					DrawSufface(255);
				}

				this->SelectObject((HBITMAP)m_hOldBmp);
			}
		}

		CMemDC* operator->()
		{
			return this;
		}

		operator CMemDC*()
		{
			return this;
		}

		CDC& GetDC() { return m_bMemDC ? *this : m_dc; }
		BOOL IsMemDC() const { return m_bMemDC; }
		BOOL IsVistaDC() const { return m_hBufferedPaint != NULL; }
		void DrawSufface(BYTE byAlpha/* = 255*/)
		{
			CRect rcClip;
			int nClipType = m_dc.GetClipBox(rcClip);

			if (nClipType != NULLREGION)
			{
				if (nClipType != SIMPLEREGION)
				{
					rcClip = m_rect;
				}

				BLENDFUNCTION blend;
				blend.AlphaFormat = AC_SRC_ALPHA;
				blend.BlendFlags = 0;
				blend.BlendOp = AC_SRC_OVER;
				blend.SourceConstantAlpha = byAlpha; 
				::AlphaBlend(m_dc.GetSafeHdc(), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), m_hDC, rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), blend);
				//::BitBlt(m_dc.GetSafeHdc(), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), m_hDC, rcClip.left, rcClip.top, SRCCOPY);
				//::UpdateLayeredWindow(m_pWnd->GetSafeHwnd(), m_dc.GetSafeHdc(), NULL, &CSize(rcClip.Width(), rcClip.Height()), m_hDC, &CPoint(rcClip.left, rcClip.top), 0, &blend, ULW_COLORKEY | ULW_ALPHA);
			}
		}
	protected:
		CDC&     m_dc;
		BOOL     m_bMemDC;
		HANDLE   m_hBufferedPaint;
		HBITMAP  m_hBmp;
		HBITMAP m_hOldBmp;
		CRect    m_rect;
		CWnd*	 m_pWnd;
		BOOL	 m_bAutoDraw;
	};
}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值