// 显示透明背景的位图
// 显示透明背景的位图
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退出。