转贴:   →电脑→程序设计→C/C++/VC/BC→ 
  
  
  用MFC实现系统任务栏的小图标 
  
杭州十三湾巷 
俞巍 
  如果我们在程序最小化时采用在系统任务栏中的小图标,就象金山词霸一样,单击左键可以实现最大最小化,单击右键有快捷菜单,那么整个程序会显的很简洁。采用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); 
}  
 
特别感谢『九头鸟』自发编辑『 dy 』| 相关讨论 | 文章录入 | 想作版主 
  
 
 
 
   
     
   
 (C)2000-2001版权所有
对本站有任何意见或建议以及其它版权问题请点击此处 
-==请将显示器分辨率设置为800*600或1024*768,推荐使用I4.x或以上浏览==- 
 
 太极链 - 509516  
江湖社区专用主机 ┏超酷下载组合┓  世和资讯  ●方竹网管软件●  电子文档处理器  非常吸引力  
聊天室专用主机 ●中国码头●  中国书生  无忧书库  网络与商务  文川阁