自己写CMemoryDC

CMemoryDC头文件

#pragma once
class CMemoryDC:public CDC
{
public:
	//从资源中加载
	CMemoryDC(UINT nID, CDC *pCDC = NULL);
	//从文件中加载
	CMemoryDC(LPCTSTR szFile, CDC *pCDC = NULL);
	//自己加载
	CMemoryDC(int cx, int cy, CDC* pDC = NULL);
	CMemoryDC();
	~CMemoryDC();
	//从资源中加载
	BOOL AddBitmap(UINT nBitmapID, CDC *pCDC = NULL);
	//从文件夹中加载
	BOOL AddFromFile(LPCTSTR szFile, CDC *pCDC = NULL);
	//透明
	void BitTrans(
		int nXDest,		// 目标起点X
		int nYDest,		// 目标起点Y
		int nWidthDest,	// 目标宽度
		int nHeightDest,// 目标高度
		CDC* pDC,		// 目标DC
		int nXSrc,		// 来源起点X
		int nYSrc,		// 来源起点Y
		COLORREF crTrans// 透明色
	);
	void StretchTrans(
		int nXDest,			// 目标起点X
		int nYDest,			// 目标起点Y
		int nWidthDest,     // 目标宽度
		int nHeightDest,    // 目标高度
		CDC* pDC,			// 目标DC
		int nXSrc,			// 来源起点X
		int nYSrc,			// 来源起点Y
		int nWidthSrc,		// 来源宽度
		int nHeightSrc,		// 来源高度
		COLORREF crTrans	// 透明色
	);
public:
	int GetWidth()const;
	int GetHeight()const;
	//创建一张空白内存画布
	BOOL Create(int cx, int cy, CDC* pDC = NULL);
private:
	CSize m_APIsize;
	void DeleteBitmap();
};

CMemoryDC的.cpp文件

#include "stdafx.h"
#include "CMemoryDC.h"


CMemoryDC::CMemoryDC(UINT nID, CDC * pCDC) :m_APIsize(0, 0)
{
	AddBitmap(nID, pCDC);
}

CMemoryDC::CMemoryDC(LPCTSTR szFile, CDC * pCDC) : m_APIsize(0, 0)
{
	AddFromFile(szFile, pCDC);
}

CMemoryDC::CMemoryDC(int cx, int cy, CDC * pDC) : m_APIsize(0, 0)
{
	Create(cx, cy, pDC);
}

CMemoryDC::CMemoryDC() : m_APIsize(0, 0)
{
}


CMemoryDC::~CMemoryDC()
{
	DeleteBitmap();
}

BOOL CMemoryDC::AddBitmap(UINT nBitmapID, CDC *pCDC)
{
	CBitmap bmp;
	//加载位图
	BOOL nResu = bmp.LoadBitmapW(nBitmapID);
	if (!nResu)
		return FALSE;
	//获取位图的高、宽
	BITMAP b;
	bmp.GetBitmap(&b);
	m_APIsize.SetSize(b.bmWidth, b.bmHeight);

	this->CreateCompatibleDC(pCDC);  //创建一个CDC
	this->SelectObject(&bmp);        //将位图选择进创建的CDC
	return TRUE;
}

BOOL CMemoryDC::AddFromFile(LPCTSTR szFile, CDC * pCDC)
{
	HBITMAP hBitmap = (HBITMAP)::LoadImage(NULL, szFile, IMAGE_BITMAP, 
		0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE);
	//获取位图的高、宽
	BITMAP b;
	GetObject(hBitmap, sizeof(b), &b);
	m_APIsize.SetSize(b.bmWidth, b.bmHeight);

	this->CreateCompatibleDC(pCDC);  //创建一个CDC
	this->SelectObject(hBitmap);        //将位图选择进创建的CDC
	::DeleteObject(hBitmap);
	return 0;
}

