0
点赞
收藏
分享

微信扫一扫

MFC GDI开发 异型窗口 和 抠图

//MemroyCD.h
class CMemoryDC :public CDC
{
CSize m_size;
public:
int GetWidth() const
{
return m_size.cx;
}
int GetHeight()const
{
return m_size.cy;
}
CSize GetSize()const
{
return m_size;
}
//根据透明图生成区域
void MakeRgn(CRgn& r)
{
r.CreateRectRgn(0, 0, 0, 0);//产生句柄
int j = 80;
while (j--)
{
int i = 70;
while (i--)
{
COLORREF c = GetPixel(i, j);
if (c != 0xFF00FF)
{
CRgn r1;
r1.CreateRectRgn(i, j, i + 1, j + 1);
r.CombineRgn(&r, &r1, RGN_OR);
}
}
}

}
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 LoadBitmap(UINT nBitmapID, CDC* pDC = NULL)
{
CBitmap bitmap;
bitmap.LoadBitmap(nBitmapID);
BITMAP bm;
bitmap.GetBitmap(&bm);
m_size.cx = bm.bmWidth;
m_size.cy = bm.bmHeight;
CreateCompatibleDC(pDC);
SelectObject(bitmap);
return TRUE;
}
//创建一张空白内存画布
BOOL Create(int cx, int cy, CDC* pDC = NULL)
{
CreateCompatibleDC(pDC);
CBitmap bitmap;
if (pDC)
bitmap.CreateCompatibleBitmap(pDC, cx, cy);
else
bitmap.CreateCompatibleBitmap(&CClientDC(NULL), cx, cy);
m_size.cx = cx;
m_size.cy = cy;
SelectObject(bitmap);
return TRUE;
}
explicit CMemoryDC(int cx, int cy, CDC* pDC = NULL)
{
Create(cx, cy, pDC);
}
explicit CMemoryDC(UINT nBitmapID, CDC* pDC = NULL)
{
LoadBitmap(nBitmapID, pDC);
}
CMemoryDC() :m_size(0, 0)
{

}
};


//Dlg.h
#include "MemroyCD.h"
class CDlg : public CDialogEx
{
// 构造
enum { FLY_COUNT = 7 };
CRgn m_rs[FLY_COUNT];
CMemoryDC m_dc[FLY_COUNT]{};
int m_nIndex{ 0 };
CPoint m_pos, m_dir{5,5};
CSize m_size;
}

//Dlg.cpp
BOOL CDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
int i = _countof(m_dc);
while (i--)
{
m_dc[i].LoadBitmap(IDB_BITMAP1 + i);
m_dc[i].MakeRgn(m_rs[i]);
}
if (rand() % 2)
m_dir.x *= -1;
if(rand()%2)
m_dir.y *= -1;
m_size.cx = GetSystemMetrics(SM_CXSCREEN) - m_dc->GetWidth();
m_size.cy = GetSystemMetrics(SM_CYSCREEN) - m_dc->GetHeight();
m_pos.x = rand() % m_size.cx;
m_pos.y = rand() % m_size.cy;

MoveWindow(m_pos.x, m_pos.y, m_dc->GetWidth(), m_dc->GetHeight(), false);
SetTimer(1, 32, 0);
if (++m_nIndex > _countof(m_rs))
m_nIndex = 0;
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}

void CDlg::OnPaint()
{
CPaintDC dc(this); // 用于绘制的设备上下文
CRgn r;
r.CreateRectRgn(0, 0, 0, 0);
r.CopyRgn(&m_rs[m_nIndex]);
SetWindowRgn(r, false);
m_dc[m_nIndex].BitTrans(0, 0, m_dc->GetWidth(), m_dc->GetHeight(), &dc, 0, 0, 0xff00ff);
}


void CDlg::OnTimer(UINT_PTR nIDEvent)
{

//CPaintDC dc(this);
CClientDC dc(this);
CRgn r;
r.CreateRectRgn(0, 0, 0, 0);
r.CopyRgn(&m_rs[m_nIndex]);
MoveWindow(CRect{ m_pos,m_dc->GetSize() }, FALSE);
SetWindowRgn(r, false);
dc.BitBlt(0, 0, m_dc->GetWidth(), m_dc->GetHeight(), &m_dc[m_nIndex], 0, 0, SRCCOPY);
if (++m_nIndex >= _countof(m_rs))
m_nIndex = 0;

m_pos.Offset(m_dir);

if (m_pos.y > m_size.cy || m_pos.y < 0)
m_dir.y *= -1;
if (m_pos.x > m_size.cx || m_pos.x < 0)
m_dir.x *= -1;

CDialogEx::OnTimer(nIDEvent);
}

粉色RGB值为0xFF00FF为要扣掉的区域

MFC GDI开发 异型窗口 和 抠图_抠图

MFC GDI开发 异型窗口 和 抠图_MFC异型窗口_02

MFC GDI开发 异型窗口 和 抠图_抠图_03

MFC GDI开发 异型窗口 和 抠图_MFC异型窗口_04

MFC GDI开发 异型窗口 和 抠图_抠图_05

MFC GDI开发 异型窗口 和 抠图_抠图_06

MFC GDI开发 异型窗口 和 抠图_MFC异型窗口_07

举报

相关推荐

0 条评论