900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > MFC和GDI+制作雪花飞舞小程序

MFC和GDI+制作雪花飞舞小程序

时间:2021-03-08 03:57:02

相关推荐

MFC和GDI+制作雪花飞舞小程序

基于CWnd对话框,利用GDI+和PNG素材实现雪花飞舞唯美场景小程序。程序技术简单,仅供新手参考学习使用。

先看疗效:

下面来说说程序原理吧:

工程:VS,MFC(对话框)工程。

窗口:主窗口宽高为0,主要接收菜单传来的消息。绘图窗口宽高为屏幕的宽高,主要绘制雪花。

元素:雪花种类共12种,GDI+绘制不同的资源图片到窗口上。

动作:动作有3种,左移动、右移动、下移动。

动作原理:绘图窗口有一个定时器Timer,定时器根据时间来判断是否需要加入新的雪花图片,图片随机。

程绘图原理

1.获取窗口DC。

2.创建位图、画刷。

3.随着TIMER,随机产生图像,同时定义好图像坐标与大小。

4.绘制图像到画刷中。

5.更新位图到窗口上。

用到的技术点:

窗口透明

WS_EX_TOPMOST(顶层)

WS_EX_LAYERED(透明异形)

WS_EX_TRANSPARENT(消息穿透)

窗口绘图

UpdateLayeredWindow();

GDI+:graphics.DrawImage、CDC 等。

托盘:Shell_NotifyIcon

菜单:TrackPopupMenu

关键代码与实现:

注册窗口类

WNDCLASS wndcls;memset(&wndcls, 0, sizeof(WNDCLASS));wndcls.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW;wndcls.lpfnWndProc = ::DefWindowProc;wndcls.hInstance = AfxGetInstanceHandle();wndcls.hIcon = NULL;wndcls.hCursor = ::LoadCursor(NULL,IDC_ARROW);wndcls.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);wndcls.lpszMenuName = NULL;wndcls.lpszClassName = lpszClassName;if(!AfxRegisterClass(&wndcls)){return FALSE;}

窗口透明异形

int nWidth = GetSystemMetrics (SM_CXSCREEN);int nHeight = GetSystemMetrics (SM_CYSCREEN);DWORD dwExStyle = WS_EX_TOOLWINDOW | WS_EX_TOPMOST | WS_EX_LAYERED | WS_EX_TRANSPARENT;DWORD dwStyle = WS_POPUP | WS_VISIBLE | WS_SYSMENU;m_pSnowWnd = new CSnowWnd;BOOL bRes = m_pSnowWnd->CreateEx(dwExStyle, _T("CSnowWnd"), _T("Snow"), dwStyle, 0, 0, nWidth, nHeight, m_hWnd, NULL);m_pSnowWnd->ShowWindow(SW_SHOW);

创建画刷

void CSnowWnd::MakeBkgndDC(){CDC *pDC = GetDC();CBitmap hBackground;hBackground.CreateCompatibleBitmap(pDC, m_rcWnd.Width(), m_rcWnd.Height());if(m_dcBack.m_hDC == NULL)m_dcBack.CreateCompatibleDC(pDC);CBitmap *pOldBmp = m_dcBack.SelectObject(&hBackground);pOldBmp->DeleteObject();hBackground.DeleteObject();ReleaseDC(pDC);}

雪花位置、大小、移动数据的产生

void CSnowWnd::DownSnow(){DWORD dwRes = 0;for(int i = m_nImgCount - 1; i >= 0; i--){PIMG pImage = m_ImgDrawSto[i];pImage->Y+= pImage->nSpeed;//下移if(pImage->Y > m_rcWnd.Height())//超出{m_ImgDrawSto.RemoveAt(i);//移除delete pImage;continue;}if(dwRes == 0)dwRes = GetTickCount() - pImage->dwTickCount;//横向移动 if (pImage->Init){pImage->Init = FALSE;pImage->StepTpye = GetRand(1, 3);}switch (pImage->StepTpye){case 1:pImage->X--;break;case 2:pImage->X++;break;}}m_nImgCount = m_ImgDrawSto.GetCount();if(dwRes > 1800)//增加雪花时间控制AddSnow(GetRand(0, m_nRowMaxCount));DrawWnd();}

绘图

void CSnowWnd::DrawWnd(){MakeBkgndDC();CDC * pDC = GetDC();Graphics g(m_dcBack.GetSafeHdc());for(int i=0;i<m_nImgCount;i++){PIMG pImage = m_ImgDrawSto[i];g.DrawImage(pImage->pImage, pImage->X, pImage->Y, pImage->Width, pImage->Height);}CPoint DestPt(0,0);CSize psize(m_rcWnd.Width(),m_rcWnd.Height());BLENDFUNCTION blend;blend.AlphaFormat = AC_SRC_ALPHA;blend.BlendFlags = 0;blend.BlendOp = AC_SRC_OVER;blend.SourceConstantAlpha = 255;UpdateLayeredWindow(pDC, NULL, &psize, &m_dcBack, &DestPt, 0, &blend, ULW_ALPHA);ReleaseDC(pDC);}

好了,主要的代码已经贴出来,如有疑问可以留言。

源程序下载链接:

/detail/xinsuiyishunjian/9587916

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。