首页 > 开发 > 综合 > 正文

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

2024-07-21 02:29:16
字体:
来源:转载
供稿:网友

  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)

  • 本文来源于网页设计爱好者web开发社区http://www.html.org.cn收集整理,欢迎访问。
  • 发表评论 共有条评论
    用户名: 密码:
    验证码: 匿名发表