如何将图标放置在“通知区域”内

Author: 何林春 Date: 1999年 第33期 13版

    Windows95的任务栏中,时钟所在的区域叫作“通知区域”。我们熟知的一些应用软件,如:《金山词霸》、《超级解霸》等软件在启动后,便放置一个小图标在该区域内。这个图标可以变化:当应用软件窗口正常打开时,该区域内显示一个软件打开的图标;当应用软件窗口最小化时,显示一个软件关闭的图标,使用非常方便。下面我们就谈谈在VC++中如何编制一个可以将图标放置在“通知区域”内的程序。
    Windows95用一个NOTIFYICONDATA数据结构来定义了任务栏图标的全部信息,其中的内容是:
    DWORDcbSize;//NOTIFYICONDATA结构的大小
    HWND hWnd;//任务栏状态区内图标所属窗口的句柄
    UINT uID; //应用程序定义的任务栏图标号
    UINTuFlags; //标示结构中哪些字段有效 
   UINTuCallbackMessage; //应用程序定义的回调消息号,一旦在任务栏图标范围内发生鼠标事件时,窗口将接收到消息
    HICONhIcon; //图标句柄
    charszTip[64];//图标的提示字符
    WINSHELLAPI BOOL WINAPI Shell_NotifyIcon(DWORD dwMessage,NOTIFYICONDATA pnid)函数向系统发送添加、修改和删除任务栏图标的消息。
    其中消息号dwMessage有三个值:
    NIM_ADD 添加一个图标
    NIM_DELETE删除一个图标
    NIM_MODIFY修改图标的属性。
    下面,我们具体介绍如何在VC++中进行编制。
    应用VC++的AppWizard创建一个新的基于对话框的应用程序项目:Notify。
    为应用程序添加两个图标(Icon):IDI_OPEN_ICON,IDI_MINI_ICON,它们分别对应对话框正常打开和最小化时的图标。
    对话框IDD_NOTIFY_DIALOG的风格中增加“Minimize box”和“Maximize box”,即具有“最小化”和“最大化”。
    对话框中有一个按钮:IDCANCEL,用于关闭对话框。
    为对话框类“CNotifyDlg”添加如下成员变量:
    BOOL m_bOpen;
    NOTIFYICONDATA m_notify;
    注释:m_bOpen用于判断对话框是正常打开还是最小化,以便设置不同的图标。在对话框类CNotifyDlg的构造函数CNotifyDlg::CNotifyDlg(CWnd* pParent /*=NULL*/)内//}}中AFX_DATA_INIT后为m_bOpen赋初值:m_bOpen=TRUE;
    m_notify是任务栏图标对应的数据结构。
    为对话框类CNotifyDlg添加如下成员函数:
    void AddIcon();
    在对话框初始化时,该函数将图标添加到“通知区域”内。
    void ModifyIcon();
    当对话框正常显示或最小化时,应用该函数使“通知区域”内显示不同的图标。
    void DeleteIcon();
    当对话框关闭时,该函数删除“通知区域”内的图标。
    这些函数的具体内容如下:
    void CNotifyDlg::AddIcon()
    { m_notify.cbSize=sizeof(NOTIFYICONDATA);
    m_notify.hWnd=GetSafeHwnd();
    m_notify.uID=0;
    m_notify.uFlags=NIF_ICON|NIF_MESSAGE|NIF_TIP;
    m_notify.uCallbackMessage=WM_COMMAND;
    m_notify.hIcon=(HICON)LoadImage(AfxGetInstanceHandle(),
    MAKEINTRESOURCE(IDI_OPEN_ICON),
    IMAGE_ICON,16,16,NULL);
    lstrcpy(m_notify.szTip,″程序正常打开″);
    Shell_NotifyIcon(NIM_ADD,&m_notify);}
    void CNotifyDlg::ModifyIcon()
    { m_notify.hIcon=(HICON)LoadImage(AfxGetInstanceHandle(),
    MAKEINTRESOURCE(m_bOpen?IDI_OPEN_ICON:IDI_MINI_ICON),
    IMAGE_ICON,16,16,NULL);
    lstrcpy(m_notify.szTip,(m_bOpen?″程序正常打开″:″程序最小化″));
    Shell_NotifyIcon(NIM_MODIFY,&m_notify);}
    void CNotifyDlg::DeleteIcon()
    { m_notify.uFlags=NULL;
    Shell_NotifyIcon(NIM_DELETE,&m_notify);}
    在对话框类CNotifyDlg的初始化成员函数内加入以下语句:
    AddIcon();
    将对话框类CNotifyDlg的成员函数OnSysCommand(UINT nID,LPARAM lParam)修改为以下形式:
    void CNotifyDlg::OnSysCommand(UINT nID, LPARAM lParam)
    { if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {CAboutDlg dlgAbout;
    dlgAbout.DoModal();}
    else
    {if(nID==SC_MINIMIZE)//对话框最小化
    {m_bOpen=!m_bOpen;
    ModifyIcon();
    ShowWindow(SW_HIDE);//隐藏对话框}
    else
     CDialog::OnSysCommand(nID, lParam);}
    }
    利用ClassWizard为对话框添加消息函数:
    BOOL CNotifyDlg::OnCommand(WPARAM wParam, LPARAM lParam) 
    { // TODO: Add your specialized code here and/or call the base class
    if(wParam==0)
    { if(lParam==WM_LBUTTONDBLCLK)//当双击鼠标左键时
    {m_bOpen=!m_bOpen;
    ModifyIcon();
    if(m_bOpen)
    ShowWindow(SW_SHOWNORMAL);//正常显示对话框
    else
    ShowWindow(SW_HIDE); //隐藏对话框}
    return TRUE;} 
    return CDialog::OnCommand(wParam, lParam);}
     在对话框成员函数OnCancel()内添加如下语句:
    DeleteIcon();//退出时删除图标
    到此,程序编制完毕,经过编译后可以运行。
    你可以看到:当程序开始运行时,在“通知区域”内有一个该程序窗口正常打开的图标;当将该对话框最小化或用鼠标双击该图标时,该区域内显示一个该程序窗口最小化的图标。如果再用鼠标双击该图标,则程序窗口又正常打开了。