Make wxAppProgressIndicator actually usable.

First of all, do define it under non-MSW platforms.

Second, don't crash in it when running under XP where wxTaskBarButton is not
available.

Also add IsAvailable() method to check for its availability explicitly and add
a demonstration of this class to the dialogs sample.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@77706 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2014-09-14 23:58:26 +00:00
parent 03e245091f
commit 28516f5643
7 changed files with 92 additions and 10 deletions

View File

@@ -17,6 +17,9 @@ class WXDLLIMPEXP_CORE wxAppProgressIndicatorBase
public: public:
wxAppProgressIndicatorBase() {} wxAppProgressIndicatorBase() {}
virtual ~wxAppProgressIndicatorBase() {} virtual ~wxAppProgressIndicatorBase() {}
virtual bool IsAvailable() const = 0;
virtual void SetValue(int value) = 0; virtual void SetValue(int value) = 0;
virtual void SetRange(int range) = 0; virtual void SetRange(int range) = 0;
virtual void Pulse() = 0; virtual void Pulse() = 0;
@@ -28,6 +31,22 @@ private:
#if defined(__WXMSW__) #if defined(__WXMSW__)
#include "wx/msw/appprogress.h" #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
#endif // _WX_APPPROG_H_ #endif // _WX_APPPROG_H_

View File

@@ -21,6 +21,8 @@ public:
wxAppProgressIndicator(wxWindow* parent = NULL, int maxValue = 100); wxAppProgressIndicator(wxWindow* parent = NULL, int maxValue = 100);
virtual ~wxAppProgressIndicator(); virtual ~wxAppProgressIndicator();
virtual bool IsAvailable() const wxOVERRIDE;
virtual void SetValue(int value) wxOVERRIDE; virtual void SetValue(int value) wxOVERRIDE;
virtual void SetRange(int range) wxOVERRIDE; virtual void SetRange(int range) wxOVERRIDE;
virtual void Pulse() wxOVERRIDE; virtual void Pulse() wxOVERRIDE;

View File

@@ -40,6 +40,17 @@ public:
*/ */
virtual ~wxAppProgressIndicator(); 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. Set the progress value in taskbar button of parent window.

View File

@@ -60,6 +60,8 @@
#include "wx/progdlg.h" #include "wx/progdlg.h"
#endif // wxUSE_PROGRESSDLG #endif // wxUSE_PROGRESSDLG
#include "wx/appprogress.h"
#if wxUSE_ABOUTDLG #if wxUSE_ABOUTDLG
#include "wx/aboutdlg.h" #include "wx/aboutdlg.h"
@@ -220,6 +222,8 @@ wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_MENU(DIALOGS_PROGRESS, MyFrame::ShowProgress) EVT_MENU(DIALOGS_PROGRESS, MyFrame::ShowProgress)
#endif // wxUSE_PROGRESSDLG #endif // wxUSE_PROGRESSDLG
EVT_MENU(DIALOGS_APP_PROGRESS, MyFrame::ShowAppProgress)
#if wxUSE_ABOUTDLG #if wxUSE_ABOUTDLG
EVT_MENU(DIALOGS_ABOUTDLG_SIMPLE, MyFrame::ShowSimpleAboutDialog) EVT_MENU(DIALOGS_ABOUTDLG_SIMPLE, MyFrame::ShowSimpleAboutDialog)
EVT_MENU(DIALOGS_ABOUTDLG_FANCY, MyFrame::ShowFancyAboutDialog) 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")); info_menu->Append(DIALOGS_PROGRESS, wxT("Pro&gress dialog\tCtrl-G"));
#endif // wxUSE_PROGRESSDLG #endif // wxUSE_PROGRESSDLG
info_menu->Append(DIALOGS_APP_PROGRESS, wxT("&App progress\tShift-Ctrl-G"));
#if wxUSE_BUSYINFO #if wxUSE_BUSYINFO
info_menu->Append(DIALOGS_BUSYINFO, wxT("&Busy info dialog\tCtrl-B")); info_menu->Append(DIALOGS_BUSYINFO, wxT("&Busy info dialog\tCtrl-B"));
#endif // wxUSE_BUSYINFO #endif // wxUSE_BUSYINFO
@@ -2268,6 +2274,29 @@ void MyFrame::ShowProgress( wxCommandEvent& WXUNUSED(event) )
#endif // wxUSE_PROGRESSDLG #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 #if wxUSE_ABOUTDLG
static void InitAboutInfoMinimal(wxAboutDialogInfo& info) static void InitAboutInfoMinimal(wxAboutDialogInfo& info)

