MFC-双缓冲绘图-CMemDC的封装

CMyMemDC.h

#pragma once
#include "afxwin.h"
#include "atlimage.h"
class CMyMemDC : public CDC
{
public:
	CMyMemDC();
	CMyMemDC(int cx, int cy, CDC* pDC = NULL);
	CMyMemDC(UINT nResID, CDC* pDC, LPCTSTR lpTyp = _T("BMP"));
	~CMyMemDC();
private:
	CSize m_size;
private:
	BOOL LoadCImageFromResourse(CImage *pImage, UINT nResID, LPCTSTR lpTyp);
public:
	BOOL Create(int cx, int cy, CDC* pDC = NULL);
	BOOL Create(UINT nResID, CDC* pDC, LPCTSTR lpTyp = _T("BMP"));
	void BitTrans(int xDest,int yDest,int nDestWidth,int nDestHeight,
		CDC* pDC,int xSrc,int ySrc,COLORREF crTrans);
	void StretchTrans(int xDest, int yDest, int nDestWidth, int nDestHeight,CDC* pDC, 
		int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, COLORREF crTrans);
	UINT GetWidth();
	UINT GetHeight();
};




CMyMemDC.cpp

#include "stdafx.h"
#include "MyMemDC.h"

CMyMemDC::CMyMemDC()
{
	m_size.cx = m_size.cy = 0;
}
CMyMemDC::CMyMemDC(int cx, int cy, CDC* pDC)
{
	Create(cx, cy, pDC);
}
CMyMemDC::CMyMemDC(UINT nResID, CDC* pDC, LPCTSTR lpTyp)
{
	Create(nResID, pDC, lpTyp);
}

