window MFC桌面下雪程序

刚接触MFC没多久,很多知识学过就忘,所以急需写一个小程序来巩固下知识,从小就喜欢雪花,喜欢在大雪中奔跑,喜欢大雪中两人手牵手的浪漫。如果能写个桌面下雪程序既是对雪花的喜爱也能练练window下的编程岂不是两全其美。

说做就做,让我们一起来完成一个漂亮的雪花程序

首先分析下程序,屏幕下雪大致可以分为以下步骤

1、创建雪花类,初始化雪花

2、在OnPaint()函数中绘制雪花

3、在定时器OnTimer()中更新雪花位置等数据,重绘桌面

这样每次刷新雪花的x,y轴,每次重绘桌面就会看到一个下雪的动作


以下为具体步骤:

我使用的是VS2008环境,首先创建一个单文档项目


然后创建一个雪花类SnowFlower

class SnowFlower
{
public:
	SnowFlower(void);
	~SnowFlower(void);

public :
	int SnowType;//雪花类型
	int x;//x位置
	int y;//y位置
	
	
};

让背景为桌面,去掉window默认的窗口

修改MainFrm.cpp中PreCreateWindow函数

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: 在此处通过修改
	
	
	
	if(cs.hMenu!=NULL){       
            ::DestroyMenu(cs.hMenu);  
            cs.hMenu = NULL;  
        }   
	cs.x=0;   //改变初始位置   
        cs.y=0;   

	//全屏
	int nFullWidth = GetSystemMetrics(SM_CXSCREEN);
	int nFullHeight = GetSystemMetrics(SM_CYSCREEN);

	cs.cx = nFullWidth;
	cs.cy = nFullHeight;
	//去掉边框
	cs.style=WS_POPUP;
	cs.dwExStyle = WS_EX_TOPMOST;
	return TRUE;
}

这样程序的窗口和边框都被隐藏,而且窗口大小为全屏模式


我们 需要在View中绘图,打开xxxxxxxView类

定义一个雪花数宏

#define SNOW_COUNT  200

定义一个雪花数组

SnowFlower sf[SNOW_COUNT];

添加初始化雪花代码

void CSnowTestView::InitSnowFlower(void)
{
	

	for(int i=0;i<SNOW_COUNT;i++){
		sf[i].x = 30+i*10;
		sf[i].y = rand()%500;
		int typesRand = rand()%100;
		if(typesRand<3){
			sf[i].SnowType = 6;
		}else if(typesRand>=3 && typesRand<8){
			sf[i].SnowType = 5;
			
		}else if(typesRand>=8 && typesRand<13){
			sf[i].SnowType = 4;
			
		}else if(typesRand>=13 && typesRand<20){
			sf[i].SnowType = 3;
			
		}else if(typesRand>=20 && typesRand<50){
			sf[i].SnowType = 2;
			
		}else if(typesRand>=70 && typesRand<101){
			sf[i].SnowType = 1;
			
		}
		
	}

	
}

在类视图中点击xxxxxView,在属性中添加对WM_TIMER的消息相应

void CSnowTestView::OnTimer(UINT_PTR nIDEvent)
{
	for(int i=0;i<SNOW_COUNT;i++){


		if(sf[i].y>760){
			sf[i].y = 0;
			sf[i].x = rand()%1000;
		}
		

		int snowType = sf[i].SnowType;
		switch(snowType){
		
			case 1:
				sf[i].y += 1;
				sf[i].x +=1;
				break;
			case 2:

				sf[i].y += 2;
				sf[i].x +=2;
				break;
			case 3:

				sf[i].y += 3;
				sf[i].x +=1;
				break;
			case 4:

				sf[i].y += 4;
				sf[i].x +=1;
				break;
			case 5:

				sf[i].y += 5;
				sf[i].x +=1;
				break;
			case 6:

				sf[i].y += 8;
				sf[i].x +=2;
				break;
		
		}
		
	}
	
	Invalidate();
	
	CView::OnTimer(nIDEvent);
}


