任务栏提示和上下文菜单
来源:岁月联盟
时间:2006-04-07
//ContextMenu.h
#pragma once#include "stdafx.h" template <class T>class CContextMenu{public: BOOL CreatContextMenu(UINT ID_Menu) { T* pT = static_cast<T*>(this); CMenu menu; menu.LoadMenu(ID_Menu); CMenu SubMenu(menu.GetSubMenu(0)); POINT pos; GetCursorPos(&pos); SubMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, pT->m_hWnd); return TRUE; }};// IconMenu.h
//需要添加一个菜单资源IDR_ICONMENU,包含ID_RESUME(恢复)、ID_QUIT(退出)#pragma once #include "stdafx.h"#include "ContextMenu.h" template <class T>class CIconMenu : public CContextMenu<T>{public: BEGIN_MSG_MAP(CContextMenu) COMMAND_ID_HANDLER(ID_RESUME, OnResume) COMMAND_ID_HANDLER(ID_QUIT, OnQuit) END_MSG_MAP() LRESULT OnResume(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { T* pT = static_cast<T*>(this); pT->ShowWindow(SW_SHOW); OpenIcon(pT->m_hWnd); return 0; } LRESULT OnQuit(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) { PostQuitMessage(0); return 0; }};//ShellIcon.h#pragma once#include "stdafx.h"#include "IconMenu.h" template <class T>class CShellIcon : public CIconMenu<T>{private: NOTIFYICONDATA m_data; CString m_appName; UINT m_msgTaskbarRestart;public: CShellIcon() { m_appName.LoadString(IDS_APPNAME); m_msgTaskbarRestart = RegisterWindowMessage(TEXT("TaskbarCreated")); } ~CShellIcon() { Shell_NotifyIcon(NIM_DELETE, &m_data); } BOOL CreateShellIcon() { T* pT = static_cast<T*>(this); SecureZeroMemory(&m_data, sizeof(m_data)); m_data.cbSize = sizeof(m_data); m_data.hIcon = LoadIcon(_Module.get_m_hInst(), MAKEINTRESOURCE(IDR_MAINFRAME)); m_data.hWnd = pT->m_hWnd; m_data.uID = IDR_MAINFRAME; m_data.uFlags = NIF_ICON | NIF_MESSAGE | NIF_INFO | NIF_TIP; m_data.uCallbackMessage = WM_ICON; m_data.dwInfoFlags = NIIF_USER; strcpy_s(m_data.szInfoTitle, m_appName); strcpy_s(m_data.szTip, m_appName); return Shell_NotifyIcon(NIM_ADD, &m_data); } void ModifyToolTips(LPCTSTR info) { strcpy_s(m_data.szInfo, info); } BOOL DispalyToolTips() { return Shell_NotifyIcon(NIM_MODIFY, &m_data); } BOOL BalloonToolTips(LPCTSTR info) { ModifyToolTips(LPCTSTR info); return DispalyToolTips(); } BEGIN_MSG_MAP(CShellIcon) MESSAGE_HANDLER(WM_ICON, OnIcon) MESSAGE_HANDLER(m_msgTaskbarRestart, OnRestart) CHAIN_MSG_MAP(CIconMenu<T>) END_MSG_MAP() LRESULT OnIcon(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { T* pT = static_cast<T*>(this); char t; if (wParam != IDR_MAINFRAME) return 1; switch(lParam) { case WM_RBUTTONUP: t = *m_data.szInfo; *m_data.szInfo = '/0'; Shell_NotifyIcon(NIM_MODIFY, &m_data); pT->CreatContextMenu(IDR_ICONMENU); *m_data.szInfo = t; break; case WM_LBUTTONUP: pT->ShowWindow(SW_SHOW); OpenIcon(pT->m_hWnd); break; case WM_MOUSEMOVE://去掉下面的注释可以使鼠标悬停在图标上时出现气泡提示,个人不太喜欢 // DispalyToolTips(); break; default: ; } return 0; }//处理Explorer外壳崩溃后任务栏重建,你会发现很多程序都没处理,结果就是Explorer一崩溃 //图标就找不到了,如果最小化到任务栏更惨,还得用任务管理器关闭,这个函数我没机会测试,希望有作用 LRESULT OnRestart(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { T* pT = static_cast<T*>(this); SecureZeroMemory(&m_data, sizeof(m_data)); m_data.cbSize = sizeof(m_data); m_data.hWnd = pT->m_hWnd; m_data.uID = IDR_MAINFRAME; Shell_NotifyIcon(NIM_DELETE, &m_data); CreateShellIcon(); return 0; }}; 因为使用任务栏提示几乎一定要用到上下文菜单(右键菜单),所以我把它们放到了一起,这几个类很好使用。CContextMenu的使用
如果你的窗口需要上下文菜单,只需要从CContextMenu派生一个类,例如:template <class T>class CMyContextMenu : public CContextMenu<T>然后完成消息映射,例如CIconMenu所做的。在你的窗口类(假设为CMyWindowClass)的继承列表里面添加public CMyContextMenu<CMyWindowClass>,在消息映射表中添加CHAIN_MSG_MAP(CMyContextMenu<CMyWindowClass>)接下来只要在需要显示上下文菜单的地方,调用CreatContextMenu(UINT ID_Menu)就可以了。CShellIcon的使用
把CShellICon加入窗口的继承列表,例如public CShellIcon<CMyWindowClass>,在消息映射表中添加CHAIN_MSG_MAP(CShellIcon<CMyWindowClass>),在OnCreat或者OnInitDialog里面的适当位置添加CreateShellIcon()。 如果要最小化到任务栏,添加OnSize函数加入 if (IsIconic()) ShowWindow(SW_HIDE);在需要弹出气泡提示的时候调用BOOL BalloonToolTips(LPCTSTR info)上一篇:C#中如何得到主机名与IP地址











