[Windows 7] SetTaskbarProgress

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

[Windows 7] SetTaskbarProgress

23 Jun 2015, 23:52

Hey all,

I edited Lexikos' SetTaskbarProgress() function seen here:
SetTaskbarProgress(pct[, state, hwnd])
Accesses Windows 7's ability to display a progress bar behind a taskbar button.
http://www.autohotkey.com/board/topic/4 ... rprogress/
to work with Unicode 64bit, Unicode 32bit, Ansi 32bit, and Basic/Classic (1.0.48.5)

I'm no expert so please let me know if you have issues (or a better way to accomplish this) but it works for me (win7 and win8.1):
Edit: per lexikos' recommendations:

Code: Select all

; SetTaskbarProgress  -  Windows 7+
;  by lexikos, modified by gwarble for U64,U32,A32 compatibility
;
; pct    -  A number between 0 and 100 or a state value (see below).
; state  -  "N" (normal), "P" (paused), "E" (error) or "I" (indeterminate).
;           If omitted (and pct is a number), the state is not changed.
; hwnd   -  The hWnd of the window which owns the taskbar button.
;           If omitted, the Last Found Window is used.
;
SetTaskbarProgress(pct, state="", hwnd="") {
 static tbl, s0:=0, sI:=1, sN:=2, sE:=4, sP:=8
 if !tbl
  Try tbl := ComObjCreate("{56FDF344-FD6D-11d0-958A-006097C9A090}"
                        , "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}")
  Catch 
   Return 0
 If hwnd =
  hwnd := WinExist()
 If pct is not number
  state := pct, pct := ""
 Else If (pct = 0 && state="")
  state := 0, pct := ""
 If state in 0,I,N,E,P
  DllCall(NumGet(NumGet(tbl+0)+10*A_PtrSize), "uint", tbl, "uint", hwnd, "uint", s%state%)
 If pct !=
  DllCall(NumGet(NumGet(tbl+0)+9*A_PtrSize), "uint", tbl, "uint", hwnd, "int64", pct*10, "int64", 1000)
Return 1
}
Example:

Code: Select all

Gui, Font, s15
Gui, Add, Text,, % "This GUI should show a progress bar on its taskbar button.`n"
                 . "It will demonstrate the four different progress states:`n"
                 . "(N)ormal, (P)aused, (E)rror and (I)ndeterminate."
Gui, Show        ; Show the window and taskbar button.
Gui, +LastFound  ; SetTaskbarProgress will use this window.

Loop
{
    progress_states=NPE
    Loop, Parse, progress_states
    {
        SetTaskbarProgress(0, A_LoopField)
        Loop 50 {
            SetTaskbarProgress(A_Index*2)
            Sleep 50
        }
        Sleep 1000
        Loop 50 {
            SetTaskbarProgress(100-A_Index*2)
            Sleep 50
        }
        SetTaskbarProgress(0)
        Sleep 1000
    }
    SetTaskbarProgress("I")
    Sleep 4000
}
GuiClose:
GuiEscape:
ExitApp

- gwarble
Last edited by gwarble on 08 Jul 2015, 13:54, edited 4 times in total.
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: [Windows 7] SetTaskbarProgress

24 Jun 2015, 01:55

Parameters to which you pass a pointer should be "ptr", not "uint", although it doesn't matter in practice.

Parameters which return a pointer via the * suffix must be "ptr*", not "uint*", otherwise any addresses >= 2**32 will be truncated.

If you're desperate for v1.0.48.05 compatibility, you can put the type name in a variable dependent on the value of A_PtrSize. If A_PtrSize is non-empty, "Ptr" is supported: ptr := A_PtrSize ? "ptr" : "uint", then use ptr or ptr "*".
(((A_PtrSize=4) OR (A_AhkVersion < 1.1)) ? 4 : 8)
I would use (A_PtrSize ? A_PtrSize : 4).
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: [Windows 7] SetTaskbarProgress

