系统托盘气泡提示和右键菜单的实现

菜单|右键

  WTL嵌入类的架构可以使整个程序很清晰,系统托盘气泡提示、上下文菜单处理可以分别独立出来,以下是实现代码,很清晰就不注释了。基本上这两个类很少需要修改,因此我把它们放到了系统包含文件搜索路径中。

//ContextMenu.h
#pragma once
template <class T>
class CContextMenu
{
public:
       BOOL CreateContextMenu(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;
       }
};

//ShellIcon.h
#pragma once
#define WM_ICON WM_USER + 180
template <class T, class MenuT, int MenuID>
class CShellIcon : public MenuT
{
private:
       NOTIFYICONDATA m_data;
       UINT m_msgTaskbarRestart;
       CString m_appName;
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)
              MESSAGE_HANDLER(WM_SIZE, OnSize)
              CHAIN_MSG_MAP(MenuT)
       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->CreateContextMenu(MenuID);
                     *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;
       }
//最小化到系统托盘
       LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
       {
              T* pT = static_cast<T*>(this);
              if (pT->IsIconic()) pT->ShowWindow(SW_HIDE);
              return 0;
       }
};

//MyIconMenu.h
#pragma once
#include "stdafx.h"
#include <ContextMenu.h>
template <class T>
class CMyIconMenu : 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;
       }
};

  CContextMenu的使用

  如果你的窗口需要上下文菜单,只需要从CContextMenu派生一个类,例如:template <class T> class CMyContextMenu : public CContextMenu<T>

  然后完成消息映射,例如CMyIconMenu所做的。在你的窗口类(假设为CMyWindowClass)的继承列表里面添加public CMyContextMenu<CMyWindowClass>,在消息映射表中添加CHAIN_MSG_MAP(CMyContextMenu<CMyWindowClass>)

  接下来只要在需要显示上下文菜单的地方,调用CreatContextMenu(UINT ID_Menu)就可以了。

  CShellIcon的使用

  首先要把stdafx.h中IE的版本改成5或者6,例如:

#define _WIN32_IE      0x0600

  然后加入CString支持,可能每个项目都几乎用到CString,大家不妨直接修改模板文件,让向导直接把CString加进去算了。

  从CContextMenu派生一个类来完成菜单映射,例如CMyIconMenu所作的。

  以下用模式对话框来演示如何给其加入托盘功能,蓝色的部分为添加的部分。

#pragma once
#include "MyIconMenu.h"
#include <ShellIcon.h>
class CMainDlg : public CDialogImpl<CMainDlg>, public CShellIcon<CMainDlg, CMyIconMenu<CMainDlg>, IDR_ICONMENU>
{
public:
       enum { IDD = IDD_MAINDLG };
       typedef CShellIcon<CMainDlg, CMyIconMenu<CMainDlg>, IDR_ICONMENU> CMyShellIcon;
       BEGIN_MSG_MAP(CMainDlg)
              MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
              COMMAND_ID_HANDLER(ID_APP_ABOUT, OnAppAbout)
              COMMAND_ID_HANDLER(IDOK, OnOK)
              COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
              CHAIN_MSG_MAP(CMyShellIcon)
       END_MSG_MAP()
       LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
       {
              // center the dialog on the screen
              CenterWindow();
              // set icons
              HICON hIcon = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
                     IMAGE_ICON, ::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON), LR_DEFAULTCOLOR);
              SetIcon(hIcon, TRUE);
              HICON hIconSmall = (HICON)::LoadImage(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME), 
                     IMAGE_ICON, ::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON), LR_DEFAULTCOLOR);
              SetIcon(hIconSmall, FALSE);
              CreateShellIcon();
              return TRUE;
       }
……………………
};

  在想弹出气泡的时候调用BOOL BalloonToolTips(LPCTSTR info)

时间: 2024-08-31 18:57:02

系统托盘气泡提示和右键菜单的实现的相关文章

VC++窗体应用程序,鼠标左键托盘显示提示,右键显示菜单

问题描述 VC++窗体应用程序,鼠标左键托盘显示提示,右键显示菜单 如题,希望左键单击托盘Icon时,有提示,类似于"安全弹出设备":右键时弹出菜单: 右键菜单我会做,左键不会做 解决方案 无非就是在你的托盘中拦截消息,wm_lbuttonup,判断按键是左键还是右键

Win8系统将蓝牙添加到右键菜单“发送到”选项的方法

  Win8系统将蓝牙添加到右键菜单"发送到"选项的方法 1.打开C:WindowsSystem32,搜索fsquirt.exe,这时会得到多个搜索结果,选择路径是C:WindowsSystem32的那个,其他的也可以,只不过是英文罢了. 2.在fsquirt.exe上右键->创建快捷方式,因为无法在当前位置创建快捷方式,所以点"是"把快捷方式放在桌面上; 3.在开始屏幕直接输入shell:sendto.然后点击输入框下面出现的shell:sendto; 4.

