用一个Timer,定时去换图标。有这个例子,找找看。

解决方案 »

  1.   

    用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);
    }
      

  2.   

    在你需要改变图标的时候,控制一下LoadIcon就成了。