Opened 5 years ago

Closed 4 years ago

#11357 closed defect (fixed)

wxGauge shows no activity on Vista when in indeterminate mode

Reported by: talon_karrde Owned by:
Priority: normal Milestone: 2.9.1
Component: wxMSW Version: stable-latest
Keywords: wxGauge Pulse Vista indeterminate mode Cc:
Blocked By: Blocking:
Patch: yes

Description

wxGauge supposedly shows no activity on Vista when wxGauge::Pulse() is called.
This issue has been found and fixed by a colleague of mine some time ago and now I am merely propagating the fixes back to the public, so I don't really know for sure if this is the correct way to fix it. It does work for us, though, so I decided to post this patch and let you decide whether to integrate it or not.
This patch is made against the trunk.

Attachments (1)

wxGauge_Vista_indeterminate_mode_fix.patch download (1.0 KB) - added by talon_karrde 5 years ago.

Download all attachments as: .zip

Change History (14)

Changed 5 years ago by talon_karrde

comment:1 follow-up: Changed 5 years ago by vadz

I tested this under both Vista and Win7 and widgets sample seems to work ok for me. What problem exactly did you encounter?

OTOH the patch does seem to make sense...

comment:2 in reply to: ↑ 1 Changed 5 years ago by talon_karrde

Replying to vadz:

I tested this under both Vista and Win7 and widgets sample seems to work ok for me. What problem exactly did you encounter?

As far as I recall, the problem encountered was exactly what is mentioned in the description of the ticket - repeatedly calling wxGauge::Pulse() didn't result in any change/action in the UI.
To be a little more specific - one of our product uses wxGauge to display the progress of a task in a dialog. The task starts with an analysis stage and then proceeds to do some work. The duration of the analysis stage cannot be predicted, so we use the gauge in indeterminate mode at first and then switch to determinate mode. This worked flawlessly on XP, but when we run it on Vista we saw that the progress bar simply didn't do anything during the analysis stage, and all the code does is calling Pulse when a "heartbeat" event arrives.
Hope that helps.

comment:3 follow-up: Changed 5 years ago by vadz

  • Milestone set to 3.0

Can anyone else see this problem under Vista? For that matter, do you see this in the widgets sample or maybe it just doesn't do what it takes to show it?

Again, the patch seems reasonably but I'd just like to understand the problem better before applying it...

comment:4 in reply to: ↑ 3 Changed 5 years ago by talon_karrde

Replying to vadz:

Can anyone else see this problem under Vista? For that matter, do you see this in the widgets sample or maybe it just doesn't do what it takes to show it?

No, the gauge in the widgets sample is working just fine. And our code is using it in a pretty straight-forward manner, with the only difference that we first hide it after creation and then show it some time later, like this:

this->pProgressBar = new wxGauge(this, wxID_ANY, 100, wxDefaultPosition, ProgressBarSize, wxGA_HORIZONTAL | wxGA_SMOOTH);
this->pProgressBar->Show(false);
...
this->pProgressBar->Show();
this->pProgressBar->Pulse();

comment:5 follow-up: Changed 5 years ago by vadz

  • Status changed from new to infoneeded_new

