MFC和GDI+制作蝴蝶苍蝇飞舞小程序
2016-06-28 14:33
489 查看
看到网上有个老外写的蝴蝶飞舞程序,一时兴起,开发个功能相似的小程序。 实现功能:屏幕上有蝴蝶或苍蝇飞舞。素材是通过提取工具提取出来的。老外程序的网址记不清了。 程序原理比较简单,本文仅供新手学习参考用。
先看效果:
下面来说说程序原理吧:
工程:VS2005,MFC(对话框)工程。窗口:每个飞舞的元素(蝴蝶/苍蝇)各是一个窗口,这些窗口的父窗口是Desktop,这些窗口具有透明异形的属性,这些窗口的大小与元素大小相同,这些窗口随着元素的形状改变而变化。
元素:蝴蝶/苍蝇 随着动作的变化,GDI+也跟着绘制新的资源图片到窗口上。
动作:动作有2种,一种是元素自身的动作,即摆动翅膀飞舞、原地休息、原地摆动翅膀等动作。另一种动作是元素的移动,即元素在屏幕上任意方向飞舞移动。
动作原理:每个元素窗口都有一个定时器Timer,两种动作会根据自己的随机时间来选择随机的动作与运动方向。
元素动作类型:蝴蝶18种走法,苍蝇16种走法。分别是:不同的方向动作、原地动作。
用到的技术点:
窗口透明:SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000);
窗口异形:
UpdateLayeredWindow(pDC, &ptWinPos, &sizeWindow, &m_dcBack, &ptSrc, 0, &m_Blend, 2);
GDI+:graphics.DrawImage、CDC 等。
托盘:Shell_NotifyIcon
菜单:TrackPopupMenu
关键代码与实现:
窗口透明设置:ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW,0); //变窗口为透明类型 DWORD dwExStyle=GetWindowLong(m_hWnd,GWL_EXSTYLE); if((dwExStyle&0x80000)!=0x80000) SetWindowLong(m_hWnd,GWL_EXSTYLE,dwExStyle^0x80000);
创建画刷:
void CFlyWnd::MakeBkgndDC() { CRect rtClient; GetClientRect(&rtClient); CDC *pDC = GetDC(); CBitmap hBackground; hBackground.CreateCompatibleBitmap(pDC,rtClient.Width(),rtClient.Height()); if(m_dcBack.m_hDC == NULL) { m_dcBack.CreateCompatibleDC(pDC); } CBitmap *pOldBmp = m_dcBack.SelectObject(&hBackground); pOldBmp->DeleteObject(); hBackground.DeleteObject(); ReleaseDC(pDC); }
动作产生后,更新画刷:
void CFlyWnd::UpdateMemoDC() { MakeBkgndDC(); CRect rcClient; GetWindowRect(&rcClient); CDC * pDC = GetDC(); if(m_dcBack.GetSafeHdc() == NULL) return; Gdiplus::Graphics graphics(m_dcBack.GetSafeHdc()); if(m_nInectType == 0) { RectF rtGdiplus(0,0,m_InectSize.cx, m_InectSize.cy); //画刷新图标 graphics.DrawImage(g_pFly[m_nIndex[0]][m_nIndex[1]], rtGdiplus, 0, 0, m_InectSize.cx, m_InectSize.cy, UnitPixel); POINT ptWinPos = {rcClient.left, rcClient.top}; SIZE sizeWindow={m_InectSize.cx, m_InectSize.cy};//图片尺寸 POINT ptSrc={0,0}; UpdateLayeredWindow(pDC, &ptWinPos, &sizeWindow, &m_dcBack, &ptSrc, 0, &m_Blend, 2); }else if(m_nInectType ==1) { RectF rtGdiplus(0,0,m_InectSize.cx, m_InectSize.cy); //画刷新图标 graphics.DrawImage(g_pButterFly[m_nIndex[0]][m_nIndex[1]], rtGdiplus, 0, 0, m_InectSize.cx, m_InectSize.cy, UnitPixel); POINT ptWinPos = {rcClient.left, rcClient.top}; SIZE sizeWindow={m_InectSize.cx, m_InectSize.cy};//图片尺寸 POINT ptSrc={0,0}; UpdateLayeredWindow(pDC, &ptWinPos, &sizeWindow, &m_dcBack, &ptSrc, 0, &m_Blend, 2); } ReleaseDC(pDC); }
动作的控制:
//由于此部分代码量比较大,请下载源程序参阅 SetTimer(1, m_nElapse, NULL); .... void CFlyWnd::OnTimer(UINT nIDEvent) { if(m_nInectType == 0) {//苍蝇 Step(); }else if(m_nInectType == 1) {//蝴蝶 ButterflyStep(); } } void CFlyWnd::UpdateFlyPos(CRect rcNewPos) { MoveWindow(&rcNewPos, FALSE); }
源程序下载链接:
http://download.csdn.net/detail/xinsuiyishunjian/9561944相关文章推荐
- C#常用GDI+文字操作汇总
- Visual C++中MFC消息的分类
- MFC中Radio Button的用法详解
- MFC对话框中添加状态栏的方法
- MFC创建右键弹出菜单的方法
- MFC中动态创建控件以及事件响应实现方法
- C++ 关于MFC多线程编程的注意事项
- MFC程序对文件的处理方法
- MFC自定义消息的实现方法
- MFC实现在文件尾追加数据的方法
- MFC之ComboBox控件用法实例教程
- MFC绘制不规则窗体的方法
- IE8引发 VS2005/2008 MFC向导出错的解决方案
- C#利用GDI+绘制旋转文字等效果实例
- MFC实现全屏功能代码实例
- 使用VS2010创建MFC ActiveX工程项目
- C++中MFC Tab Control控件的使用详解
- MFC程序设计常用技巧汇总
- MFC扩展DLL中导出类和对话框的实现方法
- VC中SDK与MFC的区别浅析