From 870051c76558a25ab6416929d7065a36da976366 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Sun, 19 Oct 2014 12:56:47 +0000 Subject: [PATCH] Handle taskbar button recreation better in wxMSW. Store the various parameters in wxTaskBarButton itself and reapply them when the button is (re)created. This fixes problems with getting the "taskbar button created" message twice, e.g. because Explorer was restarted, or getting it too late, as now wxTaskBarButton can be configured both before and after receiving this message. Closes #16566. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@78036 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/msw/taskbarbutton.h | 9 ++++++- include/wx/taskbarbutton.h | 1 + src/msw/frame.cpp | 11 ++++----- src/msw/taskbarbutton.cpp | 45 ++++++++++++++++++++++++++-------- 4 files changed, 49 insertions(+), 17 deletions(-) diff --git a/include/wx/msw/taskbarbutton.h b/include/wx/msw/taskbarbutton.h index 4ef0f609a6..ed24df01ed 100644 --- a/include/wx/msw/taskbarbutton.h +++ b/include/wx/msw/taskbarbutton.h @@ -44,18 +44,25 @@ public: virtual wxThumbBarButton* RemoveThumbBarButton(int id) wxOVERRIDE; wxThumbBarButton* GetThumbBarButtonByIndex(size_t index); bool InitOrUpdateThumbBarButtons(); + virtual void Realize() wxOVERRIDE; private: // This ctor is only used by wxTaskBarButton::New() wxTaskBarButtonImpl(wxITaskbarList3* taskbarList, wxWindow* parent); - WXHWND m_hwnd; + wxWindow* m_parent; wxITaskbarList3 *m_taskbarList; typedef wxVector wxThumbBarButtons; wxThumbBarButtons m_thumbBarButtons; int m_progressRange; + int m_progressValue; + wxTaskBarButtonState m_progressState; + wxString m_thumbnailTooltip; + wxIcon m_overlayIcon; + wxString m_overlayIconDescription; + wxRect m_thumbnailClipRect; bool m_hasInitThumbnailToolbar; friend wxTaskBarButton* wxTaskBarButton::New(wxWindow*); diff --git a/include/wx/taskbarbutton.h b/include/wx/taskbarbutton.h index 1652cc560f..68759d21f3 100644 --- a/include/wx/taskbarbutton.h +++ b/include/wx/taskbarbutton.h @@ -129,6 +129,7 @@ public: virtual bool AppendSeparatorInThumbBar() = 0; virtual wxThumbBarButton* RemoveThumbBarButton(wxThumbBarButton *button) = 0; virtual wxThumbBarButton* RemoveThumbBarButton(int id) = 0; + virtual void Realize() = 0; protected: wxTaskBarButton() { } diff --git a/src/msw/frame.cpp b/src/msw/frame.cpp index bc2db627fb..c60c93ff16 100644 --- a/src/msw/frame.cpp +++ b/src/msw/frame.cpp @@ -524,6 +524,9 @@ wxMenu* wxFrame::MSWFindMenuFromHMENU(WXHMENU hMenu) #if wxUSE_TASKBARBUTTON wxTaskBarButton* wxFrame::MSWGetTaskBarButton() { + if ( !m_taskBarButton ) + m_taskBarButton = wxTaskBarButton::New(this); + return m_taskBarButton; } #endif // wxUSE_TASKBARBUTTON @@ -991,12 +994,8 @@ WXLRESULT wxFrame::MSWWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lPara #if wxUSE_TASKBARBUTTON if ( message == wxMsgTaskbarButtonCreated ) { - if ( !m_taskBarButton ) - m_taskBarButton = wxTaskBarButton::New(this); - //else: If we get this message again, it may mean that our old taskbar - // button can't be used any more and needs to be recreated. We - // need to check whether this is really the case and sent a - // special event to allow the user code to react to this. + if ( m_taskBarButton ) + m_taskBarButton->Realize(); processed = true; } diff --git a/src/msw/taskbarbutton.cpp b/src/msw/taskbarbutton.cpp index b063821103..295ddab84f 100644 --- a/src/msw/taskbarbutton.cpp +++ b/src/msw/taskbarbutton.cpp @@ -731,9 +731,11 @@ wxTaskBarButton* wxTaskBarButton::New(wxWindow* parent) wxTaskBarButtonImpl::wxTaskBarButtonImpl(wxITaskbarList3* taskbarList, wxWindow* parent) - : m_hwnd(parent->GetHandle()), + : m_parent(parent), m_taskbarList(taskbarList), m_progressRange(0), + m_progressValue(0), + m_progressState(wxTASKBAR_BUTTON_NO_PROGRESS), m_hasInitThumbnailToolbar(false) { } @@ -752,6 +754,23 @@ wxTaskBarButtonImpl::~wxTaskBarButtonImpl() m_thumbBarButtons.clear(); } +void wxTaskBarButtonImpl::Realize() +{ + // (Re-)apply all settings: this is needed if settings were made before the + // create message was sent, taskbar icon is hidden and shown again or + // explorer is restarted + SetProgressRange(m_progressRange); + SetProgressState(m_progressState); + if ( m_progressValue > 0 ) + SetProgressValue(m_progressValue); + SetThumbnailTooltip(m_thumbnailTooltip); + SetOverlayIcon(m_overlayIcon, m_overlayIconDescription); + if ( !m_thumbnailClipRect.IsEmpty() ) + SetThumbnailClip(m_thumbnailClipRect); + m_hasInitThumbnailToolbar = false; + InitOrUpdateThumbBarButtons(); +} + void wxTaskBarButtonImpl::SetProgressRange(int range) { m_progressRange = range; @@ -761,7 +780,8 @@ void wxTaskBarButtonImpl::SetProgressRange(int range) void wxTaskBarButtonImpl::SetProgressValue(int value) { - m_taskbarList->SetProgressValue(m_hwnd, value, m_progressRange); + m_progressValue = value; + m_taskbarList->SetProgressValue(m_parent->GetHWND(), value, m_progressRange); } void wxTaskBarButtonImpl::PulseProgress() @@ -772,9 +792,9 @@ void wxTaskBarButtonImpl::PulseProgress() void wxTaskBarButtonImpl::Show(bool show) { if ( show ) - m_taskbarList->AddTab(m_hwnd); + m_taskbarList->AddTab(m_parent->GetHWND()); else - m_taskbarList->DeleteTab(m_hwnd); + m_taskbarList->DeleteTab(m_parent->GetHWND()); } void wxTaskBarButtonImpl::Hide() @@ -784,27 +804,32 @@ void wxTaskBarButtonImpl::Hide() void wxTaskBarButtonImpl::SetThumbnailTooltip(const wxString& tooltip) { - m_taskbarList->SetThumbnailTooltip(m_hwnd, tooltip.wc_str()); + m_thumbnailTooltip = tooltip; + m_taskbarList->SetThumbnailTooltip(m_parent->GetHWND(), tooltip.wc_str()); } void wxTaskBarButtonImpl::SetProgressState(wxTaskBarButtonState state) { - m_taskbarList->SetProgressState(m_hwnd, static_cast(state)); + m_progressState = state; + m_taskbarList->SetProgressState(m_parent->GetHWND(), static_cast(state)); } void wxTaskBarButtonImpl::SetOverlayIcon(const wxIcon& icon, const wxString& description) { - m_taskbarList->SetOverlayIcon(m_hwnd, + m_overlayIcon = icon; + m_overlayIconDescription = description; + m_taskbarList->SetOverlayIcon(m_parent->GetHWND(), GetHiconOf(icon), description.wc_str()); } void wxTaskBarButtonImpl::SetThumbnailClip(const wxRect& rect) { + m_thumbnailClipRect = rect; RECT rc; wxCopyRectToRECT(rect, rc); - m_taskbarList->SetThumbnailClip(m_hwnd, rect.IsEmpty() ? NULL : &rc); + m_taskbarList->SetThumbnailClip(m_parent->GetHWND(), rect.IsEmpty() ? NULL : &rc); } void wxTaskBarButtonImpl::SetThumbnailContents(const wxWindow *child) @@ -921,7 +946,7 @@ bool wxTaskBarButtonImpl::InitOrUpdateThumbBarButtons() if ( !m_hasInitThumbnailToolbar ) { - hr = m_taskbarList->ThumbBarAddButtons(m_hwnd, + hr = m_taskbarList->ThumbBarAddButtons(m_parent->GetHWND(), MAX_BUTTON_COUNT, buttons); if ( FAILED(hr) ) @@ -932,7 +957,7 @@ bool wxTaskBarButtonImpl::InitOrUpdateThumbBarButtons() } else { - hr = m_taskbarList->ThumbBarUpdateButtons(m_hwnd, + hr = m_taskbarList->ThumbBarUpdateButtons(m_parent->GetHWND(), MAX_BUTTON_COUNT, buttons); if ( FAILED(hr) )