diff --git a/include/wx/msw/taskbarbutton.h b/include/wx/msw/taskbarbutton.h index 7159ecdde0..b5be4519b5 100644 --- a/include/wx/msw/taskbarbutton.h +++ b/include/wx/msw/taskbarbutton.h @@ -13,6 +13,7 @@ #if wxUSE_TASKBARBUTTON #include "wx/defs.h" +#include "wx/vector.h" struct ITaskbarList3; @@ -27,6 +28,8 @@ public: virtual void SetProgressState(wxTaskBarButtonState state) wxOVERRIDE; virtual void SetOverlayIcon(const wxIcon& icon) wxOVERRIDE; virtual void SetThumbnailClip(const wxRect& rect) wxOVERRIDE; + virtual bool AddThumbBarButton(wxThumbBarButton *button) wxOVERRIDE; + virtual void ShowThumbnailToolbar() wxOVERRIDE; private: friend class wxTopLevelWindowMSW; @@ -34,6 +37,11 @@ private: WXWidget m_hwnd; ITaskbarList3 *m_taskbarList; + + typedef wxVector wxThumbBarButtons; + wxThumbBarButtons m_thumbBarButtons; + + bool m_hasShownThumbnailToolbar; }; #endif // wxUSE_TASKBARBUTTON diff --git a/include/wx/msw/toplevel.h b/include/wx/msw/toplevel.h index 18d3365985..92960d2a48 100644 --- a/include/wx/msw/toplevel.h +++ b/include/wx/msw/toplevel.h @@ -146,6 +146,8 @@ public: // deleted when the window itself is, do not delete it yourself. May return // NULL if the initialization of taskbar button failed. wxTaskBarButton* MSWGetTaskBarButton(); + + bool HandleTHBNClickedCommand(WXWORD id); #endif // wxUSE_TASKBARBUTTON protected: diff --git a/include/wx/taskbarbutton.h b/include/wx/taskbarbutton.h index bc8a6583b7..41a386b7f5 100644 --- a/include/wx/taskbarbutton.h +++ b/include/wx/taskbarbutton.h @@ -29,6 +29,24 @@ enum wxTaskBarButtonState wxTASKBAR_BUTTON_PAUSED = 8 }; +class WXDLLIMPEXP_ADV wxThumbBarButton { +public: + wxThumbBarButton(int id, + const wxIcon& icon, + const wxString& tooltip = wxEmptyString); + + virtual ~wxThumbBarButton() {} + + int GetID() const { return m_id; } + const wxIcon& GetIcon() const { return m_icon; } + const wxString& GetTooltip() const { return m_tooltip; } + +private: + int m_id; + wxIcon m_icon; + wxString m_tooltip; +}; + class WXDLLIMPEXP_ADV wxTaskBarButton { public: @@ -44,6 +62,16 @@ public: virtual void SetOverlayIcon(const wxIcon& icon) = 0; virtual void SetThumbnailClip(const wxRect& rect) = 0; + /** + Adds a thumbnail toolbar button to the thumbnail image of a window in + the taskbar button flyout. Note that a wxTaskbarButton can only have no + more than seven wxThumbBarButtons, and ShowThumbnailToolbar should be + called to show them, then these buttons cannot be added or removed until + the window is re-created. + */ + virtual bool AddThumbBarButton(wxThumbBarButton *button) = 0; + virtual void ShowThumbnailToolbar() = 0; + private: wxDECLARE_NO_COPY_CLASS(wxTaskBarButton); }; diff --git a/samples/taskbarbutton/taskbarbutton.cpp b/samples/taskbarbutton/taskbarbutton.cpp index 2f1f26dd94..614a3f5214 100644 --- a/samples/taskbarbutton/taskbarbutton.cpp +++ b/samples/taskbarbutton/taskbarbutton.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: taskbarbutton.cpp -// Purpose: wxTaskbarButton sample +// Purpose: wxTaskBarButton sample // Author: Chaobin Zhang // Created: 2014-04-30 // Copyright: (c) 2014 wxWidgets development team @@ -29,6 +29,19 @@ enum ClearOverlayIconBtn, SetThumbnailClipBtn, RestoreThumbnailClipBtn, + AddThumbBarButtonBtn, + ShowThumbnailToolbarBtn, +}; + +enum +{ + ThumbnailToolbarBtn_0 = wxID_HIGHEST + 100, + ThumbnailToolbarBtn_1, + ThumbnailToolbarBtn_2, + ThumbnailToolbarBtn_3, + ThumbnailToolbarBtn_4, + ThumbnailToolbarBtn_5, + ThumbnailToolbarBtn_6 }; namespace { @@ -100,6 +113,9 @@ private: void OnSetOverlayIcon(wxCommandEvent& WXUNUSED(event)); void OnClearOverlayIcon(wxCommandEvent& WXUNUSED(event)); void OnSetOrRestoreThumbnailClip(wxCommandEvent& event); + void OnAddThubmBarButton(wxCommandEvent& WXUNUSED(event)); + void OnShowThumbnailToolbar(wxCommandEvent& WXUNUSED(event)); + void OnThumbnailToolbarBtnClicked(wxCommandEvent& event); wxSlider *m_slider; wxRadioBox *m_visibilityRadioBox; @@ -114,7 +130,7 @@ bool MyApp::OnInit() if ( !wxApp::OnInit() ) return false; - MyFrame *frame = new MyFrame("wxTaskbarButton App"); + MyFrame *frame = new MyFrame("wxTaskBarButton App"); frame->Show(true); return true; @@ -193,15 +209,27 @@ MyFrame::MyFrame(const wxString& title) stcSizer->Add(setThumbnailClipBtn, 1, wxEXPAND | wxALL, 2); stcSizer->Add(restoreThumbnailClipBtn, 1, wxEXPAND | wxALL, 2); + // Thumbnail Toolbar Buttons section. + wxStaticBoxSizer *ttbSizer = + new wxStaticBoxSizer(wxVERTICAL, panel, wxT("ThumbBar Buttons")); + wxButton *addThumbBarButtonBtn = + new wxButton(panel, AddThumbBarButtonBtn, wxT("Add ThumbBar Button")); + wxButton *showThumbnailToolbarBtn = + new wxButton(panel, ShowThumbnailToolbarBtn, + wxT("Show Thumbnail Toolbar")); + ttbSizer->Add(addThumbBarButtonBtn, 1, wxEXPAND | wxALL, 2); + ttbSizer->Add(showThumbnailToolbarBtn, 1, wxEXPAND | wxALL, 2); + gs->Add(spvSizer, 0, wxEXPAND); gs->Add(m_visibilityRadioBox, 0, wxEXPAND); gs->Add(sttSizer, 0, wxEXPAND); gs->Add(spsSizer, 0, wxEXPAND); gs->Add(soiSizer, 0, wxEXPAND); gs->Add(stcSizer, 0, wxEXPAND); + gs->Add(ttbSizer, 0, wxEXPAND); wxStaticText *text = new wxStaticText( - panel, wxID_ANY, wxT("Welcome to wxTaskbarButton sample")); + panel, wxID_ANY, wxT("Welcome to wxTaskBarButton sample")); mainSizer->Add(text, 0, wxALIGN_CENTRE_HORIZONTAL); mainSizer->Add(gs); @@ -221,6 +249,15 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_BUTTON(ClearOverlayIconBtn, MyFrame::OnClearOverlayIcon) EVT_BUTTON(SetThumbnailClipBtn, MyFrame::OnSetOrRestoreThumbnailClip) EVT_BUTTON(RestoreThumbnailClipBtn, MyFrame::OnSetOrRestoreThumbnailClip) + EVT_BUTTON(AddThumbBarButtonBtn, MyFrame::OnAddThubmBarButton) + EVT_BUTTON(ShowThumbnailToolbarBtn, MyFrame::OnShowThumbnailToolbar) + EVT_BUTTON(ThumbnailToolbarBtn_0, MyFrame::OnThumbnailToolbarBtnClicked) + EVT_BUTTON(ThumbnailToolbarBtn_1, MyFrame::OnThumbnailToolbarBtnClicked) + EVT_BUTTON(ThumbnailToolbarBtn_2, MyFrame::OnThumbnailToolbarBtnClicked) + EVT_BUTTON(ThumbnailToolbarBtn_3, MyFrame::OnThumbnailToolbarBtnClicked) + EVT_BUTTON(ThumbnailToolbarBtn_4, MyFrame::OnThumbnailToolbarBtnClicked) + EVT_BUTTON(ThumbnailToolbarBtn_5, MyFrame::OnThumbnailToolbarBtnClicked) + EVT_BUTTON(ThumbnailToolbarBtn_6, MyFrame::OnThumbnailToolbarBtnClicked) wxEND_EVENT_TABLE() void MyFrame::OnSetProgressValue(wxScrollEvent& WXUNUSED(event)) @@ -296,3 +333,25 @@ void MyFrame::OnSetOrRestoreThumbnailClip(wxCommandEvent& event) MSWGetTaskBarButton()->SetThumbnailClip(rect); } + +void MyFrame::OnAddThubmBarButton(wxCommandEvent& WXUNUSED(event)) +{ + static int thumbBarButtonCounter = 0; + if ( thumbBarButtonCounter >= 7 ) + return; + + wxThumbBarButton *btn = new wxThumbBarButton( + thumbBarButtonCounter + ThumbnailToolbarBtn_0 , CreateRandomIcon()); + MSWGetTaskBarButton()->AddThumbBarButton(btn); + ++thumbBarButtonCounter; +} + +void MyFrame::OnShowThumbnailToolbar(wxCommandEvent& WXUNUSED(event)) +{ + MSWGetTaskBarButton()->ShowThumbnailToolbar(); +} + +void MyFrame::OnThumbnailToolbarBtnClicked(wxCommandEvent& event) +{ + wxLogMessage("Thumbnail Toolbar Button %d is clicked.", event.GetId()); +} diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index cfdca7e961..eeb2db1ca9 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -64,6 +64,10 @@ extern wxMenu *wxCurrentPopupMenu; #endif // wxUSE_MENUS || wxUSE_MENUS_NATIVE +#if wxUSE_TASKBARBUTTON + #define wxTHBN_CLICKED 0x1800 +#endif // wxUSE_TASKBARBUTTON + // ---------------------------------------------------------------------------- // event tables // ---------------------------------------------------------------------------- @@ -862,6 +866,13 @@ bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) } #endif // wxUSE_MENUS +#if wxUSE_TASKBARBUTTON + if ( cmd == wxTHBN_CLICKED && MSWGetTaskBarButton() ) + { + return wxTopLevelWindowMSW::HandleTHBNClickedCommand(id); + } +#endif // wxUSE_TASKBARBUTTON + return wxFrameBase::HandleCommand(id, cmd, control);; } diff --git a/src/msw/taskbarbutton.cpp b/src/msw/taskbarbutton.cpp index ed3e5dc2fb..1ed30f59e4 100644 --- a/src/msw/taskbarbutton.cpp +++ b/src/msw/taskbarbutton.cpp @@ -22,8 +22,15 @@ #include +wxThumbBarButton::wxThumbBarButton(int id, + const wxIcon& icon, + const wxString& tooltip) + : m_id(id), m_icon(icon), m_tooltip(tooltip) +{ +} + wxTaskBarButtonImpl::wxTaskBarButtonImpl(WXWidget parent) - : m_hwnd(parent), m_taskbarList(NULL) + : m_hwnd(parent), m_taskbarList(NULL), m_hasShownThumbnailToolbar(false) { HRESULT hr = CoCreateInstance ( @@ -51,6 +58,14 @@ wxTaskBarButtonImpl::~wxTaskBarButtonImpl() { if ( m_taskbarList ) m_taskbarList->Release(); + + for ( wxThumbBarButtons::iterator iter = m_thumbBarButtons.begin(); + iter != m_thumbBarButtons.end(); + ++iter) + { + delete (*iter); + } + m_thumbBarButtons.clear(); } void wxTaskBarButtonImpl::SetProgressValue(int value) @@ -93,4 +108,45 @@ void wxTaskBarButtonImpl::SetThumbnailClip(const wxRect& rect) m_taskbarList->SetThumbnailClip(m_hwnd, rect.IsEmpty() ? NULL : &rc); } +bool wxTaskBarButtonImpl::AddThumbBarButton(wxThumbBarButton *button) +{ + wxCHECK( button != NULL, wxT("Can't add invalid wxThumbBarButton.") ); + if (m_thumbBarButtons.size() >= 7) + return false; + + m_thumbBarButtons.push_back(button); + return true; +} + +void wxTaskBarButtonImpl::ShowThumbnailToolbar() +{ + if ( m_hasShownThumbnailToolbar || m_thumbBarButtons.empty() ) + return; + + THUMBBUTTON buttons[7]; + size_t i; + for ( i = 0; i < m_thumbBarButtons.size(); ++i ) + { + buttons[i].iId = m_thumbBarButtons[i]->GetID(); + buttons[i].hIcon = GetHiconOf(m_thumbBarButtons[i]->GetIcon()); + buttons[i].dwFlags = THBF_ENABLED; + buttons[i].dwMask = THB_ICON | THB_FLAGS; + wxString tooltip = m_thumbBarButtons[i]->GetTooltip(); + if ( tooltip.empty() ) + continue; + + // Truncate the tooltip if its length longer than szTip(THUMBBUTTON) + // allowed length (260). + if ( tooltip.length() > WXSIZEOF(buttons[i].szTip) ) + tooltip = tooltip.SubString(0, WXSIZEOF(buttons[i].szTip) - 1); + wxStrlcpy(buttons[i].szTip, tooltip.t_str(), tooltip.length()); + buttons[i].dwMask |= THB_TOOLTIP; + } + + m_taskbarList->ThumbBarAddButtons(m_hwnd, + m_thumbBarButtons.size(), + buttons); + m_hasShownThumbnailToolbar = true; +} + #endif // wxUSE_TASKBARBUTTON diff --git a/src/msw/toplevel.cpp b/src/msw/toplevel.cpp index 9764d06d20..c986f72115 100644 --- a/src/msw/toplevel.cpp +++ b/src/msw/toplevel.cpp @@ -688,6 +688,10 @@ wxTopLevelWindowMSW::~wxTopLevelWindowMSW() ::BringWindowToTop(GetHwndOf(parent)); } } +#if wxUSE_TASKBARBUTTON + if ( m_taskBarButton ) + delete m_taskBarButton; +#endif } // ---------------------------------------------------------------------------- @@ -1577,6 +1581,13 @@ wxTaskBarButton* wxTopLevelWindowMSW::MSWGetTaskBarButton() { return m_taskBarButton; } + +bool wxTopLevelWindowMSW::HandleTHBNClickedCommand(WXWORD id) +{ + wxCommandEvent event(wxEVT_BUTTON, id); + event.SetEventObject(this); + return ProcessEvent(event); +} #endif // wxUSE_TASKBARBUTTON