Jump to content

ITaskbarList3


wraithdu
 Share

Recommended Posts

I can't divine your broken code, so you're gonna have to post something better than errors. Small reproducer would be nice.

Probably just add the Global declaration to the first mention of $oTB3, I forgot it in my example.

Edited by wraithdu
Link to comment
Share on other sites

  • 3 weeks later...

I found a nice dll written in C++ that works easily in AutoIt3 using DllCall. It's a work in progress(pun intended) but there's enough done to do the Windows7 Taskbar Progress. You can download the dll and sources from this page:

http://psymp3.googlecode.com/svn/branches/1-CURRENT/libs/libseven/

See the _TestProgress() function at the bottom of my demo TestLib7.au3. Note the Taskbar Progress test is done out of a Tray Menu command since I have a program skeleton in my au3 template file. It was just easier to add a command to the Tray Menu.

The other file, MilesAheadMisc.au3 has routine support functions like _WindowsVersion() and _ShowUsage() etc..

TestLib7.au3

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_icon=f.ico
#AutoIt3Wrapper_outfile=TestLib7.exe
#AutoIt3Wrapper_UseUpx=n
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

; AutoIt3 Script for MilesAhead
#include <Misc.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include "MilesAheadMisc.au3"

If _WinVersion() < 6.1 Then _ShowError("Program requires Windows Seven!")

Const $ERROR_ALREADY_EXISTS = 183

If _Singleton("{A07C9E7D-62DA-4030-B4B1-1CC197378BD3}", 1) = 0 Then
    If @error = $ERROR_ALREADY_EXISTS Then Exit
Else
    OnAutoItExitRegister("_Cleanup")
EndIf
AutoItSetOption("TrayMenuMode", 3)
TraySetClick(8)

Const $TASKBAR_PROGRESS = 1, $TASKBAR_PAUSED = 2, $TASKBAR_NORMAL = 3, $TASKBAR_INDETERMINATE = 4

; handle for libseven.dll
Global $handle = -1

;flag to prevent windows being open concurrently
Global $windowOpen = False
Global $readmeFilename = @ScriptDir & "\Readme.txt"

TraySetToolTip(_ScriptBaseName())
TrayCreateItem("")
$aboutitem = TrayCreateItem("About")
$downloaditem = TrayCreateItem("Visit Hotkey Page")
;$updateitem = TrayCreateItem("Check for Update")
TrayCreateItem("")
$testProgress = TrayCreateItem("Test Taskbar Progress")
$readmeitem = TrayCreateItem("Show Readme")
$donateitem = TrayCreateItem("Donate")
TrayCreateItem("")
$exititem = TrayCreateItem("Quit")

Global $gui = GUICreate("Windows7 Taskbar", 240, 40, -1, -1, $WS_OVERLAPPEDWINDOW)
If $gui = 0 Then _ShowError("Gui Window creation failed!")
Global $prog = GUICtrlCreateProgress(20, 10, 200, 20)
Global $taskInit = False

; Tray Message Loop

While 1
    $msg = TrayGetMsg()
    Select
        Case $msg = 0
            ; do any polling here
            ContinueLoop

        Case $msg = $aboutitem
            _About()
            _ReduceMemory()

        Case $msg = $downloaditem
            _VisitHotkeyPage()

;~      Case $msg = $updateitem
;~          $windowOpen = True
;~          _Check4Update()
;~          _EmptyTrayQ()
;~          $windowOpen = False
;~          _ReduceMemory()

        Case $msg = $testProgress
            _TestProgress()

        Case $msg = $readmeitem
            _ReadMe()

        Case $msg = $donateitem
            _Donate()

        Case $msg = $exititem
            _Quit()

    EndSelect
WEnd

Func _About()
    Local $about = _ScriptBaseName() & " "
    $about &= FileGetVersion(@ScriptFullPath)
    $about &= " Copyright (c) 2011 FavesSoft LLC" & @CRLF & @CRLF
    $about &= "Show Usage Info Here"
    _ShowUsage($about, _ScriptBaseName(), False)
EndFunc   ;==>_About

Func _ReadMe()
    $result = 0
    If _ValidPath($readmeFilename) Then
        $result = ShellExecute($readmeFilename)
    EndIf
    If $result = 0 Then
        _ShowError("Help/Readme File Not Found!", "", False)
    EndIf
EndFunc   ;==>_ReadMe

Func _VisitHotkeyPage()
    ShellExecute("http://www.favessoft.com/hotkeys.html")
EndFunc   ;==>_VisitHotkeyPage

Func _Donate()
    ShellExecute("http://www.favessoft.com/donate.html")
EndFunc   ;==>_Donate

Func _Quit()
    Exit
EndFunc   ;==>_Quit

; registered clean up function
Func _Cleanup()
    If $gui <> 0 Then
        GUIDelete($gui)
    EndIf
    If $handle <> -1 Then
        DllClose($handle)
    EndIf
EndFunc   ;==>_Cleanup

