VC中的托盘程序

    VC中的托盘程序主要通过自定义消息和一个辅助结构来完成。当然,托盘的响应消息也可以是系统消息。

一、数据结构

    用到如下两个数据结构:

1. typedef struct _NOTIFYICONDATA {
    DWORD cbSize; //本结构的大小,以字节为单位
    HWND hWnd; //接收托盘图标通知消息的窗口句柄
    UINT uID; //应用程序定义的托盘图标的ID号,如果不是多个图标,并不重要
    UINT uFlags; //设置该图标的属性
    UINT uCallbackMessage; //应用程序定义的消息ID号,此消息传递给hWnd
    HICON hIcon; //图标的句柄
    TCHAR szTip[64]; //鼠标停留在图标上时显示的提示信息
    DWORD dwState;
    DWORD dwStateMask;
    TCHAR szInfo[256];
    union {
        UINT uTimeout;
        UINT uVersion;
    };
    TCHAR szInfoTitle[64];
    DWORD dwInfoFlags;
    GUID guidItem;
    HICON hBalloonIcon;
} NOTIFYICONDATA, *PNOTIFYICONDATA;
该结构中,成员uFlags可以使下列之一或组合:

 NIF_ICON 设置成员hIcon有效
 NIF_MESSAGE 设置成员uCallbackMessage有效
 NIF_TIP 设置成员szTip有效

其他项见MSDN。

2. BOOL Shell_NotifyIcon(DWORD dwMessage, PNOTIFYICONDATA lpdata);
 参数dwMessage是被传递的消息,可以是以下消息之一:
 NIM_ADD 增加图标
 NIM_DELETE 删除图标
 NIM_MODIFY 修改图标

其他项的说明见MSDN。

二、实例

    一个对话框为例,托盘所有的实现都放在对话框类中。实现的方法有多种,为简化讨论,尽量不重载函数。如对话框类为CTestTray,则实现步骤如下:

1. CTestTray.h中

 #define WM_NOTIFYICON WM_USER + 100 //自定义消息ID
  NOTIFYICONDATA m_nd; //定义类结构变量
  afx_msg LRESULT OnNotifyIcon(WPARAM wParam, LPARAM lParam); // 自定义托盘图标消息响应函数

2. CTestTray.cpp中

--- ON_MESSAGE(WM_NOTIFYICON, OnNotifyIcon) //映射消息

 

--- OnInitDialog()中:
 //初始化
 m_nd.cbSize = sizeof(NOTIFYICONDATA);
 m_nd.hWnd = m_hWnd;
 m_nd.uID = IDI_ICON1;  //IDI_ICON1为自定义图标
 m_nd.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
 m_nd.uCallbackMessage = WM_NOTIFYICON;
 m_nd.hIcon = AfxGetApp()->LoadIcon(IDI_ICON1);
 _tcscpy_s(m_nd.szTip, sizeof(m_nd.szTip), _T("托盘测试程序"));
 //显示托盘图标
 Shell_NotifyIcon(NIM_ADD, &m_nd);

初始化还可放在OnCreate、PreCreateWindow等地方。

 

--- 实现OnNotifyIcon():
// 自定义托盘图标消息响应函数
afx_msg LRESULT CTestTray::OnNotifyIcon(WPARAM wParam, LPARAM lParam)
{
 //响应在托盘图标上的单击
 //wParam中是响应消息的图标ID,lParam中则是Windows的消息
 if(wParam == IDI_ICON1){
  if(lParam == WM_LBUTTONDOWN) //左键显示对话框
   ShowWindow(SW_SHOWNORMAL);
  else if(lParam == WM_RBUTTONDOWN){ //右键弹出菜单
   CMenu menu;
   menu.LoadMenu(IDR_MENU_POPUP);
   CMenu* pMenu = menu.GetSubMenu(0);
   CPoint pos;
   GetCursorPos(&pos);
   pMenu->TrackPopupMenu(TPM_RIGHTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, AfxGetMainWnd());
  }
 }

 return afx_msg LRESULT();
}

消息响应还可在WindowProc()中完成。

 

--- CTestTray::OnSysCommand(UINT nID, LPARAM lParam)中加入:
 if(nID == SC_MINIMIZE)  //最小化时隐藏对话框
  ShowWindow(SW_HIDE);

当然,隐藏窗体可在其他地方,如按钮响应函数中。

 

--- CTestTray类的析构函数中加入:

 Shell_NotifyIcon(NIM_DELETE, &m_nd); //删除托盘图标

还可放在WM_DESTROY和WM_NCDESTROY消息响应函数。

 

    此外,托盘响应的消息也可以是其他消息,如系统消息。

 

    自此,一个托盘程序框架就完成了,可以:最小化到托盘上,左键单击托盘图标重新显示对话框,右键单击托盘图标弹出菜单。

 

参考文献:

http://www.itepub.net/html/kaifajingcui/C___VC/2006/0515/38042.html

http://www.yesky.com/190/1878190.shtml

http://www.jiuimm.com/article.asp?id=209

你可能感兴趣的:(数据结构,windows,shell,struct,delete,menu)