View File

@@ -430,6 +430,7 @@ public:
#if wxUSE_PROGRESSDLG #if wxUSE_PROGRESSDLG
void ShowProgress(wxCommandEvent& event); void ShowProgress(wxCommandEvent& event);
#endif // wxUSE_PROGRESSDLG #endif // wxUSE_PROGRESSDLG
void ShowAppProgress(wxCommandEvent& event);
#if wxUSE_ABOUTDLG #if wxUSE_ABOUTDLG
void ShowSimpleAboutDialog(wxCommandEvent& event); void ShowSimpleAboutDialog(wxCommandEvent& event);
@@ -570,6 +571,7 @@ enum
DIALOGS_ONTOP, DIALOGS_ONTOP,
DIALOGS_MODELESS_BTN, DIALOGS_MODELESS_BTN,
DIALOGS_PROGRESS, DIALOGS_PROGRESS,
DIALOGS_APP_PROGRESS,
DIALOGS_ABOUTDLG_SIMPLE, DIALOGS_ABOUTDLG_SIMPLE,
DIALOGS_ABOUTDLG_FANCY, DIALOGS_ABOUTDLG_FANCY,
DIALOGS_ABOUTDLG_FULL, DIALOGS_ABOUTDLG_FULL,

View File

@@ -62,6 +62,11 @@ wxAppProgressIndicator::~wxAppProgressIndicator()
#endif // wxUSE_TASKBARBUTTON #endif // wxUSE_TASKBARBUTTON
} }
bool wxAppProgressIndicator::IsAvailable() const
{
return !m_taskBarButtons.empty();
}
void wxAppProgressIndicator::SetValue(int value) void wxAppProgressIndicator::SetValue(int value)
{ {
wxASSERT_MSG( value <= m_maxValue, wxT("invalid progress value") ); wxASSERT_MSG( value <= m_maxValue, wxT("invalid progress value") );

View File

@@ -696,32 +696,46 @@ bool wxThumbBarButton::UpdateParentTaskBarButton()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxTaskBarButtonImpl Implementation. // wxTaskBarButtonImpl Implementation.
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
wxTaskBarButtonImpl::wxTaskBarButtonImpl(wxWindow* parent)
: m_hwnd(parent->GetHandle()), /* static */
m_taskbarList(NULL), wxTaskBarButton* wxTaskBarButton::New(wxWindow* parent)
m_progressRange(0),
m_hasInitThumbnailToolbar(false)
{ {
wxITaskbarList3* taskbarList = NULL;
HRESULT hr = CoCreateInstance HRESULT hr = CoCreateInstance
( (
wxCLSID_TaskbarList, wxCLSID_TaskbarList,
NULL, NULL,
CLSCTX_INPROC_SERVER, CLSCTX_INPROC_SERVER,
wxIID_ITaskbarList3, wxIID_ITaskbarList3,
reinterpret_cast<void **>(&m_taskbarList) reinterpret_cast<void **>(&taskbarList)
); );
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
wxLogApiError(wxT("CoCreateInstance(wxCLSID_TaskbarList)"), hr); // Don't log this error, it may be normal when running under XP.
return; return NULL;
} }
hr = m_taskbarList->HrInit(); hr = taskbarList->HrInit();
if ( FAILED(hr) ) if ( FAILED(hr) )
{ {
// This is however unexpected.
wxLogApiError(wxT("ITaskbarList3::Init"), hr); 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() wxTaskBarButtonImpl::~wxTaskBarButtonImpl()