MFC透明动画实例
来源:互联网 发布:淘宝登录验证怎么解除 编辑:程序博客网 时间:2024/06/15 20:28
最终实现效果:
过程:
一:从网上搜索一套带透明背景的位图(要做动画帧用),或者使用附件里的Fly紫文件夹里的透明位图,如果需要更换位图,需要修改相关代码
二:使用vc6.0新建一个基于对话框的MFC程序,直接打开资源文件中的对话框界面,将对话框BORDER属性设为NONE
三:将已经封装好的MemDC.h(MemdDC.h要想在vs2016中使用,需要更改里面的类名,会与MFC的类名冲突,其他版本不清楚)文件导入工程,添加相关头文件,主要使用到MemDC里的BitTrans()函数和LoadBitmap()函数,前者用于将不透明位图输出为透明位图,后者用来加载位图
四:修改对话框头文件和CPP文件
MemDC.h
#ifndef __MEM_DC__H__#define __MEM_DC__H__//防止重复编译class CMemDC : public CDC{ CSize m_size;public: ~CMemDC() { DeleteDC(); } CMemDC() { m_size.cx = m_size.cy=0; } CMemDC(UINT nBitmap,CDC* pDC=NULL) { LoadBitmap(nBitmap,pDC); } CMemDC(LPCSTR szFile,CDC* pDC=NULL) { LoadBitmap(szFile,pDC); } CMemDC(int cx,int cy,CDC* pDC=NULL) { Create(cx,cy,pDC); } BOOL DeleteDC() { if(!GetSafeHdc()) return FALSE; CBitmap* pBitmap = GetCurrentBitmap(); if(pBitmap) pBitmap ->DeleteObject(); return CDC::DeleteDC(); } int GetWidth(){return m_size.cx;} int GetHeight(){return m_size.cy;} BOOL Create(int cx,int cy,CDC* pDC=NULL) {//创建空白位图 CBitmap bmp; if(!bmp.CreateCompatibleBitmap(pDC,cx,cy)) return FALSE; m_size.cx = cx; m_size.cy = cy; CreateCompatibleDC(pDC); SelectObject(&bmp); return TRUE; } BOOL LoadBitmap(UINT nBitmap,CDC* pDC=NULL) {//进程内位图资源加载 CBitmap bmp; if(!bmp.LoadBitmap(nBitmap)) return FALSE; BITMAP bm; bmp.GetBitmap(&bm); m_size.cx = bm.bmWidth; m_size.cy = bm.bmHeight; CreateCompatibleDC(pDC); SelectObject(&bmp); return TRUE; } BOOL LoadBitmap(LPCSTR szFile,CDC* pDC=NULL) {//进程外位图图片文件加载 HBITMAP hBitmap = (HBITMAP)LoadImage(NULL,szFile,IMAGE_BITMAP, 0,0,LR_LOADFROMFILE); if(!hBitmap) return FALSE; BITMAP bm; GetObject(hBitmap,sizeof(bm),&bm); m_size.cx = bm.bmWidth; m_size.cy = bm.bmHeight; CreateCompatibleDC(pDC); SelectObject(hBitmap); return TRUE; } void BitTrans( int nXDest, // 目标起点X int nYDest, // 目标起点Y int nWidthDest, // 目标宽度 int nHeightDest,// 目标高度 CDC* pDC, // 目标DC int nXSrc, // 来源起点X int nYSrc, // 来源起点Y COLORREF crTrans// 透明色 ) { CMemDC 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 // 透明色 ) { CMemDC 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); } };#endif
主对话框头文件FlyDlg.h实现
// FlyDlg.h : header file//#if !defined(AFX_FLYDLG_H__B92F35C6_0BDF_4DB7_BDDE_ED28D1CBBEF4__INCLUDED_)#define AFX_FLYDLG_H__B92F35C6_0BDF_4DB7_BDDE_ED28D1CBBEF4__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000/////////////////////////////////////////////////////////////////////////////// CFlyDlg dialog#include "MemDC.h"class CFlyDlg : public CDialog{ enum{COUNT=7}; CMemDC m_dcBack;// CMemDC m_dc[COUNT]; int m_nIndex; CPoint m_pos;public: void OnDraw(CDC* pDC); CFlyDlg(CWnd* pParent = NULL); // standard constructor// Dialog Data //{{AFX_DATA(CFlyDlg) enum { IDD = IDD_FLY_DIALOG }; // NOTE: the ClassWizard will add data members here //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CFlyDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CFlyDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnTimer(UINT nIDEvent); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnNcPaint(); //}}AFX_MSG DECLARE_MESSAGE_MAP()};//{{AFX_INSERT_LOCATION}}// Microsoft Visual C++ will insert additional declarations immediately before the previous line.#endif // !defined(AFX_FLYDLG_H__B92F35C6_0BDF_4DB7_BDDE_ED28D1CBBEF4__INCLUDED_)
主对话框CPP文件实现FlyDlg.cpp
// FlyDlg.cpp : implementation file//#include "stdafx.h"#include "Fly.h"#include "FlyDlg.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CFlyDlg dialog#define TRANSCOLOR RGB(0,0,255)//透明色为紫色CFlyDlg::CFlyDlg(CWnd* pParent /*=NULL*/) : CDialog(CFlyDlg::IDD, pParent){ m_nIndex=0; m_pos.x = m_pos.y=0; //{{AFX_DATA_INIT(CFlyDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);}void CFlyDlg::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CFlyDlg) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CFlyDlg, CDialog) //{{AFX_MSG_MAP(CFlyDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_WM_TIMER() ON_WM_ERASEBKGND() ON_WM_NCPAINT() //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CFlyDlg message handlersBOOL CFlyDlg::OnInitDialog(){ CDialog::OnInitDialog(); m_dcBack.LoadBitmap("./Flys_紫/Back.bmp"); int i=0; CString str; while(i<COUNT) { str.Format("./Flys_紫/%03d.bmp",i+1); m_dc[i].LoadBitmap(str); ++i; } SetTimer(1,64,NULL); MoveWindow(0,0,m_dcBack.GetWidth(),m_dcBack.GetHeight()); // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon return TRUE; // return TRUE unless you set the focus to a control}// If you add a minimize button to your dialog, you will need the code below// to draw the icon. For MFC applications using the document/view model,// this is automatically done for you by the framework.void CFlyDlg::OnPaint() { CPaintDC dc(this); OnDraw(&dc);}// The system calls this to obtain the cursor to display while the user drags// the minimized window.http://www.fodizi.com/fofa/list/248.htmHCURSOR CFlyDlg::OnQueryDragIcon(){ return (HCURSOR) m_hIcon;}//为什么画面上方会产生秘密文字???void CFlyDlg::OnTimer(UINT nIDEvent) { //如果使用注释掉的这一部分,则是没有采用双缓冲,需要注释掉OnPaint函数里的OnDraw()函数和这里的Invalideate()函数 //如果使用OnDraw函数,则是采用了双缓冲技术,OnDraw()在OnPaint()中调用,所以要使用Invalidate()函数来刷新界面 /* static int i=0; CClientDC dc(this); //显示背景 dc.BitBlt(0,0,m_dcBack.GetWidth(),m_dcBack.GetHeight(), &m_dcBack,0,0,SRCCOPY); static int cx=m_dc[m_nIndex].GetWidth();//离开函数数值不丢失 static int cy=m_dc[m_nIndex].GetHeight(); static dx=5,dy=5;//运动方向 //显示蝴蝶 m_dc[m_nIndex].BitTrans(m_pos.x,m_pos.y,cx,cy,&dc,0,0,TRANSCOLOR); //控制蝴蝶位置 m_pos.Offset(dx,dy); if(m_pos.x + cx> m_dcBack.GetWidth() || m_pos.x <0) dx*=-1; if(m_pos.y + cy> m_dcBack.GetHeight() || m_pos.y < 0) dy *=-1; if(++m_nIndex>=COUNT) m_nIndex=0;*/ Invalidate(FALSE);}//使用双缓冲技术void CFlyDlg::OnDraw(CDC *pDC){ CRect rect; GetClientRect(rect); CMemDC mdc(rect.Width(),rect.Height(),pDC); //如果不用背景图去覆盖掉上一次的蝴蝶,可以用FillSolidRect这一句去覆盖(必须要有东西来覆盖掉上一次的蝴蝶), //但如果在用绿色覆盖后又再用背景图覆盖,如果没有使用双缓冲技术,会发生闪烁// mdc.FillSolidRect(0,0,rect.right,rect.Height(),RGB(255,0,0)); //既可以拉伸,也可以直接输入到缓冲内存中 //如果TRANSCOLOR为黑色并且把FillSolidRect()的注释去掉,会有神秘文字出现,改成其他颜色不会,这种现象与图本身有关// m_dcBack.StretchTrans(0,0,rect.right,rect.bottom,&mdc,0,0,m_dcBack.GetWidth(),// m_dcBack.GetHeight(),TRANSCOLOR); m_dcBack.BitTrans(0,0,rect.right,rect.bottom,&mdc,0,0,RGB(0,0,0));// dc.BitBlt(0,0,m_dcBack.GetWidth(),m_dcBack.GetHeight(),&m_dcBack,0,0,SRCCOPY); static int cx = m_dc[m_nIndex].GetWidth();//static变量第一次进入函数式初始化 static int cy = m_dc[m_nIndex].GetHeight();//离开函数数值不丢失 static dx=5,dy=5;//运动方向 m_dc[m_nIndex].BitTrans(m_pos.x,m_pos.y,cx,cy,&mdc,0,0,TRANSCOLOR); pDC ->BitBlt(0,0,mdc.GetWidth(),mdc.GetHeight(),&mdc,0,0,SRCCOPY); m_pos.Offset(dx,dy); if(m_pos.x + cx> rect.right || m_pos.x <0) dx*=-1; if(m_pos.y + cy> rect.bottom || m_pos.y < 0) dy *=-1; if(++m_nIndex>=COUNT) m_nIndex=0;}BOOL CFlyDlg::OnEraseBkgnd(CDC* pDC) { return TRUE;}void CFlyDlg::OnNcPaint() {}
程序遗留问题:
如果带有透明背景的位图的透明色为黑色的话,在运行的时候蝴蝶图片的背景仍然不会被去除掉,原因暂时未弄明白,如果有网友看了这份代码,并且
明白了这个问题的原因的话,如果能在评论里或写信指导一下本人,本人将感激不尽!!
附件下载:
=工程文件
参考:
http://study.163.com/course/courseLearn.htm?courseId=613004#/learn/video?lessonId=783001&courseId=613004
阅读全文
0 0
- MFC透明动画实例
- mfc透明
- mfc透明
- Animation 动画透明转换
- 透明动画窗体
- Android透明动画
- GDI---透明动画
- 设置MFC窗口透明
- 设置MFC窗口透明
- MFC实现透明窗口
- MFC设置窗口透明
- MFC窗体透明
- MFC 窗口背景透明
- mfc窗体透明方法
- mfc窗体透明2
- mfc控件透明方法
- mfc控件透明
- MFC 窗口透明
- Do Deep Neural Networks Learn Facial Action Units When Doing Expression Recognition?论文笔记
- python基础学习-python操作sqlite数据库
- binary-tree-preorder-traversal
- hdu 2066 一个人的旅行【Dijkstra】解法
- PHP从命令行接收参数
- MFC透明动画实例
- nyoj 17单调递增最长子序列
- shell脚本
- python 一些函数介绍
- C++ class templates(2)---《C++ Templates》
- Vacations
- JavaScript使用正则表达式
- DNS服务器搭建
- linux系统编程模拟火车售票