From bff8421ed7b346ba046d169d7a09076117dc26b7 Mon Sep 17 00:00:00 2001 From: Artur Wieczorek Date: Wed, 4 Oct 2017 16:06:33 +0200 Subject: [PATCH] Fix setting icon for wxProgressDialog (wxMSW) Icon for wxProgressDialog cannot be changed directly because the dialog is created in another thread and may not yet exist when SetIcon() is called. We have to store new icon(s) in the data structure used to share data between the main thread and the task dialog runner and wait for a cyclic update. Closes #17967. --- include/wx/msw/progdlg.h | 2 ++ src/msw/progdlg.cpp | 43 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/include/wx/msw/progdlg.h b/include/wx/msw/progdlg.h index 4d5cd9f62e..57ef0357da 100644 --- a/include/wx/msw/progdlg.h +++ b/include/wx/msw/progdlg.h @@ -41,6 +41,8 @@ public: virtual void SetTitle(const wxString& title) wxOVERRIDE; virtual wxString GetTitle() const wxOVERRIDE; + virtual void SetIcons(const wxIconBundle& icons) wxOVERRIDE; + virtual bool Show( bool show = true ) wxOVERRIDE; // Must provide overload to avoid hiding it (and warnings about it) diff --git a/src/msw/progdlg.cpp b/src/msw/progdlg.cpp index 486a1cc063..6679ea2016 100644 --- a/src/msw/progdlg.cpp +++ b/src/msw/progdlg.cpp @@ -60,6 +60,7 @@ const int wxSPDD_DISABLE_SKIP = 0x0100; const int wxSPDD_DISABLE_ABORT = 0x0200; const int wxSPDD_FINISHED = 0x0400; const int wxSPDD_DESTROYED = 0x0800; +const int wxSPDD_ICON_CHANGED = 0x1000; const int Id_SkipBtn = wxID_HIGHEST + 1; @@ -95,6 +96,8 @@ public: wxString m_expandedInformation; wxString m_labelCancel; // Privately used by callback. unsigned long m_timeStop; + wxIcon m_iconSmall; + wxIcon m_iconBig; wxProgressDialog::State m_state; bool m_progressBarMarquee; @@ -213,6 +216,12 @@ void PerformNotificationUpdates(HWND hwnd, if ( sharedData->m_notifications & wxSPDD_TITLE_CHANGED ) ::SetWindowText( hwnd, sharedData->m_title.t_str() ); + if ( sharedData->m_notifications & wxSPDD_ICON_CHANGED ) + { + ::SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)GetHiconOf(sharedData->m_iconSmall)); + ::SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM)GetHiconOf(sharedData->m_iconBig)); + } + if ( sharedData->m_notifications & wxSPDD_MESSAGE_CHANGED ) { // Split the message in the title string and the rest if it has @@ -644,6 +653,40 @@ wxString wxProgressDialog::GetTitle() const return wxGenericProgressDialog::GetTitle(); } +void wxProgressDialog::SetIcons(const wxIconBundle& icons) +{ +#ifdef wxHAS_MSW_TASKDIALOG + if ( HasNativeTaskDialog() ) + { + m_icons = icons; // We can't just call to parent's SetIcons() + // (wxGenericProgressDialog::SetIcons == wxTopLevelWindowMSW::SetIcons) + // because it does too many things. + wxIcon iconSmall; + wxIcon iconBig; + if (!icons.IsEmpty()) + { + const wxSize sizeSmall(::GetSystemMetrics(SM_CXSMICON), ::GetSystemMetrics(SM_CYSMICON)); + iconSmall = icons.GetIcon(sizeSmall, wxIconBundle::FALLBACK_NEAREST_LARGER); + + const wxSize sizeBig(::GetSystemMetrics(SM_CXICON), ::GetSystemMetrics(SM_CYICON)); + iconBig = icons.GetIcon(sizeBig, wxIconBundle::FALLBACK_NEAREST_LARGER); + } + + if (m_sharedData) + { + wxCriticalSectionLocker locker(m_sharedData->m_cs); + m_sharedData->m_iconSmall = iconSmall; + m_sharedData->m_iconBig = iconBig; + m_sharedData->m_notifications |= wxSPDD_ICON_CHANGED; + } + + return; + } +#endif // wxHAS_MSW_TASKDIALOG + + wxGenericProgressDialog::SetIcons(icons); +} + bool wxProgressDialog::Show(bool show) { #ifdef wxHAS_MSW_TASKDIALOG