MFC 绘制透明背景位图

    xiaoxiao2021-04-16  35

    // 显示透明背景的位图

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

    转载请注明原文地址: https://ju.6miu.com/read-672932.html

    最新回复(0)