托盘技术主要涉及到一个结构体(NOTIFYICONDATA)和一个函数(Shell_NotifyIcon)。

NOTIFYICONDATA结构体包含系统需要用来传递托盘区域消息的信息。其原型如下:


 
 

   typedef struct _NOTIFYICONDATA {  
 
 
 
DWORD cbSize;   //一般是sizeof(NOTIFYICONDATA) 
 
 
 
HWND hWnd;     //窗体的句柄 
 
 
 
UINT uID; 
   //托盘的标识符 
 
 
 
UINT uFlags; 
   //托盘的样式 
 
 
 
UINT uCallbackMessage;    //托盘消息处理函数,需要事先定义好 
 
 
 
HICON hIcon; 
   //托盘的图标 
 
 
 
WCHAR szTip[64]; 
   //托盘的标题 
 
 
 

   } NOTIFYICONDATA, *PNOTIFYICONDATA;


Shell_NotifyIcon函数的作用是向任务栏托盘区域发送消息。其函数体为


BOOL Shell_NotifyIcon( DWORD dwMessage,PNOTIFYICONDATA lpdata);


 第一个参数dwMessage为输入参数,传递发送的消息,表明要执行的操作。可选的值有:


NIM_DELETE/ 
 NIM_ADD/ 
 NIM_MODIFY/ 
 NIM_SETFOCUS/ 
 NIM_SETVERSION


 第二个参数lpdata为输入参数,是指向NOTIFYICONDATA结构体的指针,结构体内容用来配合第一个参数wMessage进行图标操作。



下面是一个实例。


1、定义一个自定义消息


#define UM_TRAY_NOTIFY WM_USER + 1(stdAfx.h) 

 

      afx_msg LRESULT OnTrayNotify(WPARAM uID, LPARAM lEvent);(xxxx.h) 

 

      ON_MESSAGE(UM_TRAY_NOTIFY, OnTrayNotify)(xxxx.cpp) 

 

      LRESULT CFeiGeDlg::OnTrayNotify(WPARAM uID, LPARAM lEvent)(xxxx.cpp) 

 

  { 

 
//自定义消息函数,处理点击托盘消息 

 
if (uID == 100) 

 
{ 

 
switch (lEvent) 

 
{ 

 
case WM_RBUTTONUP: 

 
{ 

 
CPoint point; 

 
GetCursorPos(&point); 

 

 
CMenu trayMenu; 

 
trayMenu.LoadMenu(IDR_TRAY_MENU); 

 

 
trayMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, 

 
point.x, point.y, this); 

 
break; 

 
} 

 
case WM_LBUTTONDBLCLK: 

 
this->ShowWindow(SW_SHOW); 

 
this->SetForegroundWindow(); 

 
break; 

 
} 

 
} 

 
return 0; 

 

  } 

 
 
 
 

  2、在对话框类中添加三个函数 

 

   void CFeiGeDlg::TrayAdd() 
 
 
 

   { 
 
 
 
NOTIFYICONDATA nid =  
 
 
 
{ 
 
 
 
sizeof(NOTIFYICONDATA), 
 
 
 
this->m_hWnd, 
 
 
 
100, 
 
 
 
NIF_MESSAGE | NIF_ICON | NIF_TIP, 
 
 
 
UM_TRAY_NOTIFY, 
 
 
 
this->m_hIcon, 
 
 
 
"飞鸽传书" 
 
 
 
}; 
 
 
 
 
  
 
 
int iErr = ::Shell_NotifyIcon(NIM_ADD,&nid); 
 
 
 

   } 
 
 
 
 
  
 
 

   void CFeiGeDlg::TrayModify() 
 
 
 

   { 
 
 
 
NOTIFYICONDATA nid = 
 
 
 
{ 
 
 
 
sizeof(NOTIFYICONDATA), 
 
 
 
this->m_hWnd, 
 
 
 
100, 
 
 
 
NIF_MESSAGE | NIF_ICON | NIF_TIP, 
 
 
 
UM_TRAY_NOTIFY, 
 
 
 
this->m_hIcon, 
 
 
 
"飞鸽传书" 
 
 
 
}; 
 
 
 
int iErr = Shell_NotifyIcon(NIM_MODIFY, &nid); 
 
 
 

   } 
 
 
 
 
  
 
 

   void CFeiGeDlg::TrayDelete() 
 
 
 

   { 
 
 
 
NOTIFYICONDATA nid = 
 
 
 
{ 
 
 
 
sizeof(NOTIFYICONDATA), 
 
 
 
this->m_hWnd, 
 
 
 
100, 
 
 
 
NIF_MESSAGE | NIF_ICON | NIF_TIP, 
 
 
 
UM_TRAY_NOTIFY, 
 
 
 
m_hIcon, 
 
 
 
"飞鸽传书" 
 
 
 
}; 
 
 
 
int iErr = Shell_NotifyIcon(NIM_DELETE, &nid); 
 
 
 

   } 
 
 

  3、在对话框类的初始化函数中添加托盘,去掉onCancel事件中的默认处理函数,改为隐藏当前窗口。 

 

  TrayAdd(); 

 

  this->ShowWindow(SW_HIDE);


4、给托盘添加一个菜单


5、添加菜单响应函数