MFC 绘制透明背景位图


// 显示透明背景的位图

// 显示透明背景的位图
BOOL CSnowDlg::TransBit(CDC* dcSnow,CDC *dcDest,int pos_x,int pos_y)
{
	// 创建空白DC
	CDC dcImg;
	CBitmap bmp;
	bmp.CreateCompatibleBitmap(dcSnow,32,32);
	dcImg.CreateCompatibleDC(dcSnow);
	dcImg.SelectObject(&bmp);

	CBitmap bmpMask;
	bmpMask.CreateBitmap(32,32,1,1,NULL);
	// 创建单色掩码位图
	CDC dcMask;  // 掩码DC
	dcMask.CreateCompatibleDC(dcDest);
	dcMask.SelectObject(bmpMask);

	// 将载入位图的内存DC中的位图,拷贝到临时DC中
	dcImg.BitBlt(0,0,32,32,dcSnow,0,0,SRCCOPY);

	// 设置临时的DC透明色
	dcImg.SetBkColor(RGB(48,113,184));
	// 掩码DC的透明区域为白色,其他区域为黑色
	dcMask.BitBlt(0,0,32,32,&dcImg,0,0,SRCCOPY);

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

	// 目标DC透明部分保持屏幕不变,其它部分变成黑色
	dcDest->SetBkColor(RGB(255,255,255));
	dcDest->SetTextColor(RGB(0,0,0));
	dcDest->BitBlt(pos_x,pos_y,32,32,&dcMask,0,0,SRCAND);
	dcDest->BitBlt(pos_x,pos_y,32,32,&dcImg,0,0,SRCPAINT);
	return TRUE;
}


Dlg.h文件内容

// SnowDlg.h : 头文件
//

#pragma once

const int SNOW_TYPE = 2;

typedef struct  
{
	int pos_x,pos_y;
	int dis_x,dis_y;
	int nType;
	int nIndex;
}FLY_SNOW;

// CSnowDlg 对话框
class CSnowDlg : public CDialog
{
// 构造
public:
	CSnowDlg(CWnd* pParent = NULL);	// 标准构造函数

// 对话框数据
	enum { IDD = IDD_SNOW_DIALOG };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持

public:
	CDC m_dcBg;
	CDC m_dcSnows[SNOW_TYPE];
	CSize m_szBg,m_szSnow;
	CArray<FLY_SNOW,FLY_SNOW> m_arr;

// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	BOOL Init(void);
	BOOL SnowFly(void);
	afx_msg void OnTimer(UINT_PTR nIDEvent);
	// 显示透明背景的位图
	BOOL TransBit(CDC* dcSnow,CDC* dcDest,int pos_x,int pos_y);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
};


Dlg.cpp文件内容

// SnowDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "Snow.h"
#include "SnowDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CSnowDlg 对话框

CSnowDlg::CSnowDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CSnowDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CSnowDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CSnowDlg, CDialog)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
	ON_WM_TIMER()
	ON_WM_LBUTTONDOWN()
END_MESSAGE_MAP()


// CSnowDlg 消息处理程序

BOOL CSnowDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	srand((unsigned int)time(0));

	Init();
	
	SetTimer(1,100,NULL);

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CSnowDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSnowDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


BOOL CSnowDlg::Init(void)
{
	CBitmap bmpBg;

	if(!bmpBg.LoadBitmap(IDB_BITMAP3))
		return FALSE;


	BITMAP bm;
	if(!bmpBg.GetBitmap(&bm))
		return FALSE;
	m_szBg.cx = bm.bmWidth;
	m_szBg.cy = bm.bmHeight;
	m_dcBg.CreateCompatibleDC(NULL);
	m_dcBg.SelectObject(&bmpBg);

	MoveWindow(0,0,m_szBg.cx,m_szBg.cy);

	for(int i=0;i<SNOW_TYPE;i++)
	{
		CBitmap bmp;
		bmp.LoadBitmap(IDB_BITMAP1+i);
		m_dcSnows[i].CreateCompatibleDC(NULL);
		m_dcSnows[i].SelectObject(&bmp);
	}

	return TRUE;
}

BOOL CSnowDlg::SnowFly(void)
{
	CClientDC dc(this);
	dc.StretchBlt(0,0,m_szBg.cx,m_szBg.cy,&m_dcBg,0,0,m_szBg.cx,m_szBg.cy,SRCCOPY);
	//dc.StretchBlt(10,10,m_szSnow.cx,m_szSnow.cy,&m_dcSnow,0,0,m_szSnow.cx,m_szSnow.cy,SRCCOPY);


	int len = m_arr.GetSize();
	
	for(int i = len-1;i>=0;i--)
	{
		FLY_SNOW &fs = m_arr.GetAt(i);
		TransBit(&m_dcSnows[fs.nType],&dc,fs.pos_x,fs.pos_y);
		fs.pos_x += fs.dis_x;
		fs.pos_y += fs.dis_y;
		fs.pos_x += rand()%5-5;
		if(fs.pos_x>=m_szBg.cx || fs.pos_x+32<=0 || fs.pos_y>=m_szBg.cy)
		{
			m_arr.RemoveAt(i);
		}
	}

	return TRUE;
}

// 定时器处理函数
void CSnowDlg::OnTimer(UINT_PTR nIDEvent)
{
	SnowFly();
	CDialog::OnTimer(nIDEvent);
}

// 显示透明背景的位图
BOOL CSnowDlg::TransBit(CDC* dcSnow,CDC *dcDest,int pos_x,int pos_y)
{
	// 创建空白DC
	CDC dcImg;
	CBitmap bmp;
	bmp.CreateCompatibleBitmap(dcSnow,32,32);
	dcImg.CreateCompatibleDC(dcSnow);
	dcImg.SelectObject(&bmp);

	CBitmap bmpMask;
	bmpMask.CreateBitmap(32,32,1,1,NULL);
	// 创建单色掩码位图
	CDC dcMask;  // 掩码DC
	dcMask.CreateCompatibleDC(dcDest);
	dcMask.SelectObject(bmpMask);

	// 将载入位图的内存DC中的位图,拷贝到临时DC中
	dcImg.BitBlt(0,0,32,32,dcSnow,0,0,SRCCOPY);

	// 设置临时的DC透明色
	dcImg.SetBkColor(RGB(48,113,184));
	// 掩码DC的透明区域为白色,其他区域为黑色
	dcMask.BitBlt(0,0,32,32,&dcImg,0,0,SRCCOPY);

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

	// 目标DC透明部分保持屏幕不变,其它部分变成黑色
	dcDest->SetBkColor(RGB(255,255,255));
	dcDest->SetTextColor(RGB(0,0,0));
	dcDest->BitBlt(pos_x,pos_y,32,32,&dcMask,0,0,SRCAND);
	dcDest->BitBlt(pos_x,pos_y,32,32,&dcImg,0,0,SRCPAINT);
	return TRUE;
}

// 鼠标左键按下事件处理函数
void CSnowDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
	FLY_SNOW fs;
	fs.pos_x = point.x;
	fs.pos_y = point.y;
	fs.dis_x = 3;
	fs.dis_y = 3;
	fs.nType = point.x%SNOW_TYPE;

	m_arr.Add(fs);

	CDialog::OnLButtonDown(nFlags, point);
}




点击后会有雪花产生,按下Esc退出。



  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值