对程序添加系统托盘图标支持-一个简单的C++封装

实现的关键是调用Windows Shell 的API Shell_NotifyIcon,该函数有两个参数,第一个参数指名操作类型,第二个参数是一个NOTIFYICONDATA结构,保存了操作相关的信息,比如图标,工具提示文本等等。关于该函数的详细情况可以在MSDN上查阅得知,这里不多叙述。

下面贴出类的实现代码,后面会有使用方法的介绍(这个Blog居然没有C++的Language Filter,太不爽了,暂时用Java的),

头文件

#ifnde f __CSYSTEMTRAY_H
#define __CSYSTEMTRAY_H

#include 
" shellapi.h "

#define WM_TRAY_MSG WM_USER 
+   0x01                    // 自定义消息,用以接收来自托盘的反馈
class  CSystemTray
{
public:
    CSystemTray(
void);
public:
    
~CSystemTray(void);
    
void Destroy();
    BOOL Create(HWND hParent, HICON hIcon, LPCTSTR szToolTip);  
//hParent 是接收WM_TRAY_MSG消息的窗口
    BOOL ModifyIcon(HICON hIcon);
    BOOL ModifyToolTipText(LPCTSTR szToolTip);
    BOOL ModifyBalloonText(LPCTSTR szTitle, LPCTSTR szInfo);
    BOOL ModifyBalloonIcon(HICON hIcon);
    BOOL SetFocus();
    
//BOOL AnimateIcon(HICON *pIconArray, UINT nSize, DWORD dwTimeInter);
private:
    
void Wait(int nSeconds);
    HWND m_hParent;
    HICON m_hIconTray, m_hIconBalloon;
    NOTIFYICONDATA m_nidSystemTray;
}
;

#endif

 

 实现:

 

#include  " SystemTray.h "

CSystemTray::CSystemTray(
void ):m_hParent(NULL), m_hIconTray(NULL), m_hIconBalloon(NULL)
{
    ::ZeroMemory(
&m_nidSystemTray, sizeof(NOTIFYICONDATA));
}


CSystemTray::
~ CSystemTray( void )
{
    Destroy();
}


BOOL CSystemTray::Create(HWND hParent, HICON hIcon, LPCTSTR szToolTip)
{
    m_hParent 
= hParent;
    

    
    m_nidSystemTray.cbSize 
= sizeof(NOTIFYICONDATA);
    m_nidSystemTray.hWnd 
= m_hParent;
    m_nidSystemTray.hIcon 
= m_hIconTray = hIcon;
    
    m_nidSystemTray.uFlags 
= NIF_ICON | NIF_MESSAGE;
    m_nidSystemTray.uCallbackMessage 
= WM_TRAY_MSG;
    
if (szToolTip)
    
{
        m_nidSystemTray.uFlags 
|= NIF_TIP;
        _tcscpy(m_nidSystemTray.szTip, szToolTip);
    }

    
return Shell_NotifyIcon(NIM_ADD, &m_nidSystemTray);
}


BOOL CSystemTray::ModifyIcon(HICON hIcon)
{
    ASSERT(m_nidSystemTray.hWnd 
!= NULL);
    m_nidSystemTray.hIcon 
= hIcon;
    m_nidSystemTray.uFlags 
= NIF_ICON;
    
return Shell_NotifyIcon(NIM_MODIFY, &m_nidSystemTray);
}


BOOL CSystemTray::ModifyToolTipText(LPCTSTR szToolTip)
{
    ASSERT(m_nidSystemTray.hWnd 
!= NULL);
    _tcscpy(m_nidSystemTray.szTip, szToolTip);
    m_nidSystemTray.uFlags 
= NIF_TIP;
    
return Shell_NotifyIcon(NIM_MODIFY, &m_nidSystemTray);
}