Func _TestProgress()
    GUISetState(@SW_SHOW, $gui)
    If Not $taskInit Then
        $handle = DllOpen("libseven.dll")
        If $handle = -1 Then _ShowError("Open of libseven.dll Failed!")
        DllCall($handle, "none:cdecl", "InitializeTaskbar")
        If @error Then
            _ShowError("Initialize Taskbar Failed!")
        EndIf
        DllCall($handle, "none:cdecl", "AssociateHwnd", "HWND", $gui)
        If @error Then
            _ShowError("Associate Window Handle Failed!")
        EndIf
        $taskInit = True
    EndIf
    DllCall($handle, "none:cdecl", "SetProgressType", "int", $TASKBAR_PROGRESS)
    If @error Then
        _ShowError("SetProgressType Function Failed!")
    EndIf
    For $x = 5 To 100 Step 5
        DllCall($handle, "none:cdecl", "UpdateProgressBar", "int", $x, "int", 100)
        If @error Then
            _ShowError("Progress Update Failed!")
        EndIf
        GUICtrlSetData($prog, $x)
        Sleep(250)
    Next
    DllCall($handle, "none:cdecl", "SetProgressType", "int", $TASKBAR_NORMAL)
    GUICtrlSetData($prog, 1)
    GUISetState(@SW_HIDE, $gui)
EndFunc   ;==>_TestProgress

MilesAheadMisc.au3

;
;MilesAheadMisc.au3
;
;misc useful functions for
;inclusion in scripts.
;
;some functions are totatlly original.
;where adapted or used directly I give
;attribution when possible.
;
;MilesAhead
;
#include-once
#include <Array.au3>
#include <File.au3>
#include <WinAPI.au3>

; Empty Tray Icon Queue of events
Func _EmptyTrayQ()
    Local $m = 0
    Do
        $m = TrayGetMsg()
    Until $m = 0
EndFunc   ;==>_EmptyTrayQ

;use Scripting.Dictionary object for simple associative arrays
Func _AssocArray()
    Local $aArray = ObjCreate("Scripting.Dictionary")
    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    $aArray.CompareMode = 1
    Return $aArray
EndFunc   ;==>_AssocArray

Func _AssocArrayDestroy(ByRef $aArray)
    If Not IsObj($aArray) Then
        Return False
    EndIf
    $aArray.RemoveAll()
    $aArray = 0
    Return True
EndFunc   ;==>_AssocArrayDestroy

;filter out empty array strings ("")
Func _ArrayDelBlanks(ByRef $someArray)
    Local $index = -1
    While UBound($someArray) > 0
        $index = _ArraySearch($someArray, "")
        If $index > -1 Then
            _ArrayDelete($someArray, $index)
        Else
            ExitLoop
        EndIf
    WEnd
EndFunc   ;==>_ArrayDelBlanks

;confirms that input consists only of valid chars
Func _ValidateInput($inputStr, $validChars)
    For $x = 1 To StringLen($inputStr)
        If Not StringInStr($validChars, StringMid($inputStr, $x, 1)) Then
            Return False
        EndIf
    Next
    Return True
EndFunc   ;==>_ValidateInput

;InputBox to allow user to change hotkey modifier key
;ModKey chars must all be in $validChars string
;Returns $curModKey if user aborts entry
Func _EditHotkeyModifier($curModKey, $validChars)
    Local $newModKey = ""
    $prompt = "Usable Modifiers include:" & @CRLF
    $prompt &= "#   for Win Key" & @CRLF
    $prompt &= "!    for Alt Key" & @CRLF
    $prompt &= "^   for Control Key" & @CRLF
    $prompt &= "^!  for Control-Alt etc.." & @CRLF
    $newModKey = InputBox("Enter HotKey Modifier", $prompt, $curModKey)
    If $newModKey = "" Or $newModKey = $curModKey Then Return $curModKey
    If Not _ValidateInput($newModKey, $validChars) Then
        _ShowError("Invalid Hotkey Modiifer Specified : Keeping Current!", "", False)
        Return $curModKey
    EndIf
    Return $newModKey
EndFunc   ;==>_EditHotkeyModifier

;return the Windows version as a number or string
;according to $retAsString param.
;example 6.1 for Windows7, 6 for Vista,
;5.1 for XP etc.. as number, as string the
;minor version will be preserved even if .0
;(Vista returns "6.0" etc.)
;
Func _WinVersion($retAsString = 0)
    Local $dwVersion = DllCall("kernel32.dll", "dword", "GetVersion")
    Local $versionStr = String(BitAND($dwVersion[0], 0x00FF))
    $versionStr &= "." & String(BitShift(BitAND($dwVersion[0], 0xFF00), 8))
    If $retAsString Then Return $versionStr
    Return Number($versionStr)
EndFunc   ;==>_WinVersion

