diff --git a/include/wx/appprogress.h b/include/wx/appprogress.h index 7c29e98286..cda93729eb 100644 --- a/include/wx/appprogress.h +++ b/include/wx/appprogress.h @@ -17,6 +17,9 @@ class WXDLLIMPEXP_CORE wxAppProgressIndicatorBase public: wxAppProgressIndicatorBase() {} virtual ~wxAppProgressIndicatorBase() {} + + virtual bool IsAvailable() const = 0; + virtual void SetValue(int value) = 0; virtual void SetRange(int range) = 0; virtual void Pulse() = 0; @@ -28,6 +31,22 @@ private: #if defined(__WXMSW__) #include "wx/msw/appprogress.h" +#else + class wxAppProgressIndicator : public wxAppProgressIndicatorBase + { + public: + wxAppProgressIndicator(wxWindow* WXUNUSED(parent) = NULL, + int WXUNUSED(maxValue) = 100) + { + } + + virtual bool IsAvailable() const wxOVERRIDE { return false; } + + virtual void SetValue(int WXUNUSED(value)) wxOVERRIDE { } + virtual void SetRange(int WXUNUSED(range)) wxOVERRIDE { } + virtual void Pulse() wxOVERRIDE { } + virtual void Reset() wxOVERRIDE { } + }; #endif #endif // _WX_APPPROG_H_ diff --git a/include/wx/msw/appprogress.h b/include/wx/msw/appprogress.h index c8bcc902cd..4194e05aa7 100644 --- a/include/wx/msw/appprogress.h +++ b/include/wx/msw/appprogress.h @@ -21,6 +21,8 @@ public: wxAppProgressIndicator(wxWindow* parent = NULL, int maxValue = 100); virtual ~wxAppProgressIndicator(); + virtual bool IsAvailable() const wxOVERRIDE; + virtual void SetValue(int value) wxOVERRIDE; virtual void SetRange(int range) wxOVERRIDE; virtual void Pulse() wxOVERRIDE; diff --git a/interface/wx/appprogress.h b/interface/wx/appprogress.h index cc23d00bbb..6cc52d69e3 100644 --- a/interface/wx/appprogress.h +++ b/interface/wx/appprogress.h @@ -40,6 +40,17 @@ public: */ virtual ~wxAppProgressIndicator(); + /** + Check if the application progress display is available. + + Currently this only returns @true when using wxMSW and running under + Vista or later system, which provide task bar button API. + + If this method returns @false, no other methods of this class do + anything, but they may still be called without any ill effects. + */ + bool IsAvailable() const; + /** Set the progress value in taskbar button of parent window. diff --git a/samples/dialogs/dialogs.cpp b/samples/dialogs/dialogs.cpp index 8da5a08e69..7804fc425c 100644 --- a/samples/dialogs/dialogs.cpp +++ b/samples/dialogs/dialogs.cpp @@ -60,6 +60,8 @@ #include "wx/progdlg.h" #endif // wxUSE_PROGRESSDLG +#include "wx/appprogress.h" + #if wxUSE_ABOUTDLG #include "wx/aboutdlg.h" @@ -220,6 +222,8 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(DIALOGS_PROGRESS, MyFrame::ShowProgress) #endif // wxUSE_PROGRESSDLG + EVT_MENU(DIALOGS_APP_PROGRESS, MyFrame::ShowAppProgress) + #if wxUSE_ABOUTDLG EVT_MENU(DIALOGS_ABOUTDLG_SIMPLE, MyFrame::ShowSimpleAboutDialog) EVT_MENU(DIALOGS_ABOUTDLG_FANCY, MyFrame::ShowFancyAboutDialog) @@ -466,6 +470,8 @@ bool MyApp::OnInit() info_menu->Append(DIALOGS_PROGRESS, wxT("Pro&gress dialog\tCtrl-G")); #endif // wxUSE_PROGRESSDLG + info_menu->Append(DIALOGS_APP_PROGRESS, wxT("&App progress\tShift-Ctrl-G")); + #if wxUSE_BUSYINFO info_menu->Append(DIALOGS_BUSYINFO, wxT("&Busy info dialog\tCtrl-B")); #endif // wxUSE_BUSYINFO @@ -2268,6 +2274,29 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) ) #endif // wxUSE_PROGRESSDLG +void MyFrame::ShowAppProgress( wxCommandEvent& WXUNUSED(event) ) +{ + wxAppProgressIndicator progress(this); + if ( !progress.IsAvailable() ) + { + wxLogStatus("Progress indicator not available under this platform."); + return; + } + + wxLogStatus("Using application progress indicator..."); + + const int range = 10; + progress.SetRange(range); + for ( int i = 0; i < range; i++ ) + { + progress.SetValue(i); + + wxMilliSleep(500); + } + + wxLogStatus("Progress finished"); +} + #if wxUSE_ABOUTDLG static void InitAboutInfoMinimal(wxAboutDialogInfo& info) diff --git a/samples/dialogs/dialogs.h b/samples/dialogs/dialogs.h index e8e1703ea8..71f022161d 100644 --- a/samples/dialogs/dialogs.h +++ b/samples/dialogs/dialogs.h @@ -430,6 +430,7 @@ public: #if wxUSE_PROGRESSDLG void ShowProgress(wxCommandEvent& event); #endif // wxUSE_PROGRESSDLG + void ShowAppProgress(wxCommandEvent& event); #if wxUSE_ABOUTDLG void ShowSimpleAboutDialog(wxCommandEvent& event); @@ -570,6 +571,7 @@ enum DIALOGS_ONTOP, DIALOGS_MODELESS_BTN, DIALOGS_PROGRESS, + DIALOGS_APP_PROGRESS, DIALOGS_ABOUTDLG_SIMPLE, DIALOGS_ABOUTDLG_FANCY, DIALOGS_ABOUTDLG_FULL, diff --git a/src/msw/appprogress.cpp b/src/msw/appprogress.cpp index f23836bee1..2aaa4883dc 100644 --- a/src/msw/appprogress.cpp +++ b/src/msw/appprogress.cpp @@ -62,6 +62,11 @@ wxAppProgressIndicator::~wxAppProgressIndicator() #endif // wxUSE_TASKBARBUTTON } +bool wxAppProgressIndicator::IsAvailable() const +{ + return !m_taskBarButtons.empty(); +} + void wxAppProgressIndicator::SetValue(int value) { wxASSERT_MSG( value <= m_maxValue, wxT("invalid progress value") ); diff --git a/src/msw/taskbarbutton.cpp b/src/msw/taskbarbutton.cpp index 1bed644ae5..b063821103 100644 --- a/src/msw/taskbarbutton.cpp +++ b/src/msw/taskbarbutton.cpp @@ -696,32 +696,46 @@ bool wxThumbBarButton::UpdateParentTaskBarButton() // ---------------------------------------------------------------------------- // wxTaskBarButtonImpl Implementation. // ---------------------------------------------------------------------------- -wxTaskBarButtonImpl::wxTaskBarButtonImpl(wxWindow* parent) - : m_hwnd(parent->GetHandle()), - m_taskbarList(NULL), - m_progressRange(0), - m_hasInitThumbnailToolbar(false) + +/* static */ +wxTaskBarButton* wxTaskBarButton::New(wxWindow* parent) { + wxITaskbarList3* taskbarList = NULL; + HRESULT hr = CoCreateInstance ( wxCLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, wxIID_ITaskbarList3, - reinterpret_cast(&m_taskbarList) + reinterpret_cast(&taskbarList) ); if ( FAILED(hr) ) { - wxLogApiError(wxT("CoCreateInstance(wxCLSID_TaskbarList)"), hr); - return; + // Don't log this error, it may be normal when running under XP. + return NULL; } - hr = m_taskbarList->HrInit(); + hr = taskbarList->HrInit(); if ( FAILED(hr) ) { + // This is however unexpected. wxLogApiError(wxT("ITaskbarList3::Init"), hr); - return; + + taskbarList->Release(); + return NULL; } + + return new wxTaskBarButtonImpl(taskbarList, parent); +} + +wxTaskBarButtonImpl::wxTaskBarButtonImpl(wxITaskbarList3* taskbarList, + wxWindow* parent) + : m_hwnd(parent->GetHandle()), + m_taskbarList(taskbarList), + m_progressRange(0), + m_hasInitThumbnailToolbar(false) +{ } wxTaskBarButtonImpl::~wxTaskBarButtonImpl()