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

  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();//退出时删除图标

  到此,程序编制完毕,经过编译后可以运行。

  你可以看到:当程序开始运行时,在“通知区域”内有一个该程序窗口正常打开的图标;当将该对话框最小化或用鼠标双击该图标时,该区域内显示一个该程序窗口最小化的图标。如果再用鼠标双击该图标,则程序窗口又正常打开了。