12.6 wxTaskBarIcon

这个类的功能是在系统托盘区(Windows,Gnome或者KDE)或者停靠区(Mac OS X)安装一个图标.点击这个图标将会弹出一个应用程序提供的菜单,并且在当鼠标划过图标的时候会显示一个可选的工具提示.这种技术提供了一种不必通过正规的用户界面快速访问某些重要功能的方法.应用程序可以通过更换图标来提供某些状态信息,比如用来提示电池的剩余电量或者windows系统上的网络连接提示.

下图演示了wxWidgets自带的samples/taskbar例子在windows平台上运行时的样子.它首先显示一个 wxWidgets的图标,当鼠标移过这个图标的时候显示"wxTaskBarIconSample."工具提示,右键单击这个图标将会显示一个菜单,菜单有三个选项,选择设置新图标选项将会将图标设置为一个笑脸,并且把工具提示更改为一个新的文本.

以wxTaskBarIcon方式驱动的应用程序并不十分复杂,如下所示.自定义的类型MyTaskBarIcon重载了wxTaskBarIcon的CreatePopupMenu函数,并且拦截了左键双击事件,并实现了三个菜单项.

class MyTaskBarIcon: public wxTaskBarIcon
{
public:
    MyTaskBarIcon() {};
    void OnLeftButtonDClick(wxTaskBarIconEvent&);
    void OnMenuRestore(wxCommandEvent&);
    void OnMenuExit(wxCommandEvent&);
    void OnMenuSetNewIcon(wxCommandEvent&);
    virtual wxMenu *CreatePopupMenu();
DECLARE_EVENT_TABLE()
};
enum {
    PU_RESTORE = 10001,
    PU_NEW_ICON,
    PU_EXIT,
};
BEGIN_EVENT_TABLE(MyTaskBarIcon, wxTaskBarIcon)
    EVT_MENU(PU_RESTORE, MyTaskBarIcon::OnMenuRestore)
    EVT_MENU(PU_EXIT,    MyTaskBarIcon::OnMenuExit)
    EVT_MENU(PU_NEW_ICON,MyTaskBarIcon::OnMenuSetNewIcon)
    EVT_TASKBAR_LEFT_DCLICK  (MyTaskBarIcon::OnLeftButtonDClick)
END_EVENT_TABLE()
void MyTaskBarIcon::OnMenuRestore(wxCommandEvent& )
{
    dialog->Show(true);
}
void MyTaskBarIcon::OnMenuExit(wxCommandEvent& )
{
    dialog->Close(true);
}
void MyTaskBarIcon::OnMenuSetNewIcon(wxCommandEvent&)
{
    wxIcon icon(smile_xpm);

    if (!SetIcon(icon, wxT("wxTaskBarIcon Sample - a different icon")))
        wxMessageBox(wxT("Could not set new icon."));
}
// 重载
wxMenu *MyTaskBarIcon::CreatePopupMenu()
{
    wxMenu *menu = new wxMenu;
    menu->Append(PU_RESTORE, wxT("&Restore TBTest"));
    menu->Append(PU_NEW_ICON,wxT("&Set New Icon"));
    menu->Append(PU_EXIT,    wxT("E&xit"));
    return menu;
}
void MyTaskBarIcon::OnLeftButtonDClick(wxTaskBarIconEvent&)
{
    dialog->Show(true);
}

下面的代码则用来显示一个对话框并且安装初始化图标.

#include "wx/wx.h"
#include "wx/taskbar.h"
// 定义一个新的应用程序
class MyApp: public wxApp
{
public:
    bool OnInit(void);
};
class MyDialog: public wxDialog
{
public:
    MyDialog(wxWindow* parent, const wxWindowID id, const wxString& title,
        const wxPoint& pos, const wxSize& size, const long windowStyle =
 wxDEFAULT_DIALOG_STYLE);
    ~MyDialog();
    void OnOK(wxCommandEvent& event);
    void OnExit(wxCommandEvent& event);
    void OnCloseWindow(wxCloseEvent& event);
    void Init(void);
protected:
    MyTaskBarIcon   *m_taskBarIcon;
DECLARE_EVENT_TABLE()
};
#include "../sample.xpm"
#include "smile.xpm"
MyDialog   *dialog = NULL;
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit(void)
{
    // 创建主窗口
    dialog = new MyDialog(NULL, wxID_ANY, wxT("wxTaskBarIcon Test Dialog"),
 wxDefaultPosition, wxSize(365, 290));
    dialog->Show(true);
    return true;
}
BEGIN_EVENT_TABLE(MyDialog, wxDialog)
    EVT_BUTTON(wxID_OK, MyDialog::OnOK)
    EVT_BUTTON(wxID_EXIT, MyDialog::OnExit)
    EVT_CLOSE(MyDialog::OnCloseWindow)
