Windows 95(以下简称Win95)以其良好的用户界面深受广大用户喜爱。Win95启动后通过开始菜单或桌面上的快捷方式启动应用程序,一般情况下,当程序执行极小化操作后,程序将排列 到任务栏并以标题的形式显示,用户通过任务栏可以快速在各任务之间切换。但是对于那些针对系统时钟、设备状态或其它一些事件,如中文输入法等应用程序,其常见操作往往是说明当前时钟、设备或事件的状态以及在各状态之间的切换等。如果只是以标题的形式缩小到任务栏,用户需要查询和修改时需要重新激活应用程序窗口来操作,使用不方便。如果能像我们常见的Win95的音量控制和时钟一样把应用程序以图标的形式放入任务栏,那么不仅当前设备或事件的状态一目了然,而且可以通过鼠标和弹出菜单来改变,必要时还能重新激活应用程序主窗口来进行进一步操作。这无疑有助于提高程序的易用性,实现友好的用户界面。下面笔者结合一个在Borlard C++5.0下编制的实例程序来演示在Win95任务栏上放置图标的方法。
任务栏上的图标用结构NOTIFYICONDATA描述,结构NOTIFYICONDATA有两种形式NOTIFYIC ONDATAA和NOTIFYICONDATAW,两种结构的选择取决于使用的字符集,其定义在shellapi.h中。
struct NOTIFYICONDATAA {
DWORD cbSize; /*结构字节大小 */
HWND hWnd; /*窗口句柄*/
UINI u ID; /*图标标识*/
UINT uFlags;
/* 标志可以是NIF-MESSAGE(传递消息)、NIF-ICON(显示图标)、NIF-TIP(显示提示)的组合*/
UINT uCallbackMessage; /*定义消息名称标识符*/
HICON hIcon; /*图标句柄*/
CHAR szTip[64];/*提示串*/
}
在结构NOTIFYICONDATAW中CHAR szTip[64]定义为:
WCHAR szTip[64];
定义NOTIFYICONDATA型变量后,通过Shell-NotifyIcon向其发送消息,以完成图标的建立、删除、修改操作。Shell-NotifyIcon定义在shellapi.h中也有两种形式Shell-NotifyIco nA和Shell-NotifyIconW。其声明如下:
WINSHELLAPI BOOL WINAPI Shell-NotifyIconA(DWORD dwMessage,PNOTIFYICONDATAA lpData);
WINSHELLAPI BOOL WINAPI Shell-NotifyIconW(DWORD dwMessage,PNOTIFYICONDATAW lpData);
其中lpData即指向类型为NOTIFYICONDATA的变量的指针,dwMessage为以下三者之一:
NIM-ADD 增加图标
NIM-MODIFY 修改图标
NIM-DELETE 删除图标
当需要在任务栏增加一个图标时,发送NIM-ADD消息;当需要修改已经存在的图标时,发送NIM-MODIFY消息;当程序退出或相关事件不存在时,发送NIM-DELETE消息。
以下是程序及相关文件清单:
/* program demo.c*/
#include"demo.h"
#include<windowsx.h>
#define MYWM-NOTIFYICON (WM-APP+100)
HINSTANCE hinstance;
BOOL IsExisted=FALSE;/*用于标记图标是否已经显示*/
UINT uNotify=IDC-NOTIFY,uTip=IDC-TIP;
BOOL IconMessage(HWND hDlg,DWORD dwMessage,UINT uID,HICON hIcon,PSTR pszTip)
{BOOL retval;
/*结构NOTIFYICONDATA赋值*/
NOTIFYICONDATA tnd; tnd.cbSize=sizeof(NOTIFYICONDATA);
tnd.hWnd=hDlg; tnd.uID=uID;
tnd.uFlags=NIF-MESSAGE|NIF-ICON|NIF-TIP; tnd.hIcon=hIcon;
tnd.uCallabackMessage=MYWM-NOTIFYICON;
if(pszTip){lstrcpyn(tnd.szTip,pszTip,sizeof(tnd.szTip));}
else{tnd.szTip[0]=‘\0’;}
retval=Shell-NotifyIcon(dwMessage,&tnd);
if(hIcon)DestroyIcon(hIcon);
return retval;
}
LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi)
{HICON hIcon;
hIcon=(HICON)LoadImage(hinstance,MAKEINTRESOURCE(lpdi->CtlID),IMAGE-ICON,16,16,0);
if(!hIcon){return(FALSE);}
DrawIconEx(1pid->hDC,lpdi->rcItem.left,lpdi->rcItem.top,hIcon,16,16,0,NU
LL,DI-NORMAL);
return(TRUE);
}
void IconStateChange(HWND hDlg) /*图标状态改变时调用*/
{ char szTip[64],szIconFilename[128];
if(!GetDlgItemText(hDlg,IDC-ICONFILENAME,szIconFilename,sizeof(szIconFilename)))
{lstrcpyn(szIconFilename,"demo.ico\0",sizeof(szIconFilename));}
if(!GetDlgItemText(hDlg,IDC-TIP,szTip,sizeof(szTip))){*szTip=‘\0’;}
IconMessage(hDlg,NIM-MODIFY,uNotify,LoadImage(hinstance,szIconFilename,I
MAGE-ICON,16,16,LR-LOADFROMFILE),szTip);
}