在任务栏上显示图标
阿伦工作室 邱理
Windows 95/Windows NT任务栏的右边是一状态区,Windows95/Wi
ndowsNT在其上显示时间和一些小图标,这些图标代表着特定的功能或
程序,用鼠标单击、右击或双击这些图标,就会弹出功能菜单或程序窗
口等。你也许想把自己的程序图标也放在任务栏的状态区上,很简单,
VC++ 5.0提供了一个函数,让你很容易地实现该功能。
Shell_NotifyIcon()函数
该函数发送消息给系统在任务栏的状态区,增加、删除或修改图
标。Shell_NotifyI con()有两个参数:
1. DWORD dwMessage
消息标志值,为以下三个中之一:
NIM_ADD
在任务栏状态区增加图标
NIM_DELETE 从任务栏状态区删除图标
NIM_MODITY 修改任务栏状态区的图标
2. PNOTIFYICONDATA pnid
指向NOTIFYICONDATA结构的指针。NOTIFYICONDATA结构如下:
typedef struct _NOTIFYICONDATA { // nid
DWORD cbSize; // NOTIFYICONDATA 结构的大小
HWND hWnd; //接收回调消息的窗口句柄
UINT uID; //自定义的图标标志值
UINT uFlags; //标志后面的三个数据成员哪个有效,
//可由NIF_ICON,NIF_MESSAGE和
NIF_TIP组合。
UINT uCallbackMessage; //回调消息
HICON hIcon; //图标句柄
char szTip[64]; //提示字符。当把鼠标移到任务栏
//状态区该图标上时,系统显示该字符
} NOTIFYICONDATA, *PNOTIFYICONDATA;
如何在任务栏状态区实现程序图标及其功能
1. 首先生成一个单文档的工程文件。
2. 在StdAfx.h 添加自定义的消息:
//回调消息
#define MYWM_NOTIFYICON WM_USER+1
//在任务栏状态区显示图标的消息
#define MYWM_SHOWAPPICONIC WM_USER+2
3. 在MainFrm.h 里添加定义消息处理函数说明,该部分看起来如
下:
protected:
//{{AFX_MSG(CMainFrame)
afx_msg void OnSysCommand(UINT nID, LPARAM lParam); //手
工加
afx_msg void OnMyIconNotify(WPARAM wParam, LPARAM lParam
); //手工加
afx_msg void OnShowAppIconic(WPARAM wParam, LPARAM lPara
m); //手工加
afx_msg void OnClose(); //系统生成
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
另外,需在MainFrm.h定义一开关值,记录程序窗口是打开或关闭
状态:
BOOL boolWndHadShow;
4. 在MainFrm.cpp里实现消息映射和消息处理函数。消息映射部
分看起来如下:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_MESSAGE(MYWM_NOTIFYICON, OnMyIconNotify)
ON_MESSAGE(MYWM_SHOWAPPICONIC,OnShowAppIconic)
ON_WM_SYSCOMMAND()
ON_WM_CLOSE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
消息处理及相关函数如下所示:
//在任务栏状态区添加图标
BOOL MyTaskBarAddIcon(HWND hwnd, UINT uID, HICON hicon,
LPSTR lpszTip)
{
BOOL res;
NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = hwnd;
tnid.uID = uID;
tnid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
tnid.uCallbackMessage = MYWM_NOTIFYICON;
tnid.hIcon = hicon;
if (lpszTip)
lstrcpyn(tnid.szTip, lpszTip, sizeof(tnid.szTip));
else
tnid.szTip[0]=‘\0';
res=shell_NotifyIco n(NIM_ADD, &tnid);
if (hicon)
DestroyIcon(hicon);
return res;
}
//从任务栏状态区删除图标
BOOL MyTaskBarDeleteIcon(HWND hwnd, UINT uID)
{
BOOL res;
NOTIFYICONDATA tnid;
tnid.cbSize = sizeof(NOTIFYICONDATA);
tnid.hWnd = hwnd;
tnid.uID = uID;
res = Shell_NotifyIcon(NIM_DELETE, &tnid);
return res;
}
//处理图标回调消息MYWM_NOTIFYICON
void CMainFrame::OnMyIconNotify( WPARAM wParam, LPARAM l
Param )
{
UINT nID;
UINT uMouseMsg;
nID = (UINT)wParam;
uMouseMsg = (UINT) lParam;
if(uMouseMsg == WM_LBUTTONDOWN)
//点击图标
{
if( boolWndHadShow ) //如果窗口已打开,隐藏窗口
ShowWindow(SW_HIDE );
else
//否则,显示窗口
ShowWindow(SW_SHOWNORMAL );
boolWndHadShow = ~boolWndHadShow;
}
}
//消息MYWM_SHOWAPPICONIC处理函数,在任务栏显示图标并隐藏
窗口
void CMainFrame::OnShowAppIconic(WPARAM wParam, LPARAM l
Param )
{
HICON theIcon = LoadIcon(AfxGetInstance-Handle(),MAKEINT
RESOURCE(IDR_MAI NFRAME) );
MyTaskBarAddIcon(GetSafeHwnd(), 100, theIcon, _T("示范程
序"));
ShowWindow(SW_HIDE );
boolWndHadShow = FALSE;
}
当程序关闭时,需把图标从任务样状态区删除,你可以添加一个处
理WM_CLOSE消息的函数来删除图标。通过ClassWizard来添加处理WM_
CLOSE的函数OnClose(),该函数如下:
void CMainFrame::OnClose()
{
// TODO: Add your message handler code here and/or call
default
MyTaskBarDeleteIcon( GetSafeHwnd(), 100 );
CFrameWnd::OnClose();
}
当用户把窗口最小化时,你应隐藏整个窗口,所以要处理ON_SYSCO
MMAND消息。首先在MainFrm.h添加函数说明,如第三步所示;然后在Ma
inFrm.cpp里说明消息映射和实现函数。消息映射如前面所示,函数实
现如下:
void CMainFrame::OnSysCommand(UINT nID, LPARAM lParam )
{
if (nID==SC_MINIMIZE )
{
ShowWindow(SW_HIDE );
boolWndHadShow=FALSE;
}
else
CWnd::OnSysCommand(nID, lParam );
}
5. 在InitInstance()函数返回前,添加一语句
m_pMainWnd->PostMessage( MYWM_SHOWAP- PICONIC );
它是发送一个自定义的消息MYWM_SHOWAP- PICONIC使程序启动后
隐藏程序窗口并在任务栏状态区显示小图标。
6. 现在,你可编译和运行该程序了。程序运行后,点击任务栏状
态区该程序的图标, 系统会弹出程序窗口,再点击一下,又隐藏了。