VC++ CMemDC类的扩展(终结版)

上一版本链接:https://blog.csdn.net/u012156872/article/details/104966445,近期做窗口自绘,发现用该方法绘制非客户区仍存在问题,于是进行了功能简化和补充。

定义和声明:

#pragma once

namespace sw {
	class CMemDC : public CDC
	{
	public:
		//构造函数可应用于非客户区窗口绘制
		CCacheDC(CDC& dc, CWnd* pWnd) :
			m_dc(dc), m_hOldBmp(NULL), m_hBmp(NULL), m_hWnd(NULL)
		{
			ASSERT_VALID(pWnd);

			Attach(::GetWindowDC(m_hWnd = pWnd->GetSafeHwnd()));
			pWnd->GetWindowRect(m_rect);
			m_rect.OffsetRect(-m_rect.TopLeft());
			m_dcMem.Attach(m_hDC);
			//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);
			m_hBmp = ::CreateCompatibleBitmap(m_dc.GetSafeHdc(), m_rect.Width(), m_rect.Height());
			m_hOldBmp = (HBITMAP)m_dcMem.SelectObject((HBITMAP)m_hBmp);
		}

		//构造函数只能应用于客户区窗口绘制
		CMemDC(CDC& dc, const CRect& rect) :
			m_dc(dc), m_hOldBmp(NULL), m_rect(rect), m_hBmp(NULL), m_hWnd(NULL)
		{
			ASSERT(!m_rect.IsRectEmpty());
			m_dcMem.CreateCompatibleDC(&m_dc);
			//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);
			m_hBmp = ::CreateCompatibleBitmap(m_dc.GetSafeHdc(), m_rect.Width(), m_rect.Height());
			m_hOldBmp = (HBITMAP)m_dcMem.SelectObject((HBITMAP)m_hBmp);		
		}

		virtual ~CMemDC()
		{
			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 = 255;
				::AlphaBlend(m_dc.GetSafeHdc(), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), m_dcMem.GetSafeHdc(), rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), blend);
			}

			m_dcMem.SelectObject((HBITMAP)m_hOldBmp);
			if (m_hWnd)
				::ReleaseDC(m_hWnd, Detach());		
		}

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

		operator CMemDC*()
		{
			return this;
		}

		CDC& GetDC() { return m_dcMem; }
		
	protected:
		CDC&     m_dc;
		HBITMAP  m_hBmp;
		HBITMAP  m_hOldBmp;
		CDC      m_dcMem;
		CRect    m_rect;
		HWND	 m_hWnd;
	};
}

猜你喜欢

转载自blog.csdn.net/u012156872/article/details/119850157