CMemoryDC

#pragma once

class CMemoryDC:public CDC
{
	CSize m_size;
public:
	
	int GetWidth()const
	{
		return m_size.cx;
	}

	int GetHeight()const
	{
		return m_size.cy;
	}
	void BitTrans(
		int nXDest,		// 目標起點X
		int nYDest,		// 目標起點Y
		int nWidthDest,	// 目標寬度
		int nHeightDest,// 目標高度
		CDC* pDC,		// 目標DC
		int nXSrc,		// 來源起點X
		int nYSrc,		// 來源起點Y
		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 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	// 透明色
	)
	{//拉伸透明
		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);
	}
	BOOL CreateRgn(CRgn& rgn,COLORREF colTrans)
	{//生成透明圖區域
		rgn.DeleteObject();//六大GDI對象都通過此函數摧毀(之後句柄變空)
		rgn.CreateRectRgn(0, 0, 0, 0);
		
		int i = -1,cx = m_size.cx,cy=m_size.cy;
		while (++i < cx)//70
		{
			int j = -1;
			while (++j < cy)//80
			{
				if (GetPixel(i, j) != colTrans)
				{
					CRgn r;
					r.CreateRectRgn(i, j, i + 1, j + 1);
					rgn.CombineRgn(&rgn, &r, RGN_OR);
				}
			}
		}
		return TRUE;
	}
	BOOL Create(int cx, int cy, CDC* pDC = NULL)
	{//創建空白內存DC
		CBitmap bmp;
		if (pDC)
			bmp.CreateCompatibleBitmap(pDC, cx, cy);
		else
		{
			CClientDC dc(NULL);
			bmp.CreateCompatibleBitmap(&dc, cx, cy);
		}
		CreateCompatibleDC(pDC);
		SelectObject(&bmp);
		m_size.cx = cx;
		m_size.cy = cy;
		return TRUE;
	}
	BOOL LoadBitmap(LPCTSTR sFile, CDC* pDC = NULL)
	{//加載外部位圖
		HGDIOBJ hBitmap = LoadImage(NULL, sFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
		if (!hBitmap)
			return FALSE;
		CreateCompatibleDC(pDC);
		SelectObject(hBitmap);
		BITMAP bm;
		GetObject(hBitmap, sizeof(bm), &bm);
		m_size.cx = bm.bmWidth;
		m_size.cy = bm.bmHeight;
		return TRUE;
	}
	BOOL LoadBitmap(UINT nIDBitmap, CDC* pDC = NULL)
	{//加載資源位圖
		CreateCompatibleDC(pDC);
		CBitmap bmp;
		bmp.LoadBitmap(nIDBitmap);
		SelectObject(&bmp);
		BITMAP bm;
		bmp.GetBitmap(&bm);
		m_size.cx = bm.bmWidth;
		m_size.cy = bm.bmHeight;
		return TRUE;
	}
	CMemoryDC(int cx, int cy, CDC* pDC = NULL)
	{
		Create(cx, cy, pDC);
	}
	CMemoryDC(UINT nIDBitmap, CDC* pDC = NULL)
	{
		LoadBitmap(nIDBitmap, pDC);
	}
	CMemoryDC(LPCTSTR sFile, CDC* pDC = NULL)
	{
		LoadBitmap(sFile, pDC);
	}	
	
	CMemoryDC()
	{

	}
	~CMemoryDC()
	{
		if (!m_hDC)
			return;
		GetCurrentBitmap()->DeleteObject();
		::DeleteDC(Detach());
	}
};

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章