用一个Timer,定时去换图标。有这个例子,找找看。
解决方案 »
- MFC中的CListCtrl控件,怎么获取选中项的名称
- 找不到WTS APIS枚举进程用户名的具体资料
- 买Visual.C++.6.0编程实例与技巧 王华写的
- 请推荐最好的网络抓包工具,我要分析一个程序所有的网络IO,应该怎么办呢
- IHtmlDocument2的get_body方法的问题
- 紧急求救:在视图类中添加对话框类后,程序如何响应对对话框类的消息
- 列位老大帮帮忙啊!求你们了!
- 请问如何改密码,十分谢谢
- 高分请教!(VC+ACESS2000,Ado)如何动态的获得表中的所有字段名字,以及如何动态的获得数据库中的所有表的名字
- 请教各位大侠,怎么样把*.gif,和*.jpg图象转换成*.bmp!(特急)
- 波波进来领分!
- 手机短消息的结构和组成
杭州十三湾巷
俞巍
如果我们在程序最小化时采用在系统任务栏中的小图标,就象金山词霸一样,单击左键可以实现最大最小化,单击右键有快捷菜单,那么整个程序会显的很简洁。采用SDK的Shell_NotifyIcon等API可以实现系统任务栏的小图标,但是程序员必须仔细理解这些API的具体用法,Chris Maunder ([email protected])开发的系统任务栏类CSystemTray封装了这些API的功能,使MFC程序员可以方便的实现具有系统任务栏小图标的程序。 CsytemTray的功能很多,看一看它的成员函数就可以知道其大致功能了。 BOOL Enabled() { return m_bEnabled; }
BOOL Visible() { return !m_bHidden; }
//Create the tray icon
Create(CWnd* pWnd, UINT uCallbackMessage,
LPCTSTR szTip, HICON icon, UINT uID);
//Change or retrieve the Tooltip text
BOOL SetTooltipText(LPCTSTR pszTooltipText);
BOOL SetTooltipText(UINT nID);
CString GetTooltipText() const;
//Change or retrieve the icon displayed
BOOL SetIcon(HICON hIcon);
BOOL SetIcon(LPCTSTR lpIconName);
BOOL SetIcon(UINT nIDResource);
BOOL SetStandardIcon(LPCTSTR lpIconName);
BOOL SetStandardIcon(UINT nIDResource);
HICON GetIcon() const;
void HideIcon();
void ShowIcon();
void RemoveIcon();
void MoveToRight();
//Change or retrieve the window to
send notification messages to
BOOL SetNotificationWnd(CWnd* pNotifyWnd);
CWnd* GetNotificationWnd() const;
下面是实现步骤:
(1〕首先在Project中加入CsystemTray类的.cpp和.h文件,这样在Workspace的ClassView中可以看到CsystemTray类。 (2)然后在CframeWnd的派生类的头文件中加入WM_ICON_NOTIFY 的消息定义 #define WM_ICON_NOTIFY WM_USER+1 在CframeWnd的派生类中添加变量 CSystemTray m_TrayIcon;在CframeWnd的派生类的CPP文件中添加消息映射 BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
... ...
ON_MESSAGE(WM_ICON_NOTIFY, OnTrayNotification)
END_MESSAGE_MAP()
(3)在CframeWnd的派生类中添加成员函数
LRESULT CMainFrame::OnTrayNotification
(WPARAM wParam, LPARAM lParam)
{
return m_TrayIcon.OnTrayNotification
(wParam, lParam);
}
(4)定义快捷菜单
在MENU中添加新菜单IDR_POPUP_MENU,可以如一般的菜单一样从ClassWizard中定义其响应。 (5)在CsystemTray中修改OnTrayNotification函数,定义你希望实现的效果,如单击左键可以实现最大最小化,单击右键有快捷菜单等功能。 LRESULT CSystemTray::OnTrayNotification
(UINT wParam, LONG lParam)
{
//Return quickly if its not for
this tray icon
if (wParam != m_tnd.uID)
return 0L; CMenu menu, *pSubMenu;//定义单击右键有快捷菜单
if (LOWORD(lParam) == WM_RBUTTONUP)
{
if (!menu.LoadMenu(m_tnd.uID))
return 0;
if (!(pSubMenu =
menu.GetSubMenu(0))) return 0;// Make first menu item the default (bold font)
::SetMenuDefaultItem(pSubMenu- >m_hMenu, 0, TRUE); //Display and track the popup menu
CPoint pos;
GetCursorPos(&pos); ::SetForegroundWindow(m_tnd.hWnd);
::TrackPopupMenu(pSubMenu->m_hMenu, 0, pos.x,
pos.y, 0, m_tnd.hWnd, NULL); // BUGFIX: See "PRB: Menus for Notification
Icons Don't Work Correctly"
::PostMessage(m_tnd.hWnd, WM_NULL, 0, 0); menu.DestroyMenu();
}
//定义双击左键有产生单击快捷菜单第一项功能的响应
else if (LOWORD(lParam) == WM_LBUTTONDBLCLK)
{
if (!menu.LoadMenu(m_tnd.uID)) return 0;
if (!(pSubMenu = menu.GetSubMenu(0))) return 0; // double click received, the default action
is to execute first menu item
::SetForegroundWindow(m_tnd.hWnd);
::SendMessage(m_tnd.hWnd, WM_COMMAND,
pSubMenu->GetMenuItemID(0), 0); menu.DestroyMenu();
}
//定义单击左键为最小化或恢复窗口
else if (LOWORD(lParam) == WM_LBUTTONUP)
{if(AfxGetMainWnd()->IsIconic()!=0)
{EnableWindow(m_tnd.hWnd,TRUE);
ShowWindow(m_tnd.hWnd,SW_SHOW);
ShowWindow(m_tnd.hWnd,SW_RESTORE);
}
else
{ShowWindow(m_tnd.hWnd,SW_SHOWMINIMIZED);
EnableWindow(m_tnd.hWnd,FALSE);
ShowWindow(m_tnd.hWnd,SW_HIDE);
}
}
return 1;
}
(6)在CmainFrame的派生类中添加WM_SIZE的消息响应函数,这可以实现程序最小化时只在系统任务栏中有一个小图标,而不会在一般任务栏中有显示
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{ CFrameWnd::OnSize(nType, cx, cy);
if(nType==SIZE_MINIMIZED)
{EnableWindow(FALSE);
ShowWindow(SW_HIDE);
}
}
看起来似乎这样实现步骤也不少,但是当我们再开发新的功能时会很方便,程序会更容易理解与开发。如我们可以很方便实现动态小图标。我们只需在CmainFrame的派生类中添加一个定时器,
SetTimer(IDW_TIMER1,500,NULL);
icon_id=0;
对定时发出的WM_TIME消息进行处理,例如时间到了就换一个图标,图标的变化可以根据自己的喜好及实际情况定义,此处有3个图标轮流变化。
void CMainFrame::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler
code here and/or call default
//change the icon
//icon_id from 0 to 2 every 0.5s
if(nIDEvent ==IDW_TIMER1)
{if(icon_id==0)
{hIcon=AfxGetApp()->LoadIcon(IDR_ICON0);
icon_id++;
}
else if(icon_id==1)
{hIcon=AfxGetApp()->LoadIcon(IDR_ICON1);
icon_id++;
}
else if(icon_id=2)
{hIcon=AfxGetApp()->LoadIcon(IDR_ICON2);
icon_id=0;
}
m_TrayIcon.SetIcon(hIcon);
}
CFrameWnd::OnTimer(nIDEvent);
}