I still can't reproduce the problem with this patch:

  • samples/minimal/minimal.cpp

    diff --git a/samples/minimal/minimal.cpp b/samples/minimal/minimal.cpp
    index 80bf766..1829861 100644
    a b bool MyApp::OnInit() 
    141141// main frame 
    142142// ---------------------------------------------------------------------------- 
    143143 
     144wxGauge *g; 
     145 
    144146// frame constructor 
    145147MyFrame::MyFrame(const wxString& title) 
    146148       : wxFrame(NULL, wxID_ANY, title) 
    MyFrame::MyFrame(const wxString& title) 
    172174    CreateStatusBar(2); 
    173175    SetStatusText("Welcome to wxWidgets!"); 
    174176#endif // wxUSE_STATUSBAR 
     177 
     178    new wxStaticText(this, -1, "&Label", wxPoint(10, 10)); 
     179    g = new wxGauge(this, -1, 100, wxPoint(80, 10), 
     180                    wxSize(200, -1), wxGA_HORIZONTAL | wxGA_SMOOTH); 
     181    g->Hide(); 
     182    g->Show(); 
    175183} 
    176184 
    177185 
    void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) 
    185193 
    186194void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) 
    187195{ 
     196    g->Pulse(); 
     197    return; 
     198 
    188199    wxMessageBox(wxString::Format 
    189200                 ( 
    190201                    "Welcome to %s!\n" 

It would be great if you could check if you can reproduce the bug by modifying this.

TIA!

comment:6 in reply to: ↑ 5 Changed 5 years ago by talon_karrde

  • Status changed from infoneeded_new to new

Replying to vadz:

It would be great if you could check if you can reproduce the bug by modifying this.

I'm really at a loss here. I modified the sample to be as identical to our application as possible (with a dialog as the progress bar's parent, a worker thread sending progress events at the same rate, using the same flags when creating windows, etc), but am still unable to reproduce the bug. The bug is still there in our app - I've rebuilt our 2.8 based libs without the fix and the progress bar shows no progress, but testing the modified minimal sample with those same libs doesn't result in the incorrect behaviour. FWIW, the bug only appears when using the Windows Vista theme, progress is correctly shown if the current theme is Windows Classic. Also, while looking closely at the bug, I noticed that some progress can actually be seen during several minute flickers, as if the progress bar is getting updated but an immediate redraw causes it to appear empty.

Anyway, I'm not sure there's more I can do to reproduce it, save for stripping our app's code to a minimum (which doesn't seem practical to me).

comment:7 Changed 5 years ago by vadz

I guess we should just apply the patch, I still feel uncomfortable not understanding why does it sometimes work and sometimes doesn't but fixing it to work in all cases is still arguably better.

I'll retest and apply it later, thanks for taking the time trying to reproduce the problem!

comment:8 Changed 5 years ago by mridang

Hi.
I've been having the same problem as talon_karrde here. I couldn't get it work under Windows 7 and my code was very, very simple.

I thought I was doing something wrong until I posted my question on StackOverflow. The post can be found here http://stackoverflow.com/questions/2856382/marquee-style-progressbar-in-wxpython.

comment:9 Changed 5 years ago by vadz

  • Milestone changed from 3.0 to 2.9.1
  • Status changed from new to confirmed

Ok, let's apply it and see if anybody complains with the new version.

comment:10 Changed 5 years ago by mridang

Thanks vadz!
Sorry to trouble you but could you tell me how I could apply this patch to wxPython so i can get this working until the 2.9.1 version is out. Please.

comment:11 Changed 5 years ago by vadz

You need to apply it to wxWidgets sources and rebuild wxPython.

comment:12 Changed 5 years ago by vadz

I've looked at the patch again and I actually have 2 questions about it:

  1. Why do we pass 60000 as LPARAM of PBM_SETMARQUEE? This means "update every minute" which doesn't make sense to me, it's either too short (if it's really going to update itself automatically even if we don't call Pulse()) or too long (if it's supposed to do something on its own even when we don't call Pulse()). MSDN doesn't say what should passing 0 here do but looking at some code using this message that I found this would seem to be a more appropriate value to use.
  2. Don't we need to also send PBM_SETMARQUEE with WPARAM of 0 in wxGauge::SetDeterminateMode() to turn the marquee mode off?

Thanks!

comment:13 Changed 4 years ago by VZ

  • Resolution set to fixed
  • Status changed from confirmed to closed

(In [64648]) Use PBM_SETMARQUEE to implement indeterminate mode in wxMSW wxGauge.

The old code which simply used PBM_SETPOS after setting PBS_MARQUEE style
often worked but sometimes apparently didn't, so switch to the officially
sanctioned PBM_SETMARQUEE to implement this.

Also make wxGauge::SetDeterminateMode() and SetIndeterminateMode() methods
private as they are not part of the public class API.

Closes #11357.

Note: See TracTickets for help on using tickets.