本文由BlueCoder编写   转载请说明出处:

http://blog.csdn.net/crocodile__/article/details/12975077

我的邮箱:bluecoder@yeah.net    欢迎大家和我交流编程心得

我的微博:BlueCoder_黎小华    欢迎光临^_^

前段时间为了系统学习MFC,花了一星期的课余时间复习了c++,将<<C++ Primer>>看了一遍,感觉关于c++的见识涨了不少,毕竟看完大师级人物写的书籍确实应该有如获光明的感觉。不过由于时间的原因,有几章节没怎么祥看——当然,以后必定细细品味

因此感叹一句:好久没写博客了啊——呵呵

ok,归入正题

今天上午看见Yorhom用HTML5实现了一个『HTML5梦幻之旅』-滚动播放的幻灯片效果,感觉不错。于是借着他给的灵感(刚好最近在学MFC),我用MFC来实现类似的效果(思想略有不同),先上一个效果gif:

下面我来讲解一下具体的实现

一、编译环境

VS2008企业完整版,创建一个MFC工程(项目名称为SlideBmp):

二、剖析实现思想

先来看看我制作的一张示意图:

ClientWidth表示窗口客户区的宽度——这里就是View窗口

(1). 从左边出现的图片,预先放在横坐标为-ClientWidth的位置,然后启动计时器,增加横坐标,逐渐移动,直到横坐标为0——也就是到达了窗口客户区,就关闭计时器——这时图片刚好停留在客户区

(2). 同理,从右边出现的图片预先放在横坐标为ClientWidth处,后面的同(1)

这样实现的效果就是每次移动的图片会覆盖上一次的图片

怎么样,还是挺简单的吧?

三、剖析实现代码

(1). 改变MFC默认的窗口外观——在CMainFrame::PreCreateWindow中,也就是创建框架窗口之前修改——代码如下:

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{if( !CFrameWnd::PreCreateWindow(cs) )return FALSE;// TODO: 在此处通过修改//  CREATESTRUCT cs 来修改窗口类或样式//更改窗口外观CSize size;//获取屏幕像素大小size.cx = ::GetSystemMetrics(SM_CXSCREEN);size.cy = ::GetSystemMetrics(SM_CYSCREEN);//窗口风格(快捷菜单式的窗口, 无边框、标题栏)cs.style    = WS_POPUPWINDOW;//去掉菜单cs.hMenu    = NULL;//窗口标题名称cs.lpszName = _T("SlideBmp");//自定义窗口大小, 并窗口居中显示cs.x      = (size.cx - 486 ) / 2;cs.y        = (size.cy - 360) / 2;cs.cx        = 486;cs.cy        = 360;return TRUE;
}

(2). 因为View窗口是MainFrame框架窗口的子窗口,因此应该在它上面做工作——贴图片

(3). 在构造函数中进行初始化工作

CSlideBmpView::CSlideBmpView()
{//初始化m_index = 0;m_start = 0;m_isStart = true;m_isLeft = false;m_isLoad = true;
}

(4). 所需变量或成员的定义,在SlideBmpView.h头文件中

全局变量

//计时器ID
#define ID_TIMER_PAINT  100//全局变量N——表示有几张图片
const int   N = 5;
//图片的名称(这里也是路径)
const LPCTSTR pszPngName[] = {_T("0.png"), _T("1.png"), _T("2.png"), _T("3.png"), _T("4.png")};

CSlideBmpView类私有成员

private:CRect m_rClient;//客户区大小CImage  m_img;//用于在内存中绘图CDC        m_bufferDC;//缓冲DCCBitmap    m_bufferBmp;//缓冲Bitmapint       m_index;//标记图片索引int     m_start;//标记图片起始位置bool  m_isStart;//标记是否是开始bool m_isLeft;//标记图片移动方向bool m_isLoad;//标记是否加载图片