;_GetVersionEx()
;
;It calls the Ansi version of GetVersionEx() WinAPI
;
;On success returns zero based 5 element array of strings
;element 0 = OS Major;1 = OS Minor; 2 = build; 3 = platform; 4 = Version String
;note Version String may be an empty string or something like "Service Pack 1"
;
;On error returns 0 and sets @error to the value contained in @error macro.
;Sets @extended to 1 if error occurred in DllStructCreate(), 2 if error
;occurred in DllStructSetData(), or 3 if error occurred in DllCall()
;
Func _GetVersionEx()
    Local $OsArray[5] = [""]
    Local $osvi = DllStructCreate("dword size;dword OsMajor;dword OsMinor;dword build;dword platform;char verString[128]")
    If @error Then
        Return SetError(@error, 1, 0)
    EndIf
    DllStructSetData($osvi, "size", 148)
    If @error Then
        $osvi = 0
        Return SetError(@error, 2, 0)
    EndIf
    Local $retVal = DllCall("Kernel32.dll", "int", "GetVersionExA", "ptr", DllStructGetPtr($osvi))
    If @error Then
        $osvi = 0
        Return SetError(@error, 3, 0)
    EndIf
    $OsArray[0] = String(DllStructGetData($osvi, "OsMajor"))
    $OsArray[1] = String(DllStructGetData($osvi, "OsMinor"))
    $OsArray[2] = String(DllStructGetData($osvi, "build"))
    $OsArray[3] = String(DllStructGetData($osvi, "platform"))
    $OsArray[4] = DllStructGetData($osvi, "verString")
    $osvi = 0
    Return $OsArray
EndFunc   ;==>_GetVersionEx

; Reduce memory usage via EmptyWorkingSet()
; Author wOuter ( mostly ) on AutoIt3 forum
Func _ReduceMemory($i_PID = -1)
    If _WinVersion() < 5 Then Return False
    If $i_PID <> -1 Then
        Local $ai_Handle = DllCall("kernel32.dll", 'int', 'OpenProcess', 'int', 0x1f0fff, 'int', False, 'int', $i_PID)
        Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', $ai_Handle[0])
        DllCall('kernel32.dll', 'int', 'CloseHandle', 'int', $ai_Handle[0])
    Else
        Local $ai_Return = DllCall("psapi.dll", 'int', 'EmptyWorkingSet', 'long', -1)
    EndIf

    Return $ai_Return[0]
EndFunc   ;==>_ReduceMemory

;returns non 0 if Glass is enabled on Vista/W7
Func _GlassEnabled()
    $retValue = DllCall("dwmapi.dll", "int", "DwmIsCompositionEnabled", "int*", "")
    If @error Then Return 0
    Return $retValue[1]
EndFunc   ;==>_GlassEnabled

;from Michael Michta on AutoIt3 forum
Func EnableBlurBehind($hWnd)
    Const $DWM_BB_ENABLE = 0x00000001
    $Struct = DllStructCreate("dword;int;ptr;int")
    DllStructSetData($Struct, 1, $DWM_BB_ENABLE)
    DllStructSetData($Struct, 2, "1")
    DllStructSetData($Struct, 4, "1")
    DllCall("dwmapi.dll", "int", "DwmEnableBlurBehindWindow", "hwnd", $hWnd, "ptr", DllStructGetPtr($Struct))
EndFunc   ;==>EnableBlurBehind

;if $Str contains a space wrap in double quotes
;
;useful for command line params of files that have
;a space in the file path
;
Func _QuoteStr($str)
    If StringInStr($str, " ") Then
        Return '"' & $str & '"'
    EndIf
    Return $str
EndFunc   ;==>_QuoteStr

;returns True if $path is a directory
Func _DirectoryExists($path)
    If Not FileExists($path) Then Return False
    If StringInStr(FileGetAttrib($path), "D") > 0 Then Return True
    Return False
EndFunc   ;==>_DirectoryExists

;return True if $path exists and contains "D" directory attribute
Func _IsFolder($path)
    Local $attr = FileGetAttrib($path)
    If $attr = "" Then
        Return SetError(1, 0, False)
    ElseIf StringInStr($attr, "D") Then
        Return True
    Else
        Return False
    EndIf
EndFunc   ;==>_IsFolder

;returns False if no media in drive or file/folder doesn't exist
;
;for use with complete paths, not for file named 'x'
;in working dir.  Seems to work ok with network paths
;(\\NAME\folder\filename) as well as those starting with
;a drive letter. The idea is to avoid the long time-out
;if FileExists was used by itself on empty drive etc..
;
Func _ValidPath($path)
    ;filter out obvious junk
    If StringLen($path) < 2 Then Return False

    Local $sysDrive = StringLeft(@WindowsDir, 2)
    Local $drive = StringLeft($path, 2)
    If $sysDrive = $drive Then
        Return FileExists($path)
    EndIf

    Local $driveType = DriveGetType($drive)
    If @error Then Return False
    Switch $driveType

        Case "Unknown"
            Return False

        Case "Network"
            If DriveStatus($drive) = "Invalid" Then Return False

        Case "CDROM", "Removable"
            If DriveStatus($drive) = "NotReady" Then Return False

    EndSwitch

    Return FileExists($path)
EndFunc   ;==>_ValidPath

; A drive passed in that consists of a letter and colon
; ( x: ) will be set to Upper Case and a slash appened ( X:\ )
;
; A drive passed in as x:\ will be set to Upper Case.
;
; The Function returns nothing.  Any changes are made to the
; input param.
;
Func _DriveUpSlash(ByRef $drive)
    If StringLen($drive) = 2 And StringRight($drive, 1) = ":" Then
        $drive = StringUpper($drive) & "\"
    ElseIf StringRight($drive, 2) = ":\" Then
        $drive = StringUpper($drive)
    EndIf
EndFunc   ;==>_DriveUpSlash

; return the basename part of a file path
; works only for files with extension
; e.g. returns "test" for c:\folder\test.exe path
;
Func _FileBaseName($path)
    If $path = "" Then Return ""
    If StringLen($path) < 3 Then Return ""

    Local $pos = StringInStr($path, "\", 0, -1)
    $pos += 1
    Local $tmp = StringMid($path, $pos)
    Return StringLeft($tmp, StringInStr($tmp, ".", 0, -1) - 1)
EndFunc   ;==>_FileBaseName

; return _FileBaseName with hash appended instead of using full path
;
Func _BaseFileStr($path)
    Return _FileBaseName($path) & _HashString32($path)
EndFunc   ;==>_BaseFileStr

; return the '.ext' part of path no matter how long the ext
; as in image.jpg returns '.jpg' or image.jpeg returns '.jpeg'
;
Func _FileExt($path)
    If $path = "" Then Return ""
    Local $pos = StringInStr($path, ".", 0, -1)
    If $pos = 0 Then Return ""
    Return StringMid($path, $pos)
EndFunc   ;==>_FileExt

; return entire path without last extension
; (e.g. c:\Folder\Text.txt returns c:\Folder\Text)
;
Func _PathNoExt($path)
    If $path = "" Then Return ""
    Local $pos = StringInStr($path, ".", 0, -1)
    If $pos = 0 Then Return ""
    Return StringLeft($path, $pos - 1)
EndFunc   ;==>_PathNoExt


;returns filename fName without drive or path
Func _FileNoPath($fName)
    Local $slashPos = StringInStr($fName, "\", 0, -1)
    $slashPos += 1
    Return StringMid($fName, $slashPos)
EndFunc   ;==>_FileNoPath

;filter out percent signs, spaces, and illegal filename chars
;and substitute underscores. Optionally chop off return str
;at $maxLen chars.
;
;
Func _NormalizeFilename($inFilename, $maxLen = 0)
    Local Const $illegalFilenameChars = "?[]/\=+<>:;"",* %"
    Local $c = ""
    Local $fixedFilename = ""

    For $x = 1 To StringLen($inFilename)
        $c = StringMid($inFilename, $x, 1)
        If StringInStr($illegalFilenameChars, $c) Then
            $c = "_"
        EndIf
        $fixedFilename &= $c
    Next
    If $maxLen Then
        Return StringLeft($fixedFilename, $maxLen)
    EndIf
    Return $fixedFilename
EndFunc   ;==>_NormalizeFilename

;return @ScriptName without extension
;useful for MsgBox titles or path
;building
;
Func _ScriptBaseName()
    Return StringLeft(@ScriptName, (StringInStr(@ScriptName, ".") - 1))
EndFunc   ;==>_ScriptBaseName

;a one-liner but saves thinking about it :)
;
Func _ScriptIniFileName()
    Return @ScriptDir & "\" & _ScriptBaseName() & ".ini"
EndFunc   ;==>_ScriptIniFileName

; #FUNCTION# ====================================================================================================================
; Name...........: _FileInPath
; Description ...: Returns the location in the PATH environment variable containing a file
; Syntax.........: _FileInPath( $sFilename )
; Parameters ....: $sFilename - The file to search for (filename only, no folders)
; Return values .: Success - Returns the path to the file and set @error=0 (@extended=1 a specified path and the file is there)
;                  Failure - Returns "" and sets @error:
;                  |1 - File not found in @WorkingDir or the PATH (@extended=1 if PATH is blank)
;                  |2 - Could not StringSplit the PATH
; Author ........: Gigglestick (c0deWorm)
; Modified.......: Comments added and logic modified
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......:
; ===============================================================================================================================
Func _FileInPath($asFilename)
    If StringInStr($asFilename, "\") Then
        If FileExists($asFilename) Then
            ; if a full or relative path was specified and the file exists then return the path
            Return SetError(0, 1, $asFilename)
        Else
            ; if a path was specified and the file does not exist then return "file not found" error
            Return SetError(1, 0, "")
        EndIf
    EndIf
    ; if the file is found in the current working directory then return the absolute file path
    If FileExists(@WorkingDir & "\" & $asFilename) Then Return SetError(0, 0, @WorkingDir & "\" & $asFilename)
    Local $i, $lasPath, $lsPath = EnvGet("PATH")
    ; if variable containing PATH is empty then return "file not found" error and @extended=2
    If StringLen($lsPath) = 0 Then Return SetError(1, 1, "")
    ; if PATH is set but only has one entry then check it
    If StringLen($lsPath) > 0 And Not StringInStr($lsPath, ";") Then
        If FileExists($lsPath & "\" & $asFilename) Then
            ; if the filename is found in the single PATH entry then return the file path
            Return SetError(0, 0, $lsPath & "\" & $asFilename)
        Else
            ; if PATH is a single entry and does not contain the filename then return "file not found" error
            Return SetError(1, 0, "")
        EndIf
    EndIf
    ; remove any blank entries (double semicolons)
    While StringInStr($lsPath, ";;")
        $lsPath = StringReplace($lsPath, ";;", ";")
    WEnd
    ; split variable containing PATH into an array of single paths
    $lasPath = StringSplit($lsPath, ";")
    ; if ";" not found in split then return error
    If @error Then Return SetError(2, 0, "")
    ; loop through array of single paths, searching for absolute file path and return absolute file path if found
    For $i = 1 To $lasPath[0]
        If FileExists($lasPath[$i] & "\" & $asFilename) Then Return SetError(0, 0, $lasPath[$i] & "\" & $asFilename)
    Next
    ; unable to find filename in current working directory or PATH so return error
    Return SetError(1, 0, "")
EndFunc   ;==>_FileInPath

;Check FavesSoft Server for newer version with optional download
;If user downloads, the script directory and zip file will be
;opened, and the calling program exited.
;
Func _Check4Update($verIniFile = "FavesVersions.ini", $url = "http://www.favessoft.com/", $maxCount = 10)
    Local $count = 0
    Local $iniFile = @ScriptDir & "\" & $verIniFile
    Local $hDownload = InetGet($url & $verIniFile, $iniFile, 1, 1)
    Local $localFile = ""
    Do
        $count += 1
        If $count > $maxCount Then ExitLoop
        Sleep(250)
    Until InetGetInfo($hDownload, 2)
    InetClose($hDownload)
    If $count > $maxCount Then
        _ShowError("Server Access Failed!", "", False)
        Return False
    EndIf
    Local $v = IniRead($iniFile, "Versions", _ScriptBaseName(), "")
    If $v = "" Then
        _ShowError("Version Info Not Found!", "", False)
        If FileExists($iniFile) Then
            FileDelete($iniFile)
        EndIf
        Return False
    EndIf
    Local $t = FileGetVersion(@ScriptFullPath)
    If $v > $t Then
        If MsgBox(0x1044, _ScriptBaseName(), "Current Version is " & $t & " Online Version is " & $v & " : Download?") = 6 Then
            $d = IniRead($iniFile, "Downloads", _ScriptBaseName(), "")
            If $d <> "" Then
                $localFile = @ScriptDir & "\" & $d
                $hDownload = InetGet($url & $d, $localFile, 1, 1)
                $count = 0
                Do
                    $count += 1
                    If $count > $maxCount Then ExitLoop
                    Sleep(250)
                Until InetGetInfo($hDownload, 2)
                InetClose($hDownload)
                If $count <= $maxCount Then
                    ShellExecute($localFile)
                    ShellExecute(@ScriptDir)
                    If FileExists($iniFile) Then
                        FileDelete($iniFile)
                    EndIf
                    Exit
                Else
                    _ShowError("Download Attempt Failed!", "", False)
                    If FileExists($iniFile) Then
                        FileDelete($iniFile)
                    EndIf
                    Return False
                EndIf
            Else
                _ShowError("Download Info Not Found!", "", False)
                If FileExists($iniFile) Then
                    FileDelete($iniFile)
                EndIf
                Return False
            EndIf
        Else
            If FileExists($iniFile) Then
                FileDelete($iniFile)
            EndIf
            Return True
        EndIf
    Else
        MsgBox(0x1040, _ScriptBaseName(), $t & " is the latest version")
    EndIf
    If FileExists($iniFile) Then
        FileDelete($iniFile)
    EndIf
EndFunc   ;==>_Check4Update

;show an error msg and optionally quit, with optional timeout
Func _ShowError($errorMsg, $title = "", $quit = True, $timeOut = 0)
    If $title = "" Then $title = _ScriptBaseName()
    MsgBox(0x1010, $title, $errorMsg, $timeOut)
    If $quit Then Exit
EndFunc   ;==>_ShowError

;show usage msg and optionally quit with optional timeout
Func _ShowUsage($usageMsg, $title = "", $quit = True, $timeOut = 0)
    If $title = "" Then $title = _ScriptBaseName()
    MsgBox(0x1040, $title, $usageMsg, $timeOut)
    If $quit Then Exit
EndFunc   ;==>_ShowUsage

;write AssocArray to IniFile Section
;returns 1 on success - sets @error on failure
Func _WriteAssocToIni($myAssoc, $myIni, $mySection)
    $retVal = 0
    If $myAssoc.Count() < 1 Then
        Return SetError(1, 0, 0)
    EndIf
    Local $iArray[$myAssoc.Count()][2]
    Local $aArray = $myAssoc.Keys()
    For $x = 0 To UBound($aArray) - 1
        $iArray[$x][0] = $aArray[$x]
        $iArray[$x][1] = _MakePosString($myAssoc($aArray[$x]))
    Next
    $retVal = IniWriteSection($myIni, $mySection, $iArray, 0)
    Return SetError(@error, 0, $retVal)
EndFunc   ;==>_WriteAssocToIni

;read AssocArray from IniFile Section
;returns number of items read - sets @error on failure
Func _ReadAssocFromIni(ByRef $myAssoc, $myIni, $mySection)
    Local $sectionArray = IniReadSection($myIni, $mySection)
    If @error Then Return SetError(1, 0, 0)
    Local $posA[9]
    Local $posS
    For $x = 1 To $sectionArray[0][0]
        $posS = _MakePosArray($sectionArray[$x][1])
        For $y = 0 To UBound($posS) - 1
            $posA[$y] = Number($posS[$y])
            If $posA[$y] < 0 Then ContinueLoop 2
        Next
        $myAssoc($sectionArray[$x][0]) = $posA
    Next
    Return $sectionArray[0][0]
EndFunc   ;==>_ReadAssocFromIni

;from _SDBM32 by trancexx on AutoIt3 forum
Func _HashString32($sString)

    Local $aArray = StringToASCIIArray($sString)
    Local $iHash = 0

    For $i = 0 To UBound($aArray) - 1
        $iHash = $aArray[$i] + BitShift($iHash, -6) + BitShift($iHash, -16) - $iHash
    Next

    Return Hex($iHash)

EndFunc   ;==>_HashString32

;makes a Position string using '#' number separator
Func _MakePosString($posArray)
    Local $str = ""
    For $x = 0 To UBound($posArray) - 2
        $str &= String($posArray[$x]) & "#"
    Next
    $str &= String($posArray[UBound($posArray) - 1])
    Return $str
EndFunc   ;==>_MakePosString

;makes a Position array from a Position string
Func _MakePosArray($posString)
    Return StringSplit($posString, "#", 2)
EndFunc   ;==>_MakePosArray

;show msgbox without sound and optionally quit with optional timeout
Func _ShowSilent($usageMsg, $title = "", $quit = True, $timeOut = 0)
    If $title = "" Then $title = _ScriptBaseName()
    MsgBox(0xA0, $title, $usageMsg, $timeOut)
    If $quit Then Exit
EndFunc   ;==>_ShowSilent

; Get the execuatble path of a window
; Author gafrost on AutoIt3 forum
Func _WinGetPath($title = "", $strComputer = 'localhost')
    Local $win = WinGetTitle($title)
    Local $pid = WinGetProcess($win)
    Local $wbemFlagReturnImmediately = 0x10
    Local $wbemFlagForwardOnly = 0x20
    Local $colItems = ""
    Local $objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
    $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_Process WHERE ProcessId = " & $pid, "WQL", _
            $wbemFlagReturnImmediately + $wbemFlagForwardOnly)
    If IsObj($colItems) Then
        For $objItem In $colItems
            If $objItem.ExecutablePath Then Return $objItem.ExecutablePath
        Next
    EndIf
    Return ""
EndFunc   ;==>_WinGetPath

;AutoIt3 Forum code to get Desktop WorkArea
Func _GetDesktopWorkArea(ByRef $left, ByRef $top, ByRef $right, ByRef $bottom)
    Local Const $SPI_SETWORKAREA = 47
    Local Const $SPI_GETWORKAREA = 48
    Local $tRcWA = DllStructCreate($tagRECT)

    If _WinAPI_SystemParametersInfo($SPI_GETWORKAREA, 0, DllStructGetPtr($tRcWA)) Then
        $left = DllStructGetData($tRcWA, "Left")
        $right = DllStructGetData($tRcWA, "Right")
        $top = DllStructGetData($tRcWA, "Top")
        $bottom = DllStructGetData($tRcWA, "Bottom")
        Return True
    EndIf
    Return False
EndFunc   ;==>_GetDesktopWorkArea

Func _SetDesktopWorkArea($left, $top, $right, $bottom)
    Local Const $SPI_SETWORKAREA = 47
    Local Const $SPI_GETWORKAREA = 48
    Local $tRcWA = DllStructCreate($tagRECT)

    DllStructSetData($tRcWA, "Left", $left)
    DllStructSetData($tRcWA, "Top", $top)
    DllStructSetData($tRcWA, "Right", $right)
    DllStructSetData($tRcWA, "Bottom", $bottom)

    Return _WinAPI_SystemParametersInfo($SPI_SETWORKAREA, 0, DllStructGetPtr($tRcWA))
EndFunc   ;==>_SetDesktopWorkArea

Func _DesktopMarginArea(ByRef $left, ByRef $top, ByRef $right, ByRef $bottom, $margin = 4)
    Local $l, $t, $r, $b
    Local $m = Int($margin)
    If $m < 0 Or $m > 12 Then $m = 4

    If $m = 0 Then
        _GetDesktopWorkArea($left, $top, $right, $bottom)
    Else
        _GetDesktopWorkArea($l, $t, $r, $b)
        $left = $l + $m
        $top = $t + $m
        $right = $r - $m
        $bottom = $b - $m
    EndIf
EndFunc   ;==>_DesktopMarginArea

Func _DesktopTaskbarGap(ByRef $left, ByRef $top, ByRef $right, ByRef $bottom, $percentMargin = 5)
    _GetDesktopWorkArea($left, $top, $right, $bottom)
    If $right - $left = @DesktopWidth And $bottom - $top = @DesktopHeight Then
        Return
    EndIf
    If $bottom < @DesktopHeight Then
        $bottom -= Int($bottom / 100 * $percentMargin)
    ElseIf $top > 0 Then
        $top += Int(($bottom - $top) / 100 * $percentMargin)
    ElseIf $left > 0 Then
        $left += Int(($right - $left) / 100 * $percentMargin)
    Else
        $right -= Int(($right - $left) / 100 * $percentMargin)
    EndIf
EndFunc   ;==>_DesktopTaskbarGap

; Set Desktop Work Area with percent gap next to Taskbar
Func _DesktopSetTaskbarGap($percentMargin = 5)
    Local $l, $t, $r, $b
    _DesktopTaskbarGap($l, $t, $r, $b, $percentMargin)
    Return _SetDesktopWorkArea($l, $t, $r, $b)
EndFunc   ;==>_DesktopSetTaskbarGap

; _ShowFolders($folders, $percentGap = 5)
;
; Show folders leaving TaskBar Gap
; ---------------------------------
; $folders[0] must have the folder count
; $percentGap is the percent of screen width
; or height to leave next to the Taskbar.
; If TaskbarGap.exe is running, $percentGap
; is set to 0 since it is assumed TaskbarGap
; has set the work area to allow for the gap.
;
; Does not Return a value
;
Func _ShowFolders($folders, $percentGap = 5)
    If Not IsArray($folders) Then Return
    Local $l = -1, $t = -1, $r = -1, $b = -1
    Local $oldMatchMode = AutoItSetOption("WinTitleMatchMode", -3)
    If ProcessExists("TaskbarGap.exe") Then
        $percentGap = 0
    EndIf
    _DesktopTaskbarGap($l, $t, $r, $b, $percentGap)
    Local $sleepVal = 2500
    Local $s = $folders[0]
    Local $h = $b - $t
    Local $w = ($r - $l) / $s
    Local $w3 = 0, $w4 = 0
    $w3 = ($r - $l) / 3
    $w4 = ($r - $l) / 4
    If $s > 4 Then $sleepVal = 4000
    If $s > 6 Then $sleepVal = 4500
    If $s >= 4 Then
        $h = ($b - $t) / 2
    EndIf
    If $s > 8 Then
        WinMinimizeAll()
        Sleep(50)
    EndIf
    For $x = 1 To $s
        ShellExecute("explorer.exe", "/e," & $folders[$x], "", "open")
    Next
    Sleep($sleepVal)
    WinWait($folders[$s], "", 8)
    If $s > 8 Then
        _TileHorizontal()
    ElseIf $s = 8 Then
        $w *= 2
        WinMove($folders[1], "", $l, $t, $w - 1, $h - 2)
        WinMove($folders[2], "", $l + $w, $t, $w - 1, $h - 2)
        WinMove($folders[3], "", $l + 2 * $w, $t, $w - 1, $h - 2)
        WinMove($folders[4], "", $l + 3 * $w, $t, $w - 1, $h - 2)
        WinMove($folders[5], "", $l, $t + $h, $w - 1, $h - 2)
        WinMove($folders[6], "", $l + $w, $t + $h, $w - 1, $h - 2)
        WinMove($folders[7], "", $l + 2 * $w, $t + $h, $w - 1, $h - 2)
        WinMove($folders[8], "", $l + 3 * $w, $t + $h, $w - 1, $h - 2)
    ElseIf $s = 7 Then
        WinMove($folders[1], "", $l, $t, $w3 - 1, $h - 2)
        WinMove($folders[2], "", $l + $w3, $t, $w3 - 1, $h - 2)
        WinMove($folders[3], "", $l + 2 * $w3, $t, $w3 - 1, $h - 2)
        WinMove($folders[4], "", $l, $t + $h, $w4 - 1, $h - 2)
        WinMove($folders[5], "", $l + $w4, $t + $h, $w4 - 1, $h - 2)
        WinMove($folders[6], "", $l + 2 * $w4, $t + $h, $w4 - 1, $h - 2)
        WinMove($folders[7], "", $l + 3 * $w4, $t + $h, $w4 - 1, $h - 2)
    ElseIf $s = 6 Then
        $w *= 2
        WinMove($folders[1], "", $l, $t, $w - 1, $h - 2)
        WinMove($folders[2], "", $l + $w, $t, $w - 1, $h - 2)
        WinMove($folders[3], "", $l + 2 * $w, $t, $w - 1, $h - 2)
        WinMove($folders[4], "", $l, $t + $h, $w - 1, $h - 2)
        WinMove($folders[5], "", $l + $w, $t + $h, $w - 1, $h - 2)
        WinMove($folders[6], "", $l + 2 * $w, $t + $h, $w - 1, $h - 2)
    ElseIf $s = 5 Then
        WinMove($folders[1], "", $l, $t, $w3 - 1, $h - 2)
        WinMove($folders[2], "", $l + $w3, $t, $w3 - 1, $h - 2)
        WinMove($folders[3], "", $l + 2 * $w3, $t, $w3 - 1, $h - 2)
        WinMove($folders[4], "", $l, $t + $h, (($r - $l) / 2) - 1, $h - 2)
        WinMove($folders[5], "", $l + ($r - $l) / 2, $t + $h, (($r - $l) / 2) - 1, $h - 2)
    ElseIf $s = 4 Then
        $w *= 2
        WinMove($folders[1], "", $l, $t, $w - 1, $h - 2)
        WinMove($folders[2], "", $l + $w, $t, $w - 1, $h - 2)
        WinMove($folders[3], "", $l, $t + $h, $w - 1, $h - 2)
        WinMove($folders[4], "", $l + $w, $t + $h, $w - 1, $h - 2)
    Else
        For $x = 1 To $s
            WinMove($folders[$x], "", $l, $t, $w - 1, $h - 2)
            $l += $w
        Next
    EndIf
    AutoItSetOption("WinTitleMatchMode", $oldMatchMode)
EndFunc   ;==>_ShowFolders

;tile windows horizontally
Func _TileHorizontal()
    DllCall("user32.dll", "int", "TileWindows", "int", 0, "int", 1, "int", 0, "int", 0, "int", 0)
EndFunc   ;==>_TileHorizontal

Func _TileVertical()
    DllCall("user32.dll", "int", "TileWindows", "int", 0, "int", 0, "int", 0, "int", 0, "int", 0)
EndFunc   ;==>_TileVertical


;AutoIt3 Forum code to get multiple monitor metrics
Func _GetVirtualMetrics(ByRef $vWidth, ByRef $vHeight)
    Local Const $SM_VIRTUALWIDTH = 78
    Local Const $SM_VIRTUALHEIGHT = 79
    Local $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALWIDTH)
    Local $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALHEIGHT)
    $vWidth = $VirtualDesktopWidth[0]
    $vHeight = $VirtualDesktopHeight[0]
EndFunc   ;==>_GetVirtualMetrics

; =================================================================================================
; Description ..: Retrieves the name of the executable file associated with the specified file name
; Parameters ...: $FileName     - Fully qualified path to existing file
;                 $Directory    - Default directory
; Return values : Full path to the executable file started when an "open" by association is run on the
;                 file specified or blank if no association was found
; Author .......: Paul Campbell (PaulIA)
; Notes ........:
; =================================================================================================
Func _API_FindExecutable($sFileName, $sDirectory = "")
    Local $rBuffer

    $rBuffer = DllStructCreate("char[4096]")
    DllCall("Shell32.dll", "hwnd", "FindExecutable", "str", $sFileName, "str", $sDirectory, "ptr", DllStructGetPtr($rBuffer))
    Return DllStructGetData($rBuffer, 1)
EndFunc   ;==>_API_FindExecutable

Edit: as I mess with this lib more I see the only thing that seems to work is progressbar traversal in green. Doesn't seem to actuate the other colors. For some reason the author uses flags numbered 1 to 4 instead of just sticking with the API flags. I hope he fixes it up as it is something that could be called easily from a variety of client languages. I've used it in FreeBASIC and AutoIt3 so far.

Edit2: otoh wraithdu's demo works with all the colors. Looks like easier isn't better in this case. :)

Edited by MilesAhead
Link to comment
Share on other sites

  • 4 weeks later...

I convinced the author of an ITaskbarList3 Delphi Unit to wrap the progressbar bits in a stdcall DLL. You can download from this link:

http://forum.doom9.org/showthread.php?p=1518190#post1518190

If you're only interested in the Taskbar Progess bits it's easy to use with DllCall(). It's just handy to have a DLL that can be called from various client languages. He rewrote the progressbar bits in C. The source is included in the download. But more importantly the 32 bit DLL release is included. A quick look at the source and it's easy to see how to call the functions. They all return int. 1 on success, 0 on failure.

Posted Image

Edited by MilesAhead
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...