BOOL CSystemTray::ModifyBalloonText(LPCTSTR szTitle, LPCTSTR szInfo)
{
    ASSERT(m_nidSystemTray.hWnd 
!= NULL);
    _tcscpy(m_nidSystemTray.szInfoTitle, szTitle);
    _tcscpy(m_nidSystemTray.szInfo, szInfo);
    m_nidSystemTray.hIcon 
= m_hIconBalloon;
    m_nidSystemTray.uFlags 
= NIF_INFO | NIF_ICON;
    BOOL bRet 
= Shell_NotifyIcon(NIM_MODIFY, &m_nidSystemTray);

    
if (bRet)
    
{
        m_nidSystemTray.hIcon 
= m_hIconTray;
        m_nidSystemTray.uFlags 
= NIF_ICON;
     
return Shell_NotifyIcon(NIM_MODIFY, &m_nidSystemTray);
    }

    
else return FALSE;
}


BOOL CSystemTray::ModifyBalloonIcon(HICON hIcon)
{
    m_nidSystemTray.dwInfoFlags 
= NIIF_USER;
    
    m_nidSystemTray.hIcon 
= m_hIconBalloon = hIcon;
    
    m_nidSystemTray.uFlags 
= NIF_INFO | NIF_ICON;
    BOOL bRet 
= FALSE;
    bRet 
= Shell_NotifyIcon(NIM_MODIFY, &m_nidSystemTray);
    
if (bRet)
    
{
        m_nidSystemTray.hIcon 
=m_hIconTray;
    
        m_nidSystemTray.uFlags 
= NIF_ICON;
    
        
return Shell_NotifyIcon(NIM_MODIFY, &m_nidSystemTray);
    }

    
else return FALSE;
}

BOOL CSystemTray::SetFocus()
{
    ASSERT(m_nidSystemTray.hWnd 
!= NULL);
    
return Shell_NotifyIcon(NIM_SETFOCUS, &m_nidSystemTray);
}

void  CSystemTray::Destroy()
{
    
if(m_nidSystemTray.hWnd != NULL)
    
{
        Shell_NotifyIcon(NIM_DELETE, 
&m_nidSystemTray);    
        ::ZeroMemory(
&m_nidSystemTray, sizeof(NOTIFYICONDATA));
    }

    m_hParent 
= NULL;
}

 

首先创建一个对话框程序,将上述文件添加至工程。

在xxxDlg.h(xxx是你的工程名)文件中,添加#include "systemtray.h",在类声明中定一个CSystemTray类型变量,比如m_stMyProg;

然后再对话框的实现文件OnInitDialog函数中添加以下代码

m_stMyProg.Create(m_hWnd,::LoadIcon(theApp.m_hInstance,MAKEINTRESOURCE(IDI_ACCEPT)), _T("This is a SystemTray example"));

其中IDI_ACCEPT是一个事先定义好的图标资源。

这样启动程序以后,我们就可以在托盘上看到相应的图标了

接下来在程序的任何位置调用ModifyIcon可以修改托盘的图标,调用ModifyToolTip可以修改托盘的工具提示(tooltip),调用ModifyBalloonIcon可以修改气球提示的图标,相应的,如果想调用系统默认图标可以调用函数::LoadStandardIcon。需要注意的是,气球提示只有在每次修改文本时才会出现,因此如果想立即看到修改图标的效果,请调用一次ModifyBalloonText。OK!

前面的头文件中定义了一个WM_TRAY_MSG消息,当鼠标经过托盘图标时该消息就会得到响应,其中消息相关的lParam参数表示鼠标的操作,比如在托盘处单击了一下鼠标左键,lParam就是一个WM_LBUTTONDOWN消息,可以根据此消息来创建上下文菜单,等等。

首先要在对话框的头文件中添加一个消息相应函数的声明


afx_msg LRESULT OnTrayMsg(WPARAM  wParam, LPARAM  lParam);

再在MFC的消息映射中添加 ON_MESSAGE(WM_TRAY_MSG, OnTrayMsg)


最后在对话框的实现文件中添加对该函数的实现

 

LRESULT CxxxxDlg::OnTrayMsg(WPARAM wParam, LPARAM lParam)
{
    
switch (lParam)
        
{
          
case WM_LBUTTONDOWN:
              
//do someting...
               break;
          
case WM_RBUTTONDOWN:
              
//then do another...
           ...


          
default:
            
break;
        }

    
return 0;
}

 

根据接收到的不同鼠标消息对其进行响应。


这个类写的还不够完整,以后会添加关于托盘鼠标动画的支持,等等。目前先到这里

2007.10.9     by  赵科进(GodBird)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值