void CMemoryDC::BitTrans(int nXDest, int nYDest, int nWidthDest, int nHeightDest, CDC * pDC, int nXSrc, int nYSrc, COLORREF crTrans)
{
	CMemoryDC dcImage(nWidthDest, nHeightDest, pDC);//临时DC
	CBitmap bmpMask;
	bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);            // 创建单色掩码位图
	CDC dcMask;//掩码DC 
	dcMask.CreateCompatibleDC(pDC);
	dcMask.SelectObject(bmpMask);
	//将载入位图的内存DC中的位图,拷贝到临时DC中
	dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);

	// 设置临时DC的透明色
	dcImage.SetBkColor(crTrans);
	//掩码DC的透明区域为白色其它区域为黑色
	dcMask.BitBlt(0, 0, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCCOPY);

	//临时DC透明区域为黑色,其它区域保持不变
	dcImage.SetBkColor(RGB(0, 0, 0));
	dcImage.SetTextColor(RGB(255, 255, 255));
	dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);

	// 目标DC透明部分保持屏幕不变,其它部分变成黑色
	pDC->SetBkColor(RGB(255, 255, 255));
	pDC->SetTextColor(RGB(0, 0, 0));
	pDC->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
	pDC->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);
}

void CMemoryDC::StretchTrans(int nXDest, int nYDest, int nWidthDest, int nHeightDest, CDC * pDC, int nXSrc, int nYSrc, int nWidthSrc, int nHeightSrc, COLORREF crTrans)
{
	CMemoryDC dcImage(nWidthDest, nHeightDest, pDC);//临时DC
	CBitmap bmpMask;
	// 创建单色掩码位图
	bmpMask.CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL);
	CDC dcMask;
	dcMask.CreateCompatibleDC(pDC);
	dcMask.SelectObject(bmpMask);

	// 将载入位图的内存DC中的位图,拷贝到临时DC中
	if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
		dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, this, nXSrc, nYSrc, SRCCOPY);
	else
		dcImage.StretchBlt(0, 0, nWidthDest, nHeightDest,
			this, nXSrc, nYSrc, nWidthSrc, nHeightSrc, SRCCOPY);

	// 设置临时DC的透明色
	dcImage.SetBkColor(crTrans);
	//掩码DC的透明区域为白色其它区域为黑色
	dcMask.BitBlt(0, 0, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCCOPY);

	//临时DC透明区域为黑色,其它区域保持不变
	dcImage.SetBkColor(RGB(0, 0, 0));
	dcImage.SetTextColor(RGB(255, 255, 255));
	dcImage.BitBlt(0, 0, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);

	// 目标DC透明部分保持屏幕不变,其它部分变成黑色
	pDC->SetBkColor(RGB(255, 255, 255));
	pDC->SetTextColor(RGB(0, 0, 0));
	pDC->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcMask, 0, 0, SRCAND);
	pDC->BitBlt(nXDest, nYDest, nWidthDest, nHeightDest, &dcImage, 0, 0, SRCPAINT);
}

int CMemoryDC::GetWidth() const
{
	return m_APIsize.cx;
}

int CMemoryDC::GetHeight() const
{
	return m_APIsize.cy;
}

void CMemoryDC::DeleteBitmap()
{
	CBitmap *pBitmap = this->GetCurrentBitmap();
	if (pBitmap)
		pBitmap->DeleteObject();
}

BOOL CMemoryDC::Create(int cx, int cy, CDC * pDC)
{
	CreateCompatibleDC(pDC);
	CBitmap bitmap;
	if (pDC)
		bitmap.CreateCompatibleBitmap(pDC, cx, cy);
	else
		bitmap.CreateCompatibleBitmap(&CClientDC(NULL), cx, cy);
	m_APIsize.cx = cx;
	m_APIsize.cy = cy;
	SelectObject(bitmap);
	return TRUE;
}

猜你喜欢

转载自blog.csdn.net/qq_38611124/article/details/82949545
今日推荐