(5). 由于我是用键盘控制图片出现的方向——方向键左键表示从左边往右出现,右键表示从右边往左边出现——添加键盘消息处理函数(WM_KEYDOWN)

void CSlideBmpView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{//如果图片起始位置是起点,表示图片已经移动结束.这时才允许继续移动图片if(!m_start){//如果按下左键if(nChar == VK_LEFT){m_isLeft = true;m_start = m_rClient.Width();}//如果按下右键else if(nChar == VK_RIGHT){m_isLeft = false; m_start = -m_rClient.Width();}//设置定时器, 触发动画的开始if(nChar == VK_LEFT || nChar == VK_RIGHT){m_index = (m_index + 1) % N;m_isLoad = true;SetTimer(ID_TIMER_PAINT, 10, NULL);InvalidateRect(NULL, false);}}CView::OnKeyDown(nChar, nRepCnt, nFlags);
}

(6). 响应计时器消息——WM_TIMER

void CSlideBmpView::OnTimer(UINT_PTR nIDEvent)
{if(m_isLeft){m_start -= 8;        }else{m_start += 8;}//如果图片刚好布满客户区, 就停止移动if(!m_start){KillTimer(ID_TIMER_PAINT);}//在移动图片时不需要加载图片m_isLoad = false;/*重绘因为, 每次绘制都会覆盖上一次的, 因此不需要重绘背景否则它会使用默认的白色画刷重绘背景, 闪屏会很厉害*/InvalidateRect(NULL, false);CView::OnTimer(nIDEvent);
}

(7). 在CSlideView::OnDraw函数中绘图——响应Win32的WM_PAINT

void CSlideBmpView::OnDraw(CDC* pDC)
{CSlideBmpDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);if (!pDoc)return;//如果是窗口建立之初if(m_isStart){m_isStart = false;GetClientRect(&m_rClient);//创建缓冲DCm_bufferDC.CreateCompatibleDC(NULL);//创建缓冲Bitmapm_bufferBmp.CreateCompatibleBitmap(pDC, 800, 600);//将缓冲Bitmap选入缓冲DC中m_bufferDC.SelectObject(m_bufferBmp);}//如果需要加载图片if(m_isLoad){//加载图片m_img.Load(pszPngName[m_index]);//在内存中绘图(缓冲DC)m_img.Draw(m_bufferDC, 0, 0);//取消图片与m_img对象的关联, 以使下一次顺利关联下一个图片m_img.Detach();}//贴图pDC->SetStretchBltMode(COLORONCOLOR);pDC->StretchBlt(m_start, 0, m_rClient.Width(), m_rClient.Height(),&m_bufferDC, 0, 0, 800, 600, SRCCOPY);
}

(8). 记得回收内存资源——在析构函数中处理

CSlideBmpView::~CSlideBmpView()
{//在析构中回收内存资源m_bufferBmp.DeleteObject();m_bufferDC.DeleteDC();m_img.~CImage();
}

四、免费资源下载

点击下载项目工程及源代码

欢迎对MFC感兴趣的朋友和我交流,结识志同道合的朋友是我的荣幸(^_^)