END_EVENT_TABLE()
MyDialog::MyDialog(wxWindow* parent, const wxWindowID id, const wxString& title,
    const wxPoint& pos, const wxSize& size, const long windowStyle):
  wxDialog(parent, id, title, pos, size, windowStyle)
{
    Init();
}
MyDialog::~MyDialog()
{
    delete m_taskBarIcon;
}
void MyDialog::OnOK(wxCommandEvent& WXUNUSED(event))
{
    Show(false);
}
void MyDialog::OnExit(wxCommandEvent& WXUNUSED(event))
{
    Close(true);
}
void MyDialog::OnCloseWindow(wxCloseEvent& WXUNUSED(event))
{
    Destroy();
}
void MyDialog::Init(void)
{
  (void)new wxStaticText(this, wxID_ANY, wxT("Press 'Hide me' to hide me, Exit to quit."),
                         wxPoint(10, 20));
  (void)new wxStaticText(this, wxID_ANY, wxT("Double-click on the taskbar icon to show me
 again."),
                         wxPoint(10, 40));
  (void)new wxButton(this, wxID_EXIT, wxT("Exit"), wxPoint(185, 230), wxSize(80, 25));
  (new wxButton(this, wxID_OK, wxT("Hide me"), wxPoint(100, 230), wxSize(80,
 25)))->SetDefault();
  Centre(wxBOTH);
  m_taskBarIcon = new MyTaskBarIcon();
  if (!m_taskBarIcon->SetIcon(wxIcon(sample_xpm), wxT("wxTaskBarIcon Sample")))
        wxMessageBox(wxT("Could not set icon."));
}

wxTaskBarIcon的事件

下表列出的事件宏用来拦截wxTaskBarIcon相关的事件.注意不是所有的发行版都产生这些事件,因此如果你想再鼠标点击的时候弹出菜单,你应该使用重载CreatePopupMenu函数的方法.还要注意wxTaskBarIconEvent事件不会提供任何鼠标指针状态信息,比如鼠标位置之类.

EVT_TASKBAR_MOVE(func) 鼠标正在图标上移动.
EVT_TASKBAR_LEFT_DOWN(func) 左键按下.
EVT_TASKBAR_LEFT_UP(func) 左键释放.
EVT_TASKBAR_RIGHT_DOWN(func) 右键按下.
EVT_TASKBAR_RIGHT_UP(func) 右键释放.
EVT_TASKBAR_LEFT_DCLICK(func) 左键双击.
EVT_TASKBAR_RIGHT_DCLICK(func) 右键双击.

wxTaskBarIcon成员函数

wxTaskBarIcon的成员函数是非常简单的,下面列出的就是它所有的成员函数.

CreatePopupMenu是一个虚函数,应用程序已经重载这个函数以返回一个wxMenu指针.这个函数在对应的 wxEVT_TASKBAR_RIGHT_DOWN事件中被调用(在Mac OS X系统上模拟了这个事件). wxWidgets也会在菜单被关闭的时候自动释放这个菜单所占用的内存.

IsIconInstalled返回是否SetIcon已经被成功调用.

IsOk在wxTaskBarIcon对象已经被成功初始化的时候返回True.

PopupMenu在当前位置显示一个菜单.最好不要调用这个函数,而应该重载CreatePopupMenu函数,然后让wxWidgets帮你显示对应的菜单.

RemoveIcon移除前一次使用SetIcon函数设置的图标.

SetIcon设置一个图标(wxIcon)以及一个可选的工具提示.这个函数可以被多次调用.