387上位机VC MFC实现桌面爬行昆虫特效
实现桌面爬行昆虫特效
功能展示
QQ聊天时,会在桌面显示非常逼真的表情特效,我们在学习上位机编程时看到这一特效也会想实现这一功能,用来捉弄朋友,当前例程就实现了这一功能,效果如图,运行例程会在桌面显示一只苍蝇爬行,在桌面右下脚可右键例程的图标进行苍蝇,蝴蝶的添加,清除操作;
要点提示
例程是通过GDI+编写一个基于对话框的自定义类CFlyDlg来实现桌面昆虫的爬行特效,类的使用很简单,只有两个对外的公共成员函数即构造函数CFlyDlg()及显示函数Show().构造一个对话对象后调用Show()显示窗口便可,如代码:CFlyDlg *pDlg = new CFlyDlg(); pDlg->Show(nFlyType,pFlyImage,nStepS);
在类中有两个函数要注意,一个是OnMouseLeave() 一个是OnMouseHover();
默认情况下,窗口是不响应 WM_MOUSELEAVE 和 WM_MOUSEHOVER 消息的,所以要使用 _TrackMouseEvent 函数来激活这两个消息。调用这个函数后,当鼠标在指定窗口上停留超过一定时间或离开窗口后,该函数会 Post 这两个消息到指定窗口。
具体使用方法:
1.添加函数的申明,定义 及与消息WM_MOUSEHOVER, WM_MOUSELEAVE的关联
afx_msg LRESULT OnMouseHover(WPARAM wParam, LPARAM lParam);
afx_msg LRESULT OnMouseLeave(WPARAM wParam, LPARAM lParam);
ON_MESSAGE( WM_MOUSEHOVER, OnMouseHover )
ON_MESSAGE( WM_MOUSELEAVE, OnMouseLeave )
2.添加一变量 BOOL m_bTracking;初初始化为FALSE; 之所以要添加这变量主要是避免鼠标已经在窗体之上时,一移动鼠标就不断重复产生 WM_MOUSEHOVER;
然后在鼠标移动函数OnMouseMove?()调用_TrackMouseEvent?()函数,代码如下
void CFlyDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_bTracking)
{
//鼠标移入窗时,请求WM_MOUSEHOVER和WM_MOUSELEAVE 消息
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.hwndTrack = m_hWnd;
tme.dwFlags = TME_LEAVE|TME_HOVER;
tme.dwHoverTime = 1;
m_bTracking = _TrackMouseEvent(&tme);//成功返回非0值
}
CDialog::OnMouseMove(nFlags, point);
}
3.最后就可以在鼠标悬浮移出函数中再次赋值变量m_bTracking
LRESULT CFlyDlg::OnMouseHover(WPARAM wParam, LPARAM lParam)
{
m_bTracking = TRUE;
return TRUE;
}
LRESULT CFlyDlg::OnMouseLeave(WPARAM wParam, LPARAM lParam)
{
m_bTracking = FALSE;
return TRUE;
}
实现功能
1.新建基于对话框的应用程序
2.将例程根目录中GDI+文件夹Include,图片文件夹res\ Butterfly,res\ Fly及自定义的类文件FlyDlg.cpp, FlyDlg.h复制到自己的工程根目录,并将两文件包加载到工程中;
3.依照例程将前面的图片添加到工程中,注意图片ID的修改,图片很多,嫌麻烦可直接复制例程图片ID到自己工程。再添加一对话框资源,ID修改为IDD_FLYDLG,去除边框,用来显示各种昆虫。再添加一菜单资源IDR_TRAY_MENU,添加几个菜单项,用来显示托盘菜单实现昆虫操作退出程序等;
4.三步取实现GDI+环境的初始化:在stdafx.h包含头文件
//使用GDI+第一步
#define UNICODE
#ifndef ULONG_PTR
#define ULONG_PTR unsigned long*
#endif
#include "Include\\gdiplus.h"
using namespace Gdiplus;
#pragma comment(lib, "Include\\gdiplus.lib")
在APP类InitInstance()初始化GDI+环境及程序退出时清除
//GDI+第二步
ULONG_PTR diplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&diplusToken, &gdiplusStartupInput, NULL);
//GDI+第三步
GdiplusShutdown(diplusToken);
4.在主对话框类头文件添加头文件,源文件中添加全部变量
#include"Afxtempl.h"
#include "FlyDlg.h"
#define WM_SHOWMENU (WM_USER + 0x100) //托盘消息
Image *g_pFly[20][10]; //16组苍蝇图片,最大[16][6]
int g_nStep[20][10];//16种走法,最大[8][2] 0X递进,1Y递进
Image *g_pButterFly[20][10]; //18组蝴蝶图片,最大[18][8]
int g_nButterStep[20][10];//18种走法,最大[18][8] 0X递进,1Y递进
5.在主对话框中添加一成员变量CArray<CFlyDlg*, CFlyDlg*>m_pFlyWndSto; 添加托盘菜单的显示函数OnShowTrayMenu ()(手动实现及WM_SHOWMENU 的关联),清除函数ClearTrayMenu();图片ID转为Image指针函数ImageFromResource();添加昆虫的函数AddInsect()
LRESULT CGkbc8Dlg::OnShowTrayMenu(WPARAM wParam,LPARAM lParam)
{
if(wParam!=IDR_MAINFRAME)
return 1;
switch(lParam)
{
case WM_RBUTTONUP: //右键起来时弹出快捷菜单
{
LPPOINT lpoint=new tagPOINT;
::GetCursorPos(lpoint); //得到鼠标位置
CMenu menu, *pPopup;
menu.LoadMenu(IDR_TRAY_MENU);
pPopup = menu.GetSubMenu(0);
pPopup->SetDefaultItem(0,TRUE);
pPopup->TrackPopupMenu(TPM_LEFTALIGN,lpoint->x,lpoint->y,this);
//资源回收
HMENU hmenu=menu.Detach();
menu.DestroyMenu();
delete lpoint;
}
break;
case WM_LBUTTONDBLCLK: //双击左键的处理
{
}
break;
default:
break;
}
return 0;
}
void CGkbc8Dlg::ClearTrayMenu()
{
NOTIFYICONDATA nid;
nid.cbSize=(DWORD)sizeof(NOTIFYICONDATA);
nid.hWnd=this->m_hWnd;
nid.uID=IDR_MAINFRAME;
nid.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP ;
nid.uCallbackMessage=WM_SHOWMENU;//自定义的消息名称
nid.hIcon=LoadIcon(AfxGetInstanceHandle(),MAKEINTRESOURCE(IDR_MAINFRAME));
wcscpy((unsigned short *)nid.szTip,(unsigned short *)_T("Fly On Desktop")); //信息提示条为“计划任务提醒”
Shell_NotifyIcon(NIM_DELETE,&nid); //在托盘区删除图标
}
Image* CGkbc8Dlg::ImageFromResource(UINT nID, LPCTSTR lpType)
{
Image* pImage = NULL;
HINSTANCE hInst = AfxGetResourceHandle();
HRSRC hRsrc = ::FindResource (hInst,MAKEINTRESOURCE(nID), lpType); // type
if (!hRsrc)
return NULL;
// load resource into memory
DWORD len = SizeofResource(hInst, hRsrc);
BYTE* lpRsrc = (BYTE*)LoadResource(hInst, hRsrc);
if (!lpRsrc)
{
CString sTemp;
sTemp.Format(_T("未找到所需的资源文件(%d)。"), nID);
AfxMessageBox(sTemp);
return FALSE;
}
// Allocate global memory on which to create stream
HGLOBAL hMem = GlobalAlloc(GMEM_FIXED, len);
BYTE* pmem = (BYTE*)GlobalLock(hMem);
memcpy(pmem,lpRsrc,len);
GlobalUnlock(hMem);
IStream* pstm;
CreateStreamOnHGlobal(hMem,FALSE,&pstm);
// load from stream
pImage=Gdiplus::Image::FromStream(pstm);
// free/release stuff
pstm->Release();
FreeResource(lpRsrc);
GlobalFree(hMem);
return pImage;
}
BOOL CGkbc8Dlg::AddInsect(int nFlyType,Image *pFlyImage[20][10],int nStepS[20][10])
{
CFlyDlg *pDlg = new CFlyDlg();
m_pFlyWndSto.Add(pDlg);
return pDlg->Show(nFlyType,pFlyImage,nStepS);
}
6.在主对话框初始化函数OnInitDialog()中初始化变量,并关联托盘菜单的菜单项点击函数,具体代码过长,不复制出来,可参阅例程
我们来演示下功能实现的整个过程
如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!
|