11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Runtime . InteropServices ;
45using System . Text ;
56using System . Windows . Forms ;
67
@@ -14,7 +15,47 @@ public static class ProgressManager {
1415 public static readonly IntPtr PBST_ERROR = ( IntPtr ) 2 ;
1516 public static readonly IntPtr PBST_PAUSED = ( IntPtr ) 3 ;
1617
18+ public enum TaskbarProgressBarState {
19+ NoProgress = 0 ,
20+ Indeterminate = 1 ,
21+ Normal = 2 ,
22+ Error = 4 ,
23+ Paused = 8
24+ }
25+
26+ [ ComImport , Guid ( "56FDF344-FD6D-11D0-958A-006097C9A090" ) , ClassInterface ( ClassInterfaceType . None ) ]
27+ private class ITaskbarList { }
28+
29+ [ ComImport , Guid ( "EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF" ) , InterfaceType ( ComInterfaceType . InterfaceIsIUnknown ) ]
30+ private interface ITaskbarList3 {
31+ // ITaskbarList
32+ void HrInit ( ) ;
33+ void AddTab ( IntPtr hwnd ) ;
34+ void DeleteTab ( IntPtr hwnd ) ;
35+ void ActivateTab ( IntPtr hwnd ) ;
36+ void SetActiveAlt ( IntPtr hwnd ) ;
37+
38+ // ITaskbarList2
39+ void MarkFullscreenWindow (
40+ IntPtr hwnd ,
41+
42+ [ MarshalAs ( UnmanagedType . Bool ) ]
43+ bool fFullscreen
44+ ) ;
45+
46+ // ITaskbarList3
47+ void SetProgressValue ( IntPtr hwnd , ulong ullCompleted , ulong ullTotal ) ;
48+ void SetProgressState ( IntPtr hwnd , TaskbarProgressBarState tbpFlags ) ;
49+ }
50+
51+ private static readonly ITaskbarList3 taskbarList = ( ITaskbarList3 ) new ITaskbarList ( ) ;
52+ private static readonly bool taskbarListSupported = Environment . OSVersion . Version >= new Version ( 6 , 1 ) ;
53+ private static bool taskbarListInitialized = false ;
54+
55+ const int VALUE_COMPLETE = 100 ;
56+
1757 private static ProgressBar progressBar = null ;
58+ private static Form progressForm = null ;
1859 private static ProgressBarStyle style = ProgressBarStyle . Marquee ;
1960 private static int value = 0 ;
2061 private static IntPtr state = PBST_NORMAL ;
@@ -256,6 +297,31 @@ public static ProgressBar ProgressBar {
256297 }
257298 }
258299
300+ public static Form ProgressForm {
301+ get {
302+ return progressForm ;
303+ }
304+
305+ set {
306+ progressForm = value ;
307+
308+ if ( progressForm == null ) {
309+ return ;
310+ }
311+
312+ if ( taskbarListSupported && ! taskbarListInitialized ) {
313+ try {
314+ taskbarList . HrInit ( ) ;
315+ taskbarListInitialized = true ;
316+ } catch { }
317+ }
318+
319+ Style = ProgressManager . style ;
320+ Value = ProgressManager . value ;
321+ State = ProgressManager . state ;
322+ }
323+ }
324+
259325 private static ProgressBarStyle Style {
260326 get {
261327 return ProgressManager . style ;
@@ -264,11 +330,25 @@ private static ProgressBarStyle Style {
264330 set {
265331 ProgressManager . style = value ;
266332
267- if ( ProgressBar = = null ) {
268- return ;
333+ if ( ProgressBar ! = null ) {
334+ ProgressBar . Style = ProgressManager . style ;
269335 }
270336
271- ProgressBar . Style = ProgressManager . style ;
337+ if ( ProgressForm != null ) {
338+ if ( ProgressForm . IsHandleCreated && ProgressForm . Handle != IntPtr . Zero ) {
339+ if ( taskbarListInitialized ) {
340+ if ( ProgressManager . style == ProgressBarStyle . Marquee ) {
341+ // error/paused states take priority over marquee style
342+ if ( ProgressManager . value < VALUE_COMPLETE && ProgressManager . state == PBST_NORMAL ) {
343+ taskbarList . SetProgressState ( ProgressForm . Handle , TaskbarProgressBarState . Indeterminate ) ;
344+ }
345+ } else {
346+ Value = ProgressManager . value ;
347+ State = ProgressManager . state ;
348+ }
349+ }
350+ }
351+ }
272352 }
273353 }
274354
@@ -280,11 +360,30 @@ private static int Value {
280360 set {
281361 ProgressManager . value = Math . Min ( 100 , Math . Max ( 0 , value ) ) ;
282362
283- if ( ProgressBar = = null ) {
284- return ;
363+ if ( ProgressBar ! = null ) {
364+ ProgressBar . Value = ProgressManager . value ;
285365 }
286366
287- ProgressBar . Value = ProgressManager . value ;
367+ if ( ProgressForm != null ) {
368+ if ( ProgressForm . IsHandleCreated && ProgressForm . Handle != IntPtr . Zero ) {
369+ if ( taskbarListInitialized ) {
370+ // marquee style takes priority over value (setting the value disables marquee style)
371+ if ( ProgressManager . style != ProgressBarStyle . Marquee || ProgressManager . state != PBST_NORMAL ) {
372+ // when reset to zero, update the state so the value can be set
373+ if ( ProgressManager . value == 0 ) {
374+ State = ProgressManager . state ;
375+ }
376+
377+ taskbarList . SetProgressValue ( ProgressForm . Handle , ( ulong ) ProgressManager . value , VALUE_COMPLETE ) ;
378+ }
379+
380+ // it is required to set the state to No Progress when completed
381+ if ( ProgressManager . value >= VALUE_COMPLETE ) {
382+ taskbarList . SetProgressState ( ProgressForm . Handle , TaskbarProgressBarState . NoProgress ) ;
383+ }
384+ }
385+ }
386+ }
288387 }
289388 }
290389
@@ -296,15 +395,30 @@ private static IntPtr State {
296395 set {
297396 ProgressManager . state = value ;
298397
299- if ( ProgressBar == null ) {
300- return ;
398+ if ( ProgressBar != null ) {
399+ if ( ProgressBar . IsHandleCreated && ProgressBar . Handle != IntPtr . Zero ) {
400+ SendMessage ( ProgressBar . Handle , PBM_SETSTATE , ProgressManager . state , IntPtr . Zero ) ;
401+ }
301402 }
302403
303- if ( ! ProgressBar . IsHandleCreated || ProgressBar . Handle == IntPtr . Zero ) {
304- return ;
404+ if ( ProgressForm != null ) {
405+ if ( ProgressForm . IsHandleCreated && ProgressForm . Handle != IntPtr . Zero ) {
406+ if ( taskbarListInitialized ) {
407+ if ( ProgressManager . value < VALUE_COMPLETE ) {
408+ if ( ProgressManager . state == PBST_NORMAL ) {
409+ // normal state does not take priority over marquee style
410+ if ( ProgressManager . style != ProgressBarStyle . Marquee ) {
411+ taskbarList . SetProgressState ( ProgressForm . Handle , TaskbarProgressBarState . Normal ) ;
412+ }
413+ } else if ( ProgressManager . state == PBST_ERROR ) {
414+ taskbarList . SetProgressState ( ProgressForm . Handle , TaskbarProgressBarState . Error ) ;
415+ } else if ( ProgressManager . state == PBST_PAUSED ) {
416+ taskbarList . SetProgressState ( ProgressForm . Handle , TaskbarProgressBarState . Paused ) ;
417+ }
418+ }
419+ }
420+ }
305421 }
306-
307- SendMessage ( ProgressBar . Handle , PBM_SETSTATE , ProgressManager . state , IntPtr . Zero ) ;
308422 }
309423 }
310424
0 commit comments