【VC++游戏开发#二】2D篇 —— 平滑的幻灯片放映效果相关推荐

  1. 《C++游戏开发》笔记十一 平滑动画:不再颤抖的小雪花

    本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9430645 作者:七十一雾央 新浪微博:http:// ...

  2. 游戏开发心得——书籍篇——《游戏引擎框架》-导论

    游戏开发心得--书籍篇--<游戏引擎框架>-导论 FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: 学习<游戏引擎框架> ...

  3. 游戏开发面试答案篇(一)-- C++篇​

    游戏开发程序岗面试题答案版C++篇,后续继续更新游戏逻辑篇.unity篇.图形学篇,并整理成文档,可在公号[游戏君五尘]获取 原文链接 游戏开发面试答案篇(一)-- C++篇​ 目录 一.基础语法 二 ...

  4. 游戏开发心得——书籍篇——《游戏引擎框架》-专业工具

    游戏开发心得--书籍篇--<游戏引擎框架>-专业工具 FOR THE SIGMA FOR THE GTINDER FOR THE ROBOMASTER 简介: 学习<游戏引擎框架&g ...

  5. Cocos2D手机游戏开发之优化篇

    Cocos2D手机游戏开发之优化篇 在这个手机游戏盛行已久的年代,一款产品想要博得更多用户的喜爱就要在细节上做得更加到位.而游戏的优化在这里面起到了非常关键的作用.试想下,一款画面和玩法都深受用户喜欢 ...

  6. 【Android游戏开发二十七】讲解游戏开发与项目下的hdpi 、mdpi与ldpi资源文件夹以及游戏高清版本的设置...

    今天一个开发者问到我为什么游戏开发要删除项目下的hdpi.mdpi和ldpi文件夹:下面详细给大家解答一下: 首先童鞋们如果看过我写的<[Android游戏开发二十一]Android os设备谎 ...

  7. 微信小游戏开发教程-2D游戏原理讲解

    微信小游戏开发教程-2D游戏原理讲解 原理 为了更加形象的描述,这里先上一张图: 背景 a. 首先,我们看到背景好像是一张无限长的图片在向下移动.实际则不然,这是一张顶部和底部刚好重叠的图片.这是一种 ...

  8. CutJS – 用于 HTML5 游戏开发的 2D 渲染引擎

    CutJS 是轻量级的,快速的,基于 Canvas 开发的 HTML5  2D 渲染引擎,可以用于游戏开发.它是开源的,跨平台的,与现代的浏览器和移动设备兼容.CutJS 提供了一个类似 DOM 树的 ...

  9. Spine 游戏开发的 2D

    Spine 是一款针对游戏开发的 2D 骨骼动画编辑工具. Spine 旨在提供更高效和简洁 的工作流程,以创建游戏所需的动画 在 Spine 中通过将图片绑定到骨骼上,然后再控制骨骼实现动画. 2D ...

最新文章

  1. 与servlet Api 的集成
  2. asp.net控件开发基础(1)
  3. python逐行读取json_如何用python读取json文件里指定的数据
  4. 06--JDBC各种连接方式的对比
  5. 44. Wildcard Matching 通配符匹配
  6. Win11系统怎样设置更改密码
  7. windows server2012 Hyper-V改进
  8. 卷积神经网络-感受野的定义
  9. linux下编译C++程序无法链接Mysql的问题
  10. c语言程序课程设计过程,C语言课程设计————写下流程图! 谢谢
  11. java 列表对话框
  12. HDOJ--1864--最大报销额
  13. 剑指 Offer 07. 重建二叉树(day02)
  14. Ubuntu安装ssh服务详细过程
  15. html lab颜色,颜色标准LAB值对照表
  16. java俄罗斯方块七中图形类_shell脚本俄罗斯方块--代码真正详解
  17. Spring IOC refresh()方法——告诉子类刷新内部bean工厂
  18. 微信点击链接或者扫描二维码通过默认浏览器打开指定链接是如何实现的
  19. 入门级蛋白磷酸化研究
  20. 陈旭数据科学与计算机学院,数据科学与计算机学院硕士研究生招生专业及各专业导师...

热门文章

  1. 前端基础知识--顶置
  2. 触发器在计算机中的作用,施密特触发器的作用_施密特触发器的典型应用
  3. bzoj4247: 挂饰(背包dp)
  4. 服务器处理蜘蛛抓取网页的过程,让你网站快速被蜘蛛抓取的十三个方法
  5. EEPROM的学习和使用方法
  6. 关于EasyPoi导出Excel公式Cell不计算的问题
  7. 电脑桌面的回收站不见了,怎么找回
  8. 基于java的摄影爱好者交流网站
  9. 学术-数学:牟合方盖
  10. Unitimes三周年完美落幕,快来领取您的奖品吧!