CMyMemDC::~CMyMemDC()
{
	if (!GetSafeHdc())
		return;
	CBitmap* pBitmap = GetCurrentBitmap();
	if (pBitmap)
		pBitmap->DeleteObject();
	DeleteDC();
}
BOOL CMyMemDC::Create(int cx, int cy, CDC* pDC)
{
	CBitmap bmp;
	if (!bmp.CreateCompatibleBitmap(pDC,cx,cy))
		return FALSE;
	m_size.cx = cx;
	m_size.cy = cy;
	CreateCompatibleDC(pDC);
	SelectObject(&bmp);
	return TRUE;
}
BOOL CMyMemDC::Create(UINT nResID, CDC* pDC, LPCTSTR lpTyp)
{
	CImage img;
	LoadCImageFromResourse(&img, nResID, lpTyp);
	CBitmap bmp;
	if (!bmp.CreateCompatibleBitmap(pDC, img.GetWidth(), img.GetHeight()))
		return FALSE;
	m_size.cx = img.GetWidth();
	m_size.cy = img.GetHeight();
	CreateCompatibleDC(pDC);
	SelectObject(&bmp);
	img.BitBlt(m_hDC, 0, 0, m_size.cx, m_size.cy, 0, 0, SRCCOPY);
	return TRUE;
}
void CMyMemDC::BitTrans(int xDest, int yDest, int nDestWidth, int nDestHeight, 
	CDC* pDC, int xSrc, int ySrc, COLORREF crTrans)
{
	CMyMemDC dcImage(nDestWidth, nDestHeight,pDC);
	CBitmap bmpMask;
	bmpMask.CreateBitmap(nDestWidth, nDestHeight, 1, 1, NULL);
	CDC dcMask;
	dcMask.CreateCompatibleDC(pDC);
	dcMask.SelectObject(&bmpMask);
	dcImage.BitBlt(0,0, nDestWidth, nDestHeight,this, xSrc, ySrc,SRCCOPY);
	dcImage.SetBkColor(crTrans);
	dcMask.BitBlt(0, 0, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCCOPY);
	dcImage.SetBkColor(RGB(0,0,0));
	dcImage.SetTextColor(RGB(255,255,255));
	dcImage.BitBlt(0, 0, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND);
	pDC->SetBkColor(RGB(255, 255, 255));
	pDC->SetTextColor(RGB(0, 0, 0));
	pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND);
	pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCPAINT);
	dcMask.DeleteDC();
	bmpMask.DeleteObject();
}
void CMyMemDC::StretchTrans(int xDest, int yDest, int nDestWidth, int nDestHeight,CDC* pDC, 
	int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, COLORREF crTrans)
{
	CMyMemDC dcImage(nDestWidth, nDestHeight, pDC);
	CBitmap bmpMask;
	bmpMask.CreateBitmap(nDestWidth, nDestHeight, 1, 1, NULL);
	CDC dcMask;
	dcMask.CreateCompatibleDC(pDC);
	dcMask.SelectObject(&bmpMask);
	if (nDestWidth == nSrcWidth && nDestHeight == nSrcHeight)
	{
		dcImage.BitBlt(0, 0, nDestWidth, nDestHeight, this, xSrc, ySrc, SRCCOPY);
	}
	else {
		dcImage.SetStretchBltMode(STRETCH_HALFTONE);
		dcImage.StretchBlt(0, 0, nDestWidth, nDestHeight, this, xSrc, ySrc, nSrcWidth, nSrcHeight, SRCCOPY);
	}
	dcImage.SetBkColor(crTrans);
	dcMask.BitBlt(0, 0, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCCOPY);
	dcImage.SetBkColor(RGB(0, 0, 0));
	dcImage.SetTextColor(RGB(255, 255, 255));
	dcImage.BitBlt(0, 0, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND);
	pDC->SetBkColor(RGB(255, 255, 255));
	pDC->SetTextColor(RGB(0, 0, 0));
	pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND);
	pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCPAINT);
	dcMask.DeleteDC();
	bmpMask.DeleteObject();
}
BOOL CMyMemDC::LoadCImageFromResourse(CImage *pImage, UINT nResID, LPCTSTR lpTyp)
{
	if (pImage == NULL)
		return FALSE;
	pImage->Destroy();
	HMODULE hModule = AfxGetInstanceHandle();
	if (lpTyp == _T("BMP"))
	{
		pImage->LoadFromResource(hModule, MAKEINTRESOURCE(nResID));
		return TRUE;
	}
	// 查找资源  
	HRSRC hRsrc = ::FindResource(hModule, MAKEINTRESOURCE(nResID), lpTyp);
	if (hRsrc == NULL)
		return FALSE;

	// 加载资源  
	HGLOBAL hImgData = ::LoadResource(hModule, hRsrc);
	if (hImgData == NULL)
	{
		::FreeResource(hImgData);
		return FALSE;
	}

	// 锁定内存中的指定资源  
	LPVOID lpVoid = ::LockResource(hImgData);

	LPSTREAM pStream = NULL;
	DWORD dwSize = ::SizeofResource(hModule, hRsrc);
	HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize);
	LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew);
	::memcpy(lpByte, lpVoid, dwSize);

	// 解除内存中的指定资源  
	::GlobalUnlock(hNew);

	// 从指定内存创建流对象  
	HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream);
	if (ht != S_OK)
	{
		GlobalFree(hNew);
	}
	else
	{
		// 加载图片  
		pImage->Load(pStream);
		if (pImage->GetBPP() == 32)  //确认该图片包含Alpha通道      
		{
			for (int i = 0; i < pImage->GetWidth(); i++)
				for (int j = 0; j < pImage->GetHeight(); j++)
				{
					byte* pByte = (byte*)pImage->GetPixelAddress(i, j);
					pByte[0] = pByte[0] * pByte[3] / 255;
					pByte[1] = pByte[1] * pByte[3] / 255;
					pByte[2] = pByte[2] * pByte[3] / 255;
				}
		}
		GlobalFree(hNew);
	}
	// 释放资源  
	::FreeResource(hImgData);

	return TRUE;
}

UINT CMyMemDC::GetWidth()
{
	return m_size.cx;
}
UINT CMyMemDC::GetHeight()
{
	return m_size.cy;
}



用法:

		CPaintDC dc(this);
		CRect rc;
		GetClientRect(rc);
		dc.BitBlt(0, 0, rc.Width(), rc.Height(), &m_dc, 0, 0, SRCCOPY);
		m_dc.BitTrans(100, 0, rc.Width(), rc.Height(), &dc,0, 0, RGB(0,0,0));
		m_dc.StretchTrans(0, 0, rc.Width()-200, rc.Height()-200, &dc, 0, 0, m_dc.GetWidth(),m_dc.GetHeight(), RGB(0, 0, 0));
		CDialog::OnPaint();




你可能感兴趣的:(MFC-双缓冲绘图-CMemDC的封装)