windows任务栏图标编程步骤
Ligo,
2009.5.12
在windows任务栏中加载图标,其步骤非常简单,关键的就是一个函数:Shell_NotifyIcon()
此API函数有三个功能:把图标放入任务栏、更换放入任务栏中的图标、删除任务栏中的图标
一、放图标到任务栏中
先看代码:
// 放置图标到任务栏中,并隐藏自己 void CTaskbarIconDlg::PutIconToTaskbar() { NOTIFYICONDATA nid; memset( &nid, 0, sizeof(nid) ); nid.cbSize = sizeof(nid); nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; strcpy( nid.szTip, "我的任务栏图标" ); nid.hWnd = m_hWnd; nid.uCallbackMessage = UM_NOTIFY; nid.hIcon = LoadIcon( AfxGetApp()->m_hInstance, MAKEINTRESOURCE(IDI_TASKBAR) ); if ( nid.hIcon == NULL ) { TRACE( TEXT("loadicon failed, return %d/n"), GetLastError() ); } else { if ( Shell_NotifyIcon( NIM_ADD, &nid ) ) { // 添加成功,就隐藏自己 MoveWindow( -10, 0, 1, 1 ); ModifyStyleEx(WS_EX_APPWINDOW,WS_EX_TOOLWINDOW);//隐藏任务栏图标 } } } |
CTaskbarIconDlg是一个对话框工程的主窗口类
UM_NOTIFY为自定义消息,且被放到了TaskbarIconDlg.cpp文件的开头位置:
#define UM_NOTIFY (WM_USER + 101)
IDI_TASKBAR是自已随便画的一个图标的ID
由结构NOTIFYICONDATA定义了要放入任务栏中图标的信息,包括图标及其对应的提示消息和对程序的通知消息
uFlags 指明了哪个成员有效,这里指定了三个信息,分别是szTip、uCallbackMessage、hIcon
hWnd 用于指定接收消息uCallbackMessage 的窗口句柄
szTip指定当放鼠标到图标上时,windows弹出的提示信息
放图标到任务栏上是通过Shell_NotifyIcon()的第一个参数NIM_ADD来完成的。第一个参数指定了是添加、修改、删除中的一种操作。
本段代码,只有在加载图标成功的时候,才把这个图标放到任务栏上,否则就不放。如果成功放到任务栏上,则隐藏程序自己
二、修改图标
修改图标和添加图标只有一点不一样:在通过NOTIFYICONDATA 结构设置好图标的各种信息之后,像添加图标一样调用Shell_NotifyIcon(),只不过第一个参数不用NIM_ADD,而是用NIM_MODIFY。
三、删除图标
删除图标更简单,在NOTIFYICONDATA结构中,只需要指定hWnd 即可,然后以NIM_DELETE做为第一个参数来调用Shell_NotifyIcon()
一般的顺序是,在程序启动时添加图标到任务栏中,在程序退出时从任务栏中删除对应的图标。我的程序中专门写了一个删除图标的函数:
// 从任务栏中删除图标 void CTaskbarIconDlg::DelIconFromTaskbar() { NOTIFYICONDATA nid; memset( &nid, 0, sizeof(nid) ); nid.cbSize = sizeof(nid); nid.hWnd = m_hWnd; Shell_NotifyIcon( NIM_DELETE, &nid ); } |
然后在退出的函数OnClose()中调用此函数:
void CTaskbarIconDlg::OnClose() { // TODO: Add your message handler code here and/or call default DelIconFromTaskbar(); CDialog::OnClose(); } |
实际上,还有很多小技巧,我没有用过,所以不敢胡乱写,就写了这个简单的步骤出来,以便不要走太多弯路
以下为接收图标消息的处理部分
接收消息我习惯直接在wndproc函数中来处理:
LRESULT CTaskbarIconDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: Add your specialized code here and/or call the base class if ( message == UM_NOTIFY ) { if ( lParam == WM_RBUTTONUP ) PopMenuFromTaskbar(); // 只在鼠标右键点击时才弹出菜单 }
return CDialog::WindowProc(message, wParam, lParam); } |
以下为弹出菜单函数:
// 从任务栏弹出菜单 void CTaskbarIconDlg::PopMenuFromTaskbar() { CMenu menu; CPoint pt;
GetCursorPos( &pt ); menu.LoadMenu( IDR_TASKBAR );
CMenu *pMenuTaskbar = menu.GetSubMenu( 0 ); pMenuTaskbar->TrackPopupMenu( TPM_LEFTALIGN, pt.x, pt.y, this, NULL ); } |
以上其实还有一个问题,当弹出菜单后,只能点击一次菜单后,菜单才会消息,否则,不管是再点击屏幕上的其它任何位置,这个菜单都不会消失。问题还未解决。网上搜索到了一篇相关网址,大家可以参考(我看得不大懂):
http://topic.csdn.net/t/20031026/08/2395499.html