win8系统中开始按钮的右键菜单无法打开怎么办?

  右键菜单,是咱们Windows系统操作中经常都需要使用到的一个功能,而且相对来说,Windows系统中的右键菜单覆盖面也是很广的,很多地方都有右键菜单,例如咱们每个程序都可以右键点击,出现右键菜单,每个文件也可以右键点击,出现右键菜单,就连空白处也可以右键点击,出现快捷菜单.虽然升级到win8系统之后,开始菜单被取消掉了,但是开始按钮的右键菜单却还在,不少朋友都很喜欢这个功能,但是今天,却有用户咨询说这个右键菜单不见了,那么这个问题咱们要如何解决呢?下面,小编就来详细的介绍一下吧! 1.首先

Win7系统鼠标右键菜单背景图片怎么设置?

  具体设置方法: 1.在魔方电脑大师的功能大全选项卡中,选择魔方美化大师. 2.在魔方美化大师中,在"系统外观设置"中选择"右键菜单背景"功能.如下图所示,直接点击打开右键菜单背景功能. 3. 浏览选择自己喜欢的右键菜单背景图片,然后点击应用到系统按钮.(注意:选择的图片大小应与右键菜单相符,否则容易出现背景图重叠或显示不全等问题) 4.保存到系统中,魔方电脑大师设置的自定义右键背景图片就成功完成了.现在在电脑桌面点击鼠标右键,就可以看到弹出的右键菜单,有了养眼的

轻松设置Windows操作系统的右键菜单

你是否发现Windows的右键菜单条目中某些项目根本没用过?而有些需要功能在右键菜单中偏偏又没有.对于不实用的快捷菜单项目,是时候该清理了! "右键菜单扩展管理器"这款软件可以帮我们轻松设置右键菜单. 电脑常识 "消肿"还清爽右键菜单 在"右键菜单扩展管理器"窗口中,我们可以分别对IE.我的电脑.我的文档以及不同类型文件等10多处右键菜单分别进行清理.当你展开相应的子类别后, 在窗口右侧即会列出当前已经关联到该类别右键的相应项目.选中该扩展项并按

Windows7右键菜单怎样显示全部内容

  在win7操作系统里面右键启动项默认只是显示一部分的,我们通常可以通过点击调出其他的,也可以根据位置不同菜单也可以随时变化.可能很多人也注意到了在一般的情况下Windows7操作系统右键菜单只显示很少一部分的内容,需要按住shift才会完全显示. 如下图所示,一般在Windows7开始菜单上右键只会展开5-6个选项(有些没有"以管理员身份运行"这一项),Shift + 右键才会显示全部内容. 这是微软所采取的优化显示措施,或许你并不喜欢这种方式,更愿意直接了当的显示所有项目.那么该

怎么美化和自定义Win7鼠标右键菜单背景?

  自定义右键菜单背景图片方法如下: 1.在魔方电脑大师的功能大全选项卡中,选择魔方美化大师. 2.在魔方美化大师中,在"系统外观设置"中选择"右键菜单背景"功能.如下图所示,直接点击打开右键菜单背景功能. 3.浏览选择自己喜欢的右键菜单背景图片,然后点击应用到系统按钮.(注意:选择的图片大小应与右键菜单相符,否则容易出现背景图重叠或显示不全等问题) 4.保存到系统中,魔方电脑大师设置的自定义右键背景图片就成功完成了.现在在电脑桌面点击鼠标右键,就可以看到弹出的右键

如何在win7电脑的右键菜单下添加清空回收站选项?

  关于咱们win7系统下载官网的右键菜单,想必大家都是十分熟悉的吧?很多时候,咱们都需要使用到右键菜单这个功能,比如说咱们可以使用右键菜单在电脑任意的目录中创建新的文件夹.创建快捷方式.创建一个word文件.一个excel文件,除了新建功能之外,右键菜单还可以执行操作.复制.粘贴,查看.重命名等多种功能,不过最近有的朋友突发奇想了,想要将清空回收站的选项放入win7系统下载官网的右键菜单中,那么咱们要如何才能实现呢?下面小编就来为大家讲述一下吧! 推荐系统:win7 32位旗舰版下载 1.首先

如何将win7旗舰版右键菜单中的新建“公文包”选项删除掉?

  通过win7系统下载官网系统的右键菜单,咱们可以执行很多的操作,其中有一个操作是咱们经常都会使用到的,那便是新建的功能,例如咱们可以在任意的位置新建一个Word文档,新建一个TXT文档,新建一个excel文档,不仅如此,咱们还可以新建快捷方式等等,虽然说这个新建的内容很丰富,但是其中却有很多是咱们平时不会使用到的,那么咱们是否可以将这些不会使用到的内容删除掉呢?下面,小编就以win7旗舰版为例,来详细介绍一下如何将新家内容中的"公文包"选项删除掉. 1.首先,咱们同时按下win7旗