#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());
}
};