添加对WM_PAINT(绘图)消息的相应
void CSnowTestView::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
	CDC MemDc;
	MemDc.CreateCompatibleDC(&dc);
	CBitmap bg_bitmap;
	bg_bitmap.LoadBitmap(IDB_BITMAP1);
	MemDc.SelectObject(&bg_bitmap);

	CBrush brush;
	brush.CreateSolidBrush(RGB(255,255,255));
	MemDc.SelectObject(&brush);
	
	for(int i=0;i<SNOW_COUNT;i++){
		int snowType = sf[i].SnowType;
		switch(snowType){
		
			case 1:
				MemDc.Ellipse(sf[i].x,sf[i].y,sf[i].x+6,sf[i].y+6);
				break;
			case 2:

				MemDc.Ellipse(sf[i].x,sf[i].y,sf[i].x+9,sf[i].y+9);
				break;
			case 3:

				MemDc.Ellipse(sf[i].x,sf[i].y,sf[i].x+13,sf[i].y+13);
				break;
			case 4:

				MemDc.Ellipse(sf[i].x,sf[i].y,sf[i].x+17,sf[i].y+17);
				break;
			case 5:

				MemDc.Ellipse(sf[i].x,sf[i].y,sf[i].x+21,sf[i].y+21);
				break;
			case 6:

				MemDc.Ellipse(sf[i].x,sf[i].y,sf[i].x+25,sf[i].y+25);
				break;
			
		
		}
		
		
	}
	
	
	dc.BitBlt(0,0,1370,770,&MemDc,0,0,SRCCOPY );

<span style="white-space:pre">	</span>MemDc.DeleteDC();
}

为了让程序播放音乐,点开资源,添加资源选择*.wav文件

添加音乐播放函数PlayMusic(),

需要加入以下文件头和库

#include "mmsystem.h"
#pragma comment(lib,"WINMM.LIB")
#pragma comment(lib,"msimg32.lib")

void CSnowTestView::PlayMusic(void)
{
	PlaySound(MAKEINTRESOURCE(IDR_WAVE1),AfxGetResourceHandle(),SND_RESOURCE|SND_ASYNC|SND_LOOP);

}


为了让程序一启动就开始运行,在view中重写OnInitialUpdate方法添加调用雪花初始化函数,定时器函数等

void CSnowTestView::OnInitialUpdate()
{
	InitSnowFlower();
	SetTimer(1,30,NULL);
	PlayMusic();
	CView::OnInitialUpdate();

	// TODO: 在此添加专用代码和/或调用基类
}
以上代码程序已经可以跑起来了,看到桌面飘舞的雪花是不是非常兴奋呢?

为了程序更加完善,我们还可以为程序添加一个托盘

1、打开MainFrm.cpp

2、添加一个NOTIFYICONDATA成员变量 m_nid;

3、声明一个消息响应函数 afx_msg void onShowTask(WPARAM wParam,LPARAM IParam);

LRESULT CMainFrame::onShowTask(WPARAM wParam,LPARAM lParam) {
<span style="white-space:pre">	</span>//wParam接收的是图标的ID,lParam接收的是鼠标的行为 
	if(IDI_ICON1 != wParam){
	
		return 1;
	}
	switch(lParam){ 
		case WM_RBUTTONUP://右键起来时弹出快捷菜单
		{   
			LPPOINT lpoint=new tagPOINT; 
			::GetCursorPos(lpoint);//得到鼠标位置 
			CMenu menu; 
			menu.LoadMenu(IDR_MENU1);
			CMenu* pPopup = menu.GetSubMenu(0);
			//pPopup->CheckMenuItem(ID_32777,MF_BYCOMMAND | MF_CHECKED);
			SetForegroundWindow(); 
			pPopup->TrackPopupMenu(TPM_LEFTALIGN| TPM_RIGHTBUTTON,lpoint->x,lpoint->y,this); 
			
				
			//资源回收 
			HMENU hmenu=menu.Detach(); 
			menu.DestroyMenu(); 
			delete pPopup;
			delete lpoint; 


			
		   } 
		   break; 
		case WM_LBUTTONDBLCLK://双击左键的处理 
		   {     
			   SendMessage(WM_YHMESSAGE1);
			  
		   } 
		   break; 
	} 
return 0; 

}

4、定义一个自定义消息 #define WM_SHOWTASK  WM_USER+1

5、在BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)和END_MESSAGE_MAP()之间添加 ON_MESSAGE(WM_SHOWTASK,onShowTask)注册信息

6、添加ToTray()方法初始化m_nid

void CMainFrame::ToTray(void)
{
	
	m_nid.cbSize = (DWORD)sizeof(NOTIFYICONDATA); 
	m_nid.hWnd = this->m_hWnd; 
	m_nid.uID = IDI_ICON1;  //应用程序定义的该图标的ID号
	m_nid.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; 
	m_nid.uCallbackMessage = WM_SHOWTASK; //自定义消息
	m_nid.hIcon = LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDI_ICON1));
	wcscpy(m_nid.szTip,_T("雪花尽情的飘舞吧"));  
	Shell_NotifyIcon(NIM_ADD,&m_nid);//在托盘区添加图标 
}


效果图:








程序下载地址:http://pan.baidu.com/s/1o63I1yM





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值