24 Jun 2015, 10:39

Thanks for the tips... updated first post
Basic/Classic support is not imperative, but someone might benefit from it so I left it in

Edit: I broke (I)ndeterminate mode somehow... will investigate [Edit: somehow I broke windows, because even going back to the original function it won't show the Indeterminate version anymore]

Edit: [Solved indeterminate not working] from stack overflow:
Okay, it looks like it was a problem with the configuration of my system. I post the answer here because it's not obvious why one progress bar animation would work but not another.

In System Properties / Performance Options, I had "Animations in the taskbar and Start Menu" disabled. This option apparently disables the "indeterminate" animation but not the regular one. By re-enabling the option, the indeterminate animation works.
Last edited by gwarble on 24 Jun 2015, 18:00, edited 2 times in total.
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
Flipeador
Posts: 1204
Joined: 15 Nov 2014, 21:31
Location: Argentina
Contact:

Re: [Windows 7] SetTaskbarProgress

24 Jun 2015, 17:03

with permission.

Code: Select all

Gui, Font, s15
Gui, Add, Text,, % "------------------------------------------------------"
Gui, Show
Gui, +LastFound +HWND_G
 
SetTaskbarProgress( 0, _G )
Sleep 100
Loop, 50 {
	SetTaskbarProgress( A_Index, _G )
	Sleep 50
}
Sleep 100
SetTaskbarProgress( "Paused", _G )
Sleep, 1000
SetTaskbarProgress( "Normal", _G )
Sleep, 1000
Loop, 49 {
	SetTaskbarProgress( A_Index * 2, _G )
	Sleep 100
}
Sleep 100
SetTaskbarProgress( "Error", _G )
Sleep 1000
SetTaskbarProgress( "Indeterminate", _G )
Sleep 1000
ExitApp
Esc::ExitApp

;###############################################################
;SetTaskbarProgress( [0~100 | Normal, Paused, Indeterminate, Error], [Win ID] )
SetTaskbarProgress(State, hWnd := "") { ;http://ahkscript.org/boards/viewtopic.php?p=48299#p48299
	static ppv
	if !ppv
		DllCall("ole32.dll\OleInitialize", "PtrP", 0)
		, VarSetCapacity(CLSID, 16), VarSetCapacity(riid, 16)
		, DllCall("ole32.dll\CLSIDFromString", "Str", "{56FDF344-FD6D-11d0-958A-006097C9A090}", "Ptr", &CLSID)
		, DllCall("ole32.dll\CLSIDFromString", "Str", "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}", "Ptr", &riid)
		, DllCall("ole32.dll\CoCreateInstance", "Ptr", &CLSID, "Ptr", 0, "UInt", 21, "Ptr", &riid, "PtrP", ppv)
	hWnd := hWnd ? hWnd : IsWindow()
	s0 := 0, sI := sIndeterminate := 1, sN := sNormal := 2, sE := sError := 4, sP := sPaused := 8
	if InVar( State, "0,N,P,E,I,Normal,Paused,Error,Indeterminate" )
		return DllCall(NumGet(NumGet(ppv+0)+10*A_PtrSize), "Ptr", ppv, "Ptr", hWnd, "UInt", s%State%)
	return DllCall(NumGet(NumGet(ppv+0)+9*A_PtrSize), "Ptr", ppv, "Ptr", hWnd, "Int64", State * 10, "Int64", 1000)
}

;If [var] in [ .. ]
InVar(Haystack, Needle, Delimiter := ",", OmitChars := "") {
	Loop, Parse, % Needle, %Delimiter%, %OmitChars%
		if (A_LoopField = Haystack)
			return 1
	return 0
}

IsWindow(hWnd*) {
	if !hWnd.MaxIndex()
		return DllCall("User32.dll\GetForegroundWindow")
	return i := DllCall("User32.dll\IsWindow", "Ptr", hWnd[1] )
		, ErrorLevel := !i
}
untested.
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: [Windows 7] SetTaskbarProgress

24 Jun 2015, 17:55

Thanks, but what's the difference (besides accepting full state names instead of just first initial, and not working in Ansi32bit or Basic)
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: [Windows 7] SetTaskbarProgress

24 Jun 2015, 20:28

If you don't mind sacrificing v1.0.48.05 support, you don't need to call OleInitialize(); AutoHotkey v1.1 does it on startup.

Also, you can use ComObjCreate instead of calling CoCreateInstance directly, which also means you don't need SetTaskbarProgress_COM_GUID4String.

Code: Select all

tbl := ComObjCreate("{56FDF344-FD6D-11d0-958A-006097C9A090}", "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}")
Use try/catch instead of checking the HRESULT.
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: [Windows 7] SetTaskbarProgress

24 Jun 2015, 22:31

Thanks again for the tips...
Did I do the Try/Catch appropriately?
- gwarble

Code: Select all

; SetTaskbarProgress  -  Windows 7+
;  by lexikos, modified by gwarble for U64,U32,A32 compatibility
;
; pct    -  A number between 0 and 100 or a state value (see below).
; state  -  "N" (normal), "P" (paused), "E" (error) or "I" (indeterminate).
;           If omitted (and pct is a number), the state is not changed.
; hwnd   -  The hWnd of the window which owns the taskbar button.
;           If omitted, the Last Found Window is used.
;
SetTaskbarProgress(pct, state="", hwnd="") {
 static tbl, s0:=0, sI:=1, sN:=2, sE:=4, sP:=8
 if !tbl
  Try tbl := ComObjCreate("{56FDF344-FD6D-11d0-958A-006097C9A090}"
                        , "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}")
  Catch 
   Return 0
 If hwnd =
  hwnd := WinExist()
 If pct is not number
  state := pct, pct := ""
 Else If (pct = 0 && state="")
  state := 0, pct := ""
 If state in 0,I,N,E,P
  DllCall(NumGet(NumGet(tbl+0)+10*A_PtrSize), "uint", tbl, "uint", hwnd, "uint", s%state%)
 If pct !=
  DllCall(NumGet(NumGet(tbl+0)+9*A_PtrSize), "uint", tbl, "uint", hwnd, "int64", pct*10, "int64", 1000)
Return 1
}
Last edited by gwarble on 25 Jun 2015, 09:56, edited 2 times in total.
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: [Windows 7] SetTaskbarProgress

25 Jun 2015, 01:40

Yes, assuming you want the function to just do nothing on failure.
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: [Windows 7] SetTaskbarProgress

08 Jul 2015, 13:52

Forum had a brain freeze last week I guess and we lost some of the replies... here is the Basic/Classic compatible version just in case anyone is looking for it, and I've put the concise version that works in A32, U32, U64 in the first post...

Thanks for all the help

Code: Select all

; SetTaskbarProgress  -  Requires Windows 7+
;  by lexikos, modified by gwarble for U64,U32,A32,Basic compatibility
;
; pct    -  A number between 0 and 100 or a state value (see below).
; state  -  "N" (normal), "P" (paused), "E" (error) or "I" (indeterminate).
;           If omitted (and pct is a number), the state is not changed.
; hwnd   -  The ID of the window which owns the taskbar button.
;           If omitted, the Last Found Window is used.
;
;
SetTaskbarProgress(pct, state="", hwnd="")
{
    static tbl, s0:=0, sI:=1, sN:=2, sE:=4, sP:=8
    if !tbl
    {
        DllCall("ole32\OleInitialize", "Uint", 0) ;COM_Init() ; Create a TaskbarList object with ITaskbarList3 interface:
        if DllCall("ole32\CoCreateInstance", "uint", SetTaskbarProgress_COM_GUID4String(CLSID,"{56FDF344-FD6D-11d0-958A-006097C9A090}"), "uint", 0, "uint", 21, "uint", SetTaskbarProgress_COM_GUID4String(IID,"{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}"), "ptr*", tbl) != 0
         Return     ;MsgBox 16,, Error creating TaskbarList object. Is this script running on Windows 7? Exiting.
    }
    if hwnd =
        hwnd := WinExist()
    if pct is not number
        state := pct, pct := ""
    else if (pct = 0 && state="")
        state := 0, pct := ""
    if state in 0,I,N,E,P   ; ITaskbarList3::SetProgressState
        DllCall(NumGet(NumGet(tbl+0)+10*(A_PtrSize ? A_PtrSize : 4)), "uint", tbl, "uint", hwnd, "uint", s%state%)
    if pct !=               ; ITaskbarList3::SetProgressValue
        DllCall(NumGet(NumGet(tbl+0)+9*(A_PtrSize ? A_PtrSize : 4)), "uint", tbl, "uint", hwnd, "int64", pct*10, "int64", 1000)
}
 
SetTaskbarProgress_COM_GUID4String(ByRef CLSID, String)
{
        Ptr := A_PtrSize ? "Ptr" : "UInt" ; If A_PtrSize is not defined, use UInt instead.
	VarSetCapacity(CLSID, 16)
	If A_IsUnicode
         DllCall("ole32\CLSIDFromString", Ptr, &String, Ptr, &CLSID)
	Else
        {
	 VarSetCapacity(wString, 38 * 2 + 1) ; COM_Unicode4Ansi()
	 DllCall("kernel32\MultiByteToWideChar", "Uint", 0, "Uint", 0, Ptr, &String, "int", -1, Ptr, &wString, "int", 38 + 1)
         DllCall("ole32\CLSIDFromString", Ptr, &wString, Ptr, &CLSID)
        }
	Return	&CLSID
}
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
Joe Glines
Posts: 770
Joined: 30 Sep 2013, 20:49
Location: Dallas
Contact:

Re: [Windows 7] SetTaskbarProgress

16 Jul 2015, 06:14

This is very cool! At first I was thinking about only using it for a progress bar, but it also donned on my I can use it to "flash" (put settings to zero and 100 in a loop). Does a great job telling you a given program needs "attention". Very slick! :)
Sign-up for the 🅰️HK Newsletter

ImageImageImageImage:clap:
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey :ugeek:
YouTube

:thumbup: Quick Access Popup, the powerful Windows folders, apps and documents launcher!
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: [Windows 7] SetTaskbarProgress

17 Jul 2015, 18:14

Joetazz, that's what FlashWindow is for.

Code: Select all

DllCall("FlashWindow", "ptr", WinExist(WinTitle), "int", true)
Not as effective as alternating colours, but at least it's consistent with other applications, and works on XP.
User avatar
Joe Glines
Posts: 770
Joined: 30 Sep 2013, 20:49
Location: Dallas
Contact:

Re: [Windows 7] SetTaskbarProgress

17 Jul 2015, 18:54

@lexikos- Thank you for pointing this out! :) BTW- in case anyone else runs into this issue, the script didn't work on my computer until I re-enabled "Use Visual styles on windows buttons" under Performance settings on System properties-->Advanced-->Settings.
Sign-up for the 🅰️HK Newsletter

ImageImageImageImage:clap:
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey :ugeek:
YouTube

:thumbup: Quick Access Popup, the powerful Windows folders, apps and documents launcher!
User avatar
TheDewd
Posts: 1510
Joined: 19 Dec 2013, 11:16
Location: USA

Re: [Windows 7] SetTaskbarProgress

08 Feb 2017, 11:37

I tried to simplify the function... Is there anything wrong with my setup below?:

Example:

Code: Select all

#SingleInstance, Force
Gui, +LastFound -Resize +HwndMyGui
Gui, Margin, 10, 10
Gui, Add, Button, xm ym w120 h26 gControlHandler vO, NoProgress
Gui, Add, Button, xp y+10 wp hp gControlHandler vI, Indeterminate
Gui, Add, Button, xp y+10 wp hp gControlHandler vN, Normal
Gui, Add, Button, xp y+10 wp hp gControlHandler vE, Error
Gui, Add, Button, xp y+10 wp hp gControlHandler vP, Paused
Gui, Add, Slider, x+10 ym w240 Range1-100 Line TickInterval10 ToolTip gControlHandler vValue,
Gui, Show, AutoSize, Example
return

ControlHandler:
    Gui, Submit, NoHide
    
    If (State = "") {
        State := "O"
    }
    
    If (StrLen(A_GuiControl) = 1) {
        State := A_GuiControl
    }
    
    If (A_GuiControl = "O") {
        SetTaskbarProgress()
    } Else If (A_GuiControl = "I") {
        SetTaskbarProgress("I")
    } Else If (A_GuiControl = "N") {
        SetTaskbarProgress("N", Value)
    } Else If (A_GuiControl = "E") {
        SetTaskbarProgress("E", Value)
    } Else If (A_GuiControl = "P") {
        SetTaskbarProgress("P", Value)
    } Else If (A_GuiControl = "Value") {
        If (State != "I" && State != "O") {
            SetTaskbarProgress(State, Value)
        }
    }
return

SetTaskbarProgress(State := "", Value := "", Hwnd := "") {
    Static TBL := ""

    If (!TBL) {
        Try {
            TBL := ComObjCreate("{56FDF344-FD6D-11D0-958A-006097C9A090}", "{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}")
        }
    }

    State := (State = "I" ? 1 : State = "N" ? 2 : State = "E" ? 4 : State = "P" ? 8 : 0)
    Hwnd := (Hwnd = "" ? WinExist() : Hwnd)

    DllCall(NumGet(NumGet(TBL + 0) + 10 * A_PtrSize), "Ptr", TBL, "Ptr", Hwnd, "UInt", State)

    If (Value != "") {
        DllCall(NumGet(NumGet(TBL + 0) + 9 * A_PtrSize), "Ptr", TBL, "Ptr", Hwnd, "Int64", Value, "Int64", 100)
    }

    return (TBL ? 0 : 1)
}
Function:

Code: Select all

SetTaskbarProgress(State := "", Value := "", Hwnd := "") {
    Static TBL := ""

    If (!TBL) {
        Try TBL := ComObjCreate("{56FDF344-FD6D-11D0-958A-006097C9A090}", "{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}")
    }

    State := (State = "I" ? 1 : State = "N" ? 2 : State = "E" ? 4 : State = "P" ? 8 : 0)
    Hwnd := (Hwnd = "" ? WinExist() : Hwnd)

    DllCall(NumGet(NumGet(TBL + 0) + 10 * A_PtrSize), "Ptr", TBL, "Ptr", Hwnd, "UInt", State)

    If (Value != "") {
        DllCall(NumGet(NumGet(TBL + 0) + 9 * A_PtrSize), "Ptr", TBL, "Ptr", Hwnd, "Int64", Value, "Int64", 100)
    }

    return (TBL ? 0 : 1)
}
Edit: Changed "UInt" to "Ptr".
Last edited by TheDewd on 09 Feb 2017, 08:19, edited 2 times in total.
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: [Windows 7] SetTaskbarProgress

09 Feb 2017, 02:49

Not wrong, but the first 2 params should be ptr

Code: Select all

HRESULT ( STDMETHODCALLTYPE *SetProgressValue )(     // int
	__RPC__in ITaskbarList3 * This,                  // ptr
	/* [in] */ __RPC__in HWND hwnd,                  // ptr
	/* [in] */ ULONGLONG ullCompleted,               // int64
	/* [in] */ ULONGLONG ullTotal);                  // int64

HRESULT ( STDMETHODCALLTYPE *SetProgressState )(     // int
	__RPC__in ITaskbarList3 * This,                  // ptr
	/* [in] */ __RPC__in HWND hwnd,                  // ptr
	/* [in] */ TBPFLAG tbpFlags);                    // int
ShObjIdl.h
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
p0p0v
Posts: 4
Joined: 13 Apr 2017, 14:45

Re: [Windows 7] SetTaskbarProgress

14 Apr 2017, 07:30

Hi
with windows 7 works great , but on windows 10 i havnt any button on taskbar :(

can this work for windows 8/10 ?
User avatar
Joe Glines
Posts: 770
Joined: 30 Sep 2013, 20:49
Location: Dallas
Contact:

Re: [Windows 7] SetTaskbarProgress

14 Apr 2017, 09:08

@p0p0v It works for me just fine on Windows 10
Sign-up for the 🅰️HK Newsletter

ImageImageImageImage:clap:
AHK Tutorials:Web Scraping | | Webservice APIs | AHK and Excel | Chrome | RegEx | Functions
Training: AHK Webinars Courses on AutoHotkey :ugeek:
YouTube

:thumbup: Quick Access Popup, the powerful Windows folders, apps and documents launcher!
p0p0v
Posts: 4
Joined: 13 Apr 2017, 14:45

Re: [Windows 7] SetTaskbarProgress

15 Apr 2017, 08:45

i used

Code: Select all

WinSet, ExStyle, ^0x80
to hide gui from "alt-tab" menu
but on windows 10 this hide button from taskbar too :((((

sorry for desinformation

Help me please to hide window in this example from alt+tab but show button on tasbar...
User avatar
Maestr0
Posts: 136
Joined: 05 Dec 2013, 17:43

Re: [Windows 7] SetTaskbarProgress

07 Oct 2018, 07:12

I've been dabbling with the AHK v2 alpha. For future reference, below is a working function for both v1 and v2.

Code: Select all

; SetTaskbarProgress  -  Windows 7+
;  by lexikos, modified by gwarble for U64,U32,A32 compatibility, modified by Maestr0 for AHK v1 and AHK v2 compatibility
;
; pct    -  A number between 0 and 100 or a state value (see below).
; state  -  "N" (normal), "P" (paused), "E" (error) or "I" (indeterminate).
;           If omitted (and pct is a number), the state is not changed.
; hwnd   -  The hWnd of the window which owns the taskbar button.
;           If omitted, the Last Found Window is used.
;
SetTaskbarProgress(pct, state:="", hwnd:="") {
 static tbl, s0:=0, sI:=1, sN:=2, sE:=4, sP:=8
 if !tbl
  Try tbl := ComObjCreate("{56FDF344-FD6D-11d0-958A-006097C9A090}"
                        , "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}")
  Catch 
   Return 0
 If ( hwnd = "" )
  hwnd := WinExist()
 If !(pct is "number")
  state := pct, pct := ""
 Else If (pct = 0 && state="")
  state := 0, pct := ""
 If StrLen(state) && InStr("0INEP",state) ; good catch, MrRed!
  DllCall(NumGet(NumGet(tbl+0)+10*A_PtrSize), "uint", tbl, "uint", hwnd, "uint", s%state%)
 If ( pct != "" )
  DllCall(NumGet(NumGet(tbl+0)+9*A_PtrSize), "uint", tbl, "uint", hwnd, "int64", pct*10, "int64", 1000)
Return 1
}
Last edited by Maestr0 on 15 Jul 2020, 01:55, edited 1 time in total.
MrRED
Posts: 10
Joined: 19 May 2018, 21:15
Location: USA

Re: [Windows 7] SetTaskbarProgress

26 Jun 2020, 20:17

@Maestr0
I have used your revision today and noticed that on sample code it always use Normal notification type instead of switching to Paused, Error, Indeterminate.
The problem turns out that InStr("0INEP",state) returns 1 even when state is blank, so the first DllCall is triggered when not expected.

Given zero is also a valid value of state - I had to add explicit StrLen check of state before checking for InStr match.

Code: Select all

; SetTaskbarProgress  -  Windows 7+
;  by lexikos, modified by gwarble for U64,U32,A32 compatibility, modified by Maestr0 for AHK v1 and AHK v2 compatibility
;
; pct    -  A number between 0 and 100 or a state value (see below).
; state  -  "N" (normal), "P" (paused), "E" (error) or "I" (indeterminate).
;           If omitted (and pct is a number), the state is not changed.
; hwnd   -  The hWnd of the window which owns the taskbar button.
;           If omitted, the Last Found Window is used.
;
SetTaskbarProgress(pct, state:="", hwnd:="") {
 static tbl, s0:=0, sI:=1, sN:=2, sE:=4, sP:=8
 if !tbl
  Try tbl := ComObjCreate("{56FDF344-FD6D-11d0-958A-006097C9A090}"
                        , "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}")
  Catch 
   Return 0
 If ( hwnd = "" )
  hwnd := WinExist()
 If !(pct is "number")
  state := pct, pct := ""
 Else If (pct = 0 && state="")
  state := 0, pct := ""
 If StrLen(state) && InStr("0INEP",state)
  DllCall(NumGet(NumGet(tbl+0)+10*A_PtrSize), "uint", tbl, "uint", hwnd, "uint", s%state%)
 If ( pct != "" )
  DllCall(NumGet(NumGet(tbl+0)+9*A_PtrSize), "uint", tbl, "uint", hwnd, "int64", pct*10, "int64", 1000)
Return 1
}
User avatar
Maestr0
Posts: 136
Joined: 05 Dec 2013, 17:43

Re: [Windows 7] SetTaskbarProgress

15 Jul 2020, 01:54

MrRED wrote:
26 Jun 2020, 20:17
@Maestr0
I have used your revision today and noticed that on sample code it always use Normal notification type instead of switching to Paused, Error, Indeterminate.
The problem turns out that InStr("0INEP",state) returns 1 even when state is blank, so the first DllCall is triggered when not expected.

Given zero is also a valid value of state - I had to add explicit StrLen check of state before checking for InStr match.

Code: Select all

; SetTaskbarProgress  -  Windows 7+
;  by lexikos, modified by gwarble for U64,U32,A32 compatibility, modified by Maestr0 for AHK v1 and AHK v2 compatibility
;
; pct    -  A number between 0 and 100 or a state value (see below).
; state  -  "N" (normal), "P" (paused), "E" (error) or "I" (indeterminate).
;           If omitted (and pct is a number), the state is not changed.
; hwnd   -  The hWnd of the window which owns the taskbar button.
;           If omitted, the Last Found Window is used.
;
SetTaskbarProgress(pct, state:="", hwnd:="") {
 static tbl, s0:=0, sI:=1, sN:=2, sE:=4, sP:=8
 if !tbl
  Try tbl := ComObjCreate("{56FDF344-FD6D-11d0-958A-006097C9A090}"
                        , "{ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf}")
  Catch 
   Return 0
 If ( hwnd = "" )
  hwnd := WinExist()
 If !(pct is "number")
  state := pct, pct := ""
 Else If (pct = 0 && state="")
  state := 0, pct := ""
 If StrLen(state) && InStr("0INEP",state)
  DllCall(NumGet(NumGet(tbl+0)+10*A_PtrSize), "uint", tbl, "uint", hwnd, "uint", s%state%)
 If ( pct != "" )
  DllCall(NumGet(NumGet(tbl+0)+9*A_PtrSize), "uint", tbl, "uint", hwnd, "int64", pct*10, "int64", 1000)
Return 1
}
Awesome, thank you! Yes, in hindsight I see that you're correct. I'll update my post above.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 180 guests