Page 1 of 2
ProgressBarGadget on Vista bug?
Posted: Thu Aug 28, 2008 10:35 am
by whertz
It seems the progressbargadget does not get updated properly on Windows Vista. The following code works properly on XP with or without the XP skins mode selected, but on Vista the bar only goes about a quarter of the way up. On XP the bar goes all the way to the top. If you compile without XP skins support, it does work on Vista. Anyone know of a solution? I think the problem lies with adding items to the listicongadget, if you comment it out, the bar works properly. Here's the code:
Code: Select all
Procedure addtolist()
For n2=0 To 150
AddGadgetItem(1,-1,Str(Random(10000)))
Next n2
EndProcedure
If OpenWindow(0, 0, 0, 600, 100, "ProgressBarGadget Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ListIconGadget(1,10,10,580,80,"",100)
ProgressBarGadget(0, 10, 40, 580, 20, 0, 200)
HideGadget(1,1)
For n=0 To 200
addtolist()
SetGadgetState(0,n)
While WindowEvent():Wend
Next n
HideGadget(0,1)
HideGadget(1,0)
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Posted: Thu Aug 28, 2008 10:47 am
by srod
Take away the HideGadget(0,1) and it works fine here on Vista with xp themes enabled or not. I did have to move the progress bar because it does sit atop the listicon!
Posted: Thu Aug 28, 2008 10:56 am
by whertz
srod wrote:Take away the HideGadget(0,1) and it works fine here on Vista with xp themes enabled or not. I did have to move the progress bar because it does sit atop the listicon!
Thanks srod, but I want the listicongadget hidden while I add items to it, so your solution does not work for me.
Posted: Thu Aug 28, 2008 11:02 am
by srod
Sorry, I see what you're after.
Yes, not a PB bug as such; a Vista peculiarity. The fact is that the progress bar is being updated faster than the system can redraw. Stick in a sizeable delay and all works fine. There must be a better way though...
Posted: Thu Aug 28, 2008 11:09 am
by whertz
Yes, adding a delay works to an extent. The bar still doesn't go all the way to the top, there's still a bit to go! But this way is bad anyway, because I'm adding a lot of items and doing other stuff when adding to the listicongadget, so any delay is not good.
Posted: Thu Aug 28, 2008 12:00 pm
by srod
Right, after much poking and prodding I can see what is happening. Because of the visual style applied to the progress bar under Vista (the marquee type effect), the rendering of the actual bar can lag behind the actual position of the slider etc. What Windows does is 'buffer' the drawing and sets up a timer in order to complete the drawing in stages.
Now, your code has no way of knowing when this timer completes and so is issuing the HideGadget() command too early. What we need is some way of determining when this damn timer ends and that is a problem! (Of course a nice message sent from the progress bar to inform us of the completion of this buffered drawing would be nice!)
I have confirmed this by a manual count of the number of times the timer is called etc. and then hidden the progress bar. This works fine, but we cannot rely upon a manual count. Let me try something else...
Posted: Thu Aug 28, 2008 12:11 pm
by srod
Okay, a complete and total utter hack in which I set up a timer to monitor the timer created by Windows in order to complete the painting of the progressbar!

We are snooping upon the snooper!
If this doesn't run in other versions of Windows then you'll need some conditional code to take account of this.
Code: Select all
Global oldProc, progressFlag
Procedure progressCallback(hWnd, uMsg, wParam, lParam)
Protected result = CallWindowProc_(oldProc, hWnd, uMsg, wParam, lParam)
Static count
Select uMsg
Case #WM_PAINT
If GetGadgetState(0) = 200
;Create a timer to monitor the 'other' timer!
SetTimer_(hWnd, 100, 10, 0)
EndIf
Case #WM_TIMER
If wParam = 100 ;This is our timer.
count+1 ;A count of the number of times this timer is called consecutively.
Else
count=0
EndIf
If count = 10 ;Should be enough to determine that the 'other' timer has completed. Increase this value if you get problems.
KillTimer_(hWnd, 100)
count = 0
HideGadget(0,1)
HideGadget(1,0)
EndIf
EndSelect
ProcedureReturn result
EndProcedure
Procedure addtolist()
For n2=0 To 150
AddGadgetItem(1,-1,Str(Random(10000)))
Next n2
EndProcedure
If OpenWindow(0, 0, 0, 600, 100, "ProgressBarGadget Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
ListIconGadget(1,10,10,580,80,"",100)
ProgressBarGadget(0, 10, 40, 580, 20, 0, 200)
oldProc = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @progressCallback())
HideGadget(1,1)
For n=0 To 200
addtolist()
SetGadgetState(0,n)
Next n
Repeat : Until WaitWindowEvent()=#PB_Event_CloseWindow
EndIf
Posted: Thu Aug 28, 2008 1:34 pm
by Sparkie
Another option might be to remove the theme from the ProgressBarGadget...
Code: Select all
If OSVersion() >= #PB_OS_Windows_Vista
SetWindowTheme_(GadgetID(0), @null.w, @null.w)
EndIf
Posted: Thu Aug 28, 2008 1:37 pm
by srod
Yes, I was thinking about that; but to have all that lovely Vista gloss, ...and then remove it!

Posted: Thu Aug 28, 2008 1:41 pm
by Sparkie
gloss, schmoss....I'll take quick and clean everytime

Posted: Thu Aug 28, 2008 1:52 pm
by srod
What, even if it looks like something which fell from fangbeast's left nostril?

Posted: Thu Aug 28, 2008 2:01 pm
by Derek
Without the gloss and slowness we might as well be using XP.

Posted: Thu Aug 28, 2008 2:05 pm
by srod
You don't think XP is faster than Vista then?
Posted: Thu Aug 28, 2008 3:40 pm
by Derek
Yeah, I was trying to say that xp + gloss + slowness (is that a word) = vista.

Posted: Thu Aug 28, 2008 3:41 pm
by srod
Oops, sorry; I think you said it clearly enough! srod = daft twit!
