diff --git a/include/wx/msw/taskbarbutton.h b/include/wx/msw/taskbarbutton.h index 0087065051..bcde84f08c 100644 --- a/include/wx/msw/taskbarbutton.h +++ b/include/wx/msw/taskbarbutton.h @@ -32,13 +32,19 @@ public: const wxString& description = wxString()) wxOVERRIDE; virtual void SetThumbnailClip(const wxRect& rect) wxOVERRIDE; virtual void SetThumbnailContents(const wxWindow *child) wxOVERRIDE; - virtual bool AddThumbBarButton(wxThumbBarButton *button) wxOVERRIDE; - virtual void ShowThumbnailToolbar() wxOVERRIDE; + virtual bool InsertThumbBarButton(size_t pos, + wxThumbBarButton *button) wxOVERRIDE; + virtual bool AppendThumbBarButton(wxThumbBarButton *button) wxOVERRIDE; + virtual bool RemoveThumbBarButton(wxThumbBarButton *button) wxOVERRIDE; + virtual bool RemoveThumbBarButton(int id) wxOVERRIDE; private: friend class wxFrame; wxTaskBarButtonImpl(WXWidget parent); + bool InitOrUpdateThumbBarButtons(); + int GetThumbBarButtonID(size_t index); + WXWidget m_hwnd; ITaskbarList3 *m_taskbarList; @@ -46,8 +52,7 @@ private: wxThumbBarButtons m_thumbBarButtons; int m_progressRange; - - bool m_hasShownThumbnailToolbar; + bool m_hasInitThumbnailToolbar; }; #endif // wxUSE_TASKBARBUTTON diff --git a/include/wx/taskbarbutton.h b/include/wx/taskbarbutton.h index 4e9530ba00..904efed5b1 100644 --- a/include/wx/taskbarbutton.h +++ b/include/wx/taskbarbutton.h @@ -13,6 +13,8 @@ #if wxUSE_TASKBARBUTTON +#include "wx/defs.h" + // ---------------------------------------------------------------------------- // wxTaskBarButton: define wxTaskBarButton interface. // ---------------------------------------------------------------------------- @@ -33,18 +35,33 @@ class WXDLLIMPEXP_ADV wxThumbBarButton { public: wxThumbBarButton(int id, const wxIcon& icon, - const wxString& tooltip = wxString()); + const wxString& tooltip = wxString(), + bool enable = true, + bool dismissOnClick = false, + bool hasBackground = true, + bool shown = true, + bool interactive = true); virtual ~wxThumbBarButton() {} int GetID() const { return m_id; } const wxIcon& GetIcon() const { return m_icon; } const wxString& GetTooltip() const { return m_tooltip; } + bool IsEnable() const { return m_enable; } + bool IsDismissOnClick() const { return m_dismissOnClick; } + bool HasBackground() const { return m_hasBackground; } + bool IsShown() const { return m_shown; } + bool IsInteractive() const { return m_interactive; } private: int m_id; wxIcon m_icon; wxString m_tooltip; + bool m_enable; + bool m_dismissOnClick; + bool m_hasBackground; + bool m_shown; + bool m_interactive; }; class WXDLLIMPEXP_ADV wxTaskBarButton @@ -65,16 +82,10 @@ public: const wxString& description = wxString()) = 0; virtual void SetThumbnailClip(const wxRect& rect) = 0; virtual void SetThumbnailContents(const wxWindow *child) = 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; + virtual bool InsertThumbBarButton(size_t pos, wxThumbBarButton *button) = 0; + virtual bool AppendThumbBarButton(wxThumbBarButton *button) = 0; + virtual bool RemoveThumbBarButton(wxThumbBarButton *button) = 0; + virtual bool RemoveThumbBarButton(int id) = 0; private: wxDECLARE_NO_COPY_CLASS(wxTaskBarButton); diff --git a/samples/taskbarbutton/taskbarbutton.cpp b/samples/taskbarbutton/taskbarbutton.cpp index ce1fdf0e33..6de3becdf5 100644 --- a/samples/taskbarbutton/taskbarbutton.cpp +++ b/samples/taskbarbutton/taskbarbutton.cpp @@ -30,7 +30,7 @@ enum SetThumbnailClipBtn, RestoreThumbnailClipBtn, AddThumbBarButtonBtn, - ShowThumbnailToolbarBtn, + RemoveThumbBarButtonBtn, }; enum @@ -114,13 +114,16 @@ private: void OnClearOverlayIcon(wxCommandEvent& WXUNUSED(event)); void OnSetOrRestoreThumbnailClip(wxCommandEvent& event); void OnAddThubmBarButton(wxCommandEvent& WXUNUSED(event)); - void OnShowThumbnailToolbar(wxCommandEvent& WXUNUSED(event)); + void OnRemoveThubmBarButton(wxCommandEvent& WXUNUSED(event)); void OnThumbnailToolbarBtnClicked(wxCommandEvent& event); wxSlider *m_slider; wxRadioBox *m_visibilityRadioBox; wxTextCtrl *m_textCtrl; wxChoice *m_stateChoice; + + typedef wxVector wxThumbBarButtons; + wxThumbBarButtons m_thumbBarButtons; }; IMPLEMENT_APP(MyApp) @@ -215,8 +218,8 @@ MyFrame::MyFrame(const wxString& title) wxButton *addThumbBarButtonBtn = new wxButton(panel, AddThumbBarButtonBtn, wxT("Add ThumbBar Button")); wxButton *showThumbnailToolbarBtn = - new wxButton(panel, ShowThumbnailToolbarBtn, - wxT("Show Thumbnail Toolbar")); + new wxButton(panel, RemoveThumbBarButtonBtn, + wxT("Remove Last ThumbBar Button")); ttbSizer->Add(addThumbBarButtonBtn, 1, wxEXPAND | wxALL, 2); ttbSizer->Add(showThumbnailToolbarBtn, 1, wxEXPAND | wxALL, 2); @@ -250,7 +253,7 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_BUTTON(SetThumbnailClipBtn, MyFrame::OnSetOrRestoreThumbnailClip) EVT_BUTTON(RestoreThumbnailClipBtn, MyFrame::OnSetOrRestoreThumbnailClip) EVT_BUTTON(AddThumbBarButtonBtn, MyFrame::OnAddThubmBarButton) - EVT_BUTTON(ShowThumbnailToolbarBtn, MyFrame::OnShowThumbnailToolbar) + EVT_BUTTON(RemoveThumbBarButtonBtn, MyFrame::OnRemoveThubmBarButton) EVT_BUTTON(ThumbnailToolbarBtn_0, MyFrame::OnThumbnailToolbarBtnClicked) EVT_BUTTON(ThumbnailToolbarBtn_1, MyFrame::OnThumbnailToolbarBtnClicked) EVT_BUTTON(ThumbnailToolbarBtn_2, MyFrame::OnThumbnailToolbarBtnClicked) @@ -311,6 +314,7 @@ void MyFrame::OnChoice(wxCommandEvent& event) break; } + MSWGetTaskBarButton()->SetProgressValue(m_slider->GetValue()); MSWGetTaskBarButton()->SetProgressState(state); } @@ -341,21 +345,27 @@ void MyFrame::OnSetOrRestoreThumbnailClip(wxCommandEvent& event) MSWGetTaskBarButton()->SetThumbnailClip(rect); } + void MyFrame::OnAddThubmBarButton(wxCommandEvent& WXUNUSED(event)) { - static int thumbBarButtonCounter = 0; - if ( thumbBarButtonCounter >= 7 ) + if ( m_thumbBarButtons.size() >= 7 ) return; - wxThumbBarButton *btn = new wxThumbBarButton( - thumbBarButtonCounter + ThumbnailToolbarBtn_0 , CreateRandomIcon()); - MSWGetTaskBarButton()->AddThumbBarButton(btn); - ++thumbBarButtonCounter; + wxThumbBarButton* button = + new wxThumbBarButton(m_thumbBarButtons.size() + ThumbnailToolbarBtn_0 , + CreateRandomIcon()); + MSWGetTaskBarButton()->AppendThumbBarButton(button); + m_thumbBarButtons.push_back(button); } -void MyFrame::OnShowThumbnailToolbar(wxCommandEvent& WXUNUSED(event)) +void MyFrame::OnRemoveThubmBarButton(wxCommandEvent& WXUNUSED(event)) { - MSWGetTaskBarButton()->ShowThumbnailToolbar(); + if ( m_thumbBarButtons.empty() ) + return; + + wxThumbBarButton* button = m_thumbBarButtons.back(); + m_thumbBarButtons.pop_back(); + MSWGetTaskBarButton()->RemoveThumbBarButton(button); } void MyFrame::OnThumbnailToolbarBtnClicked(wxCommandEvent& event) diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index 06816c73da..7083d502dc 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -905,7 +905,9 @@ bool wxFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND control) #if wxUSE_TASKBARBUTTON if ( cmd == wxTHBN_CLICKED && m_taskBarButton ) { - wxCommandEvent event(wxEVT_BUTTON, id); + wxTaskBarButtonImpl * const + tbButton = reinterpret_cast(m_taskBarButton); + wxCommandEvent event(wxEVT_BUTTON, tbButton->GetThumbBarButtonID(id)); event.SetEventObject(this); return ProcessEvent(event); } diff --git a/src/msw/taskbarbutton.cpp b/src/msw/taskbarbutton.cpp index 0ef450b1bf..e299fd7565 100644 --- a/src/msw/taskbarbutton.cpp +++ b/src/msw/taskbarbutton.cpp @@ -14,6 +14,10 @@ #pragma hdrstop #endif +#ifndef WX_PRECOMP + #include "wx/icon.h" +#endif + #if wxUSE_TASKBARBUTTON #include "wx/msw/wrapshl.h" @@ -22,10 +26,44 @@ #include +namespace { + +// The maximum number of thumbnail toolbar buttons allowed on windows is 7. +static const int LIMITED_BUTTON_SIZE = 7; + +THUMBBUTTONFLAGS GetNativeThumbButtonFlags(const wxThumbBarButton& button) +{ + WXUINT flags = 0; + flags |= (button.IsEnable() ? THBF_ENABLED : THBF_DISABLED); + if ( button.IsDismissOnClick() ) + flags |= THBF_DISMISSONCLICK; + if ( !button.HasBackground() ) + flags |= THBF_NOBACKGROUND; + if ( !button.IsShown() ) + flags |= THBF_HIDDEN; + if ( !button.IsInteractive() ) + flags |= THBF_NONINTERACTIVE; + return static_cast(flags); +} + +} // namespace + wxThumbBarButton::wxThumbBarButton(int id, const wxIcon& icon, - const wxString& tooltip) - : m_id(id), m_icon(icon), m_tooltip(tooltip) + const wxString& tooltip, + bool enable, + bool dismissOnClick, + bool hasBackground, + bool shown, + bool interactive) + : m_id(id), + m_icon(icon), + m_tooltip(tooltip), + m_enable(enable), + m_dismissOnClick(dismissOnClick), + m_hasBackground(hasBackground), + m_shown(shown), + m_interactive(interactive) { } @@ -33,7 +71,7 @@ wxTaskBarButtonImpl::wxTaskBarButtonImpl(WXWidget parent) : m_hwnd(parent), m_taskbarList(NULL), m_progressRange(0), - m_hasShownThumbnailToolbar(false) + m_hasInitThumbnailToolbar(false) { HRESULT hr = CoCreateInstance ( @@ -52,7 +90,7 @@ wxTaskBarButtonImpl::wxTaskBarButtonImpl(WXWidget parent) hr = m_taskbarList->HrInit(); if ( FAILED(hr) ) { - wxLogApiError(wxT("ITaskbarButtonList3::Init"), hr); + wxLogApiError(wxT("ITaskbarList3::Init"), hr); return; } } @@ -131,28 +169,74 @@ void wxTaskBarButtonImpl::SetThumbnailContents(const wxWindow *child) SetThumbnailClip(child->GetRect()); } -bool wxTaskBarButtonImpl::AddThumbBarButton(wxThumbBarButton *button) +bool wxTaskBarButtonImpl::AppendThumbBarButton(wxThumbBarButton *button) { - wxCHECK( button != NULL, wxT("Can't add invalid wxThumbBarButton.") ); - if (m_thumbBarButtons.size() >= 7) + if ( m_thumbBarButtons.size() >= LIMITED_BUTTON_SIZE ) return false; m_thumbBarButtons.push_back(button); - return true; + return InitOrUpdateThumbBarButtons(); } -void wxTaskBarButtonImpl::ShowThumbnailToolbar() +bool wxTaskBarButtonImpl::InsertThumbBarButton(size_t pos, + wxThumbBarButton *button) { - if ( m_hasShownThumbnailToolbar || m_thumbBarButtons.empty() ) - return; + if ( m_thumbBarButtons.size() >= LIMITED_BUTTON_SIZE || + m_thumbBarButtons.size() < pos ) + return false; - THUMBBUTTON buttons[7]; + m_thumbBarButtons.insert(m_thumbBarButtons.begin() + pos, button); + return InitOrUpdateThumbBarButtons(); +} + +bool wxTaskBarButtonImpl::RemoveThumbBarButton(wxThumbBarButton *button) +{ + wxThumbBarButtons::iterator it; + for ( it = m_thumbBarButtons.begin(); it != m_thumbBarButtons.end(); ++it ) + { + if ( button == *it ) + { + m_thumbBarButtons.erase(it); + return InitOrUpdateThumbBarButtons(); + } + } + + return false; +} + +bool wxTaskBarButtonImpl::RemoveThumbBarButton(int id) +{ + wxThumbBarButtons::iterator it; + for ( it = m_thumbBarButtons.begin(); it != m_thumbBarButtons.end(); ++it ) + { + if ( id == (*it)->GetID() ) + { + m_thumbBarButtons.erase(it); + return InitOrUpdateThumbBarButtons(); + } + } + + return false; +} + +bool wxTaskBarButtonImpl::InitOrUpdateThumbBarButtons() +{ + THUMBBUTTON buttons[LIMITED_BUTTON_SIZE]; size_t i; + HRESULT hr; + + for ( i = 0; i < LIMITED_BUTTON_SIZE; ++i ) + { + memset(&buttons[i], 0, sizeof buttons[i]); + buttons[i].iId = i; + buttons[i].dwFlags = THBF_HIDDEN; + buttons[i].dwMask = THB_FLAGS; + } + 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].dwFlags = GetNativeThumbButtonFlags(*m_thumbBarButtons[i]); buttons[i].dwMask = THB_ICON | THB_FLAGS; wxString tooltip = m_thumbBarButtons[i]->GetTooltip(); if ( tooltip.empty() ) @@ -166,10 +250,37 @@ void wxTaskBarButtonImpl::ShowThumbnailToolbar() buttons[i].dwMask |= THB_TOOLTIP; } - m_taskbarList->ThumbBarAddButtons(m_hwnd, - m_thumbBarButtons.size(), - buttons); - m_hasShownThumbnailToolbar = true; + if ( !m_hasInitThumbnailToolbar ) + { + hr = m_taskbarList->ThumbBarAddButtons(m_hwnd, + LIMITED_BUTTON_SIZE, + buttons); + if ( FAILED(hr) ) + { + wxLogApiError(wxT("ITaskbarList3::ThumbBarAddButtons"), hr); + } + m_hasInitThumbnailToolbar = true; + } + else + { + hr = m_taskbarList->ThumbBarUpdateButtons(m_hwnd, + LIMITED_BUTTON_SIZE, + buttons); + if ( FAILED(hr) ) + { + wxLogApiError(wxT("ITaskbarList3::ThumbBarUpdateButtons"), hr); + } + } + + return SUCCEEDED(hr); +} + +int wxTaskBarButtonImpl::GetThumbBarButtonID(size_t index) +{ + if ( index >= m_thumbBarButtons.size() ) + return -1; + + return m_thumbBarButtons[index]->GetID(); } #endif // wxUSE_TASKBARBUTTON