Jump to content

Recommended Posts

Posted (edited)

I wanted an alternate progress window for some of my scripts that didn't have progress points or involved waiting for some other process to run. So I came up with this UDF that displays a progress .gif and status text. It also allows you to display a transparency screen and progress bar if needed. I also made it customizable so you can create your own themes. I've found it very useful and thought I'd share it with the community. Enjoy!

Posted Image

Busy.au3

#cs ----------------------------------------------------------------------------

    File:           Busy.au3
    AutoIt Version: 3.3.0.0
    Author:         zorphnog (Michael Mims)

    Script Function:
    Provides a status window with text, progress bar, and gif animation

#ce ----------------------------------------------------------------------------

#include-once
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <File.au3>
#include <WinApi.au3>
#include "GIFAnimation.au3"

Global Const _
    $BSY_SIZE          = 14, _
    $BSY_MAINWIN       = 0, _
    $BSY_PARWIN        = 1, _
    $BSY_GIFOBJ        = 2, _
    $BSY_STATUSTEXT    = 3, _
    $BSY_STATUSBAR     = 4, _
    $BSY_SCREENWIN     = 5, _
    $BSY_THEME_DIR     = 6, _
    $BSY_THEME_BGCOLOR = 7, _
    $BSY_THEME_TEXT    = 8, _
    $BSY_THEME_BAR     = 9, _
    $BSY_THEME_BGBAR   = 10, _
    $BSY_THEME_SCREEN  = 11, _
    $BSY_THEME_GIF     = 12, _
    $BSY_THEME_CORNERS = 13
Global Const _
    $BUSY_SCREEN     = 0x1, _
    $BUSY_PROGRESS   = 0x2, _
    $BUSY_FULLSCREEN = 0x4, _
    $BUSY_TOPMOST    = 0x8
Global $g_aBsy_Info[$BSY_SIZE], $g_aBsy_GIFs, $g_aBsy_GIFs, $g_hBsy_GIFThread, $g_iBsy_Transparency, $g_tBsy_CurrentFrame

; #FUNCTION# ====================================================================================================================
; Name...........: _Busy_Close
; Description ...: Closes the busy status window.
; Syntax.........: _Busy_Close()
; Parameters ....: None
; Return values .: Success - Returns a 0
;                  Failure - Returns a -1
;                  @Error  - 0 = No error
;                  |1 = Invalid busy array
; Author ........: zorphnog
; Remarks .......: None
; ===============================================================================================================================
Func _Busy_Close()
    If Not IsArray($g_aBsy_Info) Or UBound($g_aBsy_Info) <> $BSY_SIZE Then Return SetError(1, 0, -1)
    GUIRegisterMsg(15, "")
    _GUICtrlDeleteGIF($g_aBsy_Info[$BSY_GIFOBJ], $g_aBsy_GIFs, $g_hBsy_GIFThread, $g_tBsy_CurrentFrame)
    GUISetState(@SW_ENABLE, $g_aBsy_Info[$BSY_PARWIN])
    GUISetState(@SW_UNLOCK, $g_aBsy_Info[$BSY_PARWIN])
    GUIDelete($g_aBsy_Info[$BSY_MAINWIN])
    If $g_aBsy_Info[$BSY_SCREENWIN] <> 0 Then GUIDelete($g_aBsy_Info[$BSY_SCREENWIN])
    __Busy_Reset()
    Return 0
EndFunc   ;==>_Busy_Close

; #FUNCTION# ====================================================================================================================
; Name...........: _Busy_Create
; Description ...: Creates and displays a busy status window.
; Syntax.........: _Busy_Create([$sStatus [, $iOptions [, $iTrans [, $hGui]]]])
; Parameters ....: $sStatusText - Status text for the busy window
;                  $iOptions    - Busy window options
;                                 |$BUSY_PROGRESS   = Creates a progress bar in the busy window
;                                 |$BUSY_SCREEN     = Create a transparent screen behind the busy window
;                                 |$BUSY_FULLSCREEN = Center the busy window in the monitor instead of the parent gui (Default if $hGui is not specified)
;                                 |$BUSY_TOPMOST    = Give the busy window the $WS_EX_TOPMOST attribute
;                  $iTrans      - The transparency number in the range 0 - 255
;                  $hGui        - Handle to a parent GUI
; Return values .: Success - Returns a 0
;                  Failure - Returns a -1
;                  @Error  - 0 = No error.
;                  |1 = Invalid busy array
; Author ........: zorphnog
; Remarks .......:
; ===============================================================================================================================
Func _Busy_Create($sStatusText = "", $iOptions = -1, $iTrans = -1, $hGui = 0)
    If Not IsArray($g_aBsy_Info) Or UBound($g_aBsy_Info) <> $BSY_SIZE Then Return SetError(1, 0, -1)
    If Not FileExists($g_aBsy_Info[$BSY_THEME_DIR]) Then _Busy_UseTheme("Default")
    Local $iGHeight = 85, $iGWidth = 150, $iHeight, $iWidth, $tRect, $tPoint
    Local $bProgress = False, $bFullScreen = False, $bTopmost = False

    ; Set options
    If $iOptions < 0 Or IsKeyword($iOptions) Then $iOptions = 0
    If $iTrans < 0 Or IsKeyword($iTrans) Then $iTrans = 225
    If $iTrans > 255 Then $iTrans = 255
    If $hGui = 0 Or IsKeyword($hGui) Then
        $hGui = 0
    Else
        $tRect = _WinAPI_GetClientRect($hGui)
        $tPoint = DllStructCreate("int X;int Y")
        _WinAPI_ClientToScreen($hGui, $tPoint)
    EndIf
    $g_aBsy_Info[$BSY_PARWIN] = $hGui
    If BitAND($iOptions, $BUSY_PROGRESS) = $BUSY_PROGRESS Then
        $iGHeight += 10
        $bProgress = True
    EndIf
    If BitAND($iOptions, $BUSY_FULLSCREEN) = $BUSY_FULLSCREEN Then $bFullScreen = True
    If BitAND($iOptions, $BUSY_TOPMOST) = $BUSY_TOPMOST Then $bTopmost = True

    ; Create screen window
    If BitAND($iOptions, $BUSY_SCREEN) = $BUSY_SCREEN Then
        If $bFullScreen Or $hGui = 0 Then
            $g_aBsy_Info[$BSY_SCREENWIN] = GUICreate("", @DesktopWidth, @DesktopHeight, 0, 0, BitOR($WS_POPUP, $WS_DISABLED), $WS_EX_TOOLWINDOW)
        Else
            $g_aBsy_Info[$BSY_SCREENWIN] = GUICreate("", DllStructGetData($tRect, "Right"), DllStructGetData($tRect, "Bottom"), DllStructGetData($tPoint, "X"), DllStructGetData($tPoint, "Y"), BitOR($WS_POPUP, $WS_DISABLED), $WS_EX_TOOLWINDOW, $hGui)
        EndIf
        GUISetBkColor($g_aBsy_Info[$BSY_THEME_SCREEN], $g_aBsy_Info[$BSY_SCREENWIN])
        WinSetTrans($g_aBsy_Info[$BSY_SCREENWIN], "", $iTrans)
        If $bTopmost Then WinSetOnTop($g_aBsy_Info[$BSY_SCREENWIN], "", 1)
        GUISetState(@SW_SHOW, $g_aBsy_Info[$BSY_SCREENWIN])
    EndIf

    ; Create busy window
    If $bFullScreen Or $hGui = 0 Then
        $g_aBsy_Info[$BSY_MAINWIN] = GUICreate("", $iGWidth, $iGHeight, -1, -1, BitOR($WS_POPUP, $WS_BORDER), $WS_EX_TOOLWINDOW)
    Else
        Local $iX = (DllStructGetData($tRect, "Right") - $iGWidth) / 2 + DllStructGetData($tPoint, "X")
        Local $iY = (DllStructGetData($tRect, "Bottom") - $iGHeight) / 2 + DllStructGetData($tPoint, "Y")
        $g_aBsy_Info[$BSY_MAINWIN] = GUICreate("", $iGWidth, $iGHeight, $iX, $iY, BitOR($WS_POPUP, $WS_BORDER), $WS_EX_TOOLWINDOW, $hGui)
        GUISetState(@SW_LOCK, $hGui)
        GUISetState(@SW_DISABLE, $hGui)
    EndIf
    If $bTopmost Then WinSetOnTop($g_aBsy_Info[$BSY_MAINWIN], "", 1)
    GUISetBkColor($g_aBsy_Info[$BSY_THEME_BGCOLOR], $g_aBsy_Info[$BSY_MAINWIN])

    ; Add corner images
    If $g_aBsy_Info[$BSY_THEME_CORNERS] = True Then
        GUISetStyle($WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_LAYERED), $g_aBsy_Info[$BSY_MAINWIN])
        GUICtrlCreatePic($g_aBsy_Info[$BSY_THEME_DIR] & "\tr.bmp", $iGWidth - 5, 0, 5, 5)
        GUICtrlSetState(-1, $GUI_DISABLE)
        GUICtrlCreatePic($g_aBsy_Info[$BSY_THEME_DIR] & "\br.bmp", $iGWidth - 5, $iGHeight - 5, 5, 5)
        GUICtrlSetState(-1, $GUI_DISABLE)
        GUICtrlCreatePic($g_aBsy_Info[$BSY_THEME_DIR] & "\bl.bmp", 0, $iGHeight - 5, 5, 5)
        GUICtrlSetState(-1, $GUI_DISABLE)
        GUICtrlCreatePic($g_aBsy_Info[$BSY_THEME_DIR] & "\tl.bmp", 0, 0, 5, 5)
        GUICtrlSetState(-1, $GUI_DISABLE)
    EndIf
    __GetGifPixSize($g_aBsy_Info[$BSY_THEME_GIF], $iHeight, $iWidth)
    $g_aBsy_Info[$BSY_GIFOBJ] = _GUICtrlCreateGIF($g_aBsy_Info[$BSY_THEME_GIF], Int(($iGWidth - $iWidth) / 2), 10, $g_aBsy_GIFs, $g_hBsy_GIFThread, $g_iBsy_Transparency, $g_tBsy_CurrentFrame)
    GUIRegisterMsg(15, "__Busy_Refresh"); WM_PAINT

    ; Add progress controls
    If $bProgress Then
        GUICtrlCreateLabel("", 15, $iHeight + 18, 120, 2)
        GUICtrlSetBkColor(-1, $g_aBsy_Info[$BSY_THEME_BGBAR])
        $g_aBsy_Info[$BSY_STATUSBAR] = GUICtrlCreateLabel("", 15, $iHeight + 18, 120, 2)
        GUICtrlSetBkColor(-1, $g_aBsy_Info[$BSY_THEME_BAR])
        GUICtrlSetState(-1, $GUI_HIDE)
        $g_aBsy_Info[$BSY_STATUSTEXT] = GUICtrlCreateLabel($sStatusText, 5, $iHeight + 25, $iGWidth - 10, 15, BitOR(0x50000000, $SS_CENTER))
        GUICtrlSetColor(-1, $g_aBsy_Info[$BSY_THEME_TEXT])
        GUICtrlSetFont(-1, -1, -1, -1, "Arial")
    Else
        $g_aBsy_Info[$BSY_STATUSTEXT] = GUICtrlCreateLabel($sStatusText, 5, $iHeight + 15, $iGWidth - 10, 15, BitOR(0x50000000, $SS_CENTER))
        GUICtrlSetColor(-1, $g_aBsy_Info[$BSY_THEME_TEXT])
        GUICtrlSetFont(-1, -1, -1, -1, "Arial")
    EndIf
    GUISetState(@SW_SHOW, $g_aBsy_Info[$BSY_MAINWIN])
    Return 0
EndFunc   ;==>_Busy_Create

; #FUNCTION# ====================================================================================================================
; Name...........: _Busy_Update
; Description ...: Update the status text or progress of the busy window
; Syntax.........: _Busy_Update($sStatusText, $iStatusPercent)
; Parameters ....: $sStatusText    - The status text for the busy window
;                  $iStatusPercent - A percent number for the progress bar in the range 0 - 100
; Return values .: Success - Returns a 0
;                  Failure - Returns a -1
;                  @Error  - 0 = No error.
;                  |1 = Invalid busy array
; Author ........: zorphnog
; Remarks .......:
; ===============================================================================================================================
Func _Busy_Update($sStatusText = "", $iStatusPercent = -1)
    If Not IsArray($g_aBsy_Info) Or UBound($g_aBsy_Info) <> $BSY_SIZE Then Return SetError(1, 0, -1)
    If $sStatusText <> GUICtrlRead($g_aBsy_Info[$BSY_STATUSTEXT]) Then GUICtrlSetData($g_aBsy_Info[$BSY_STATUSTEXT], $sStatusText)
    If $iStatusPercent > -1 Then
        If $iStatusPercent > 100 Then $iStatusPercent = 100
        If $iStatusPercent = 0 Then
            GUICtrlSetState($g_aBsy_Info[$BSY_STATUSBAR], $GUI_HIDE)
        Else
            GUICtrlSetPos($g_aBsy_Info[$BSY_STATUSBAR], 15, 66, 120 * $iStatusPercent / 100)
            If BitAND(GUICtrlGetState($g_aBsy_Info[$BSY_STATUSBAR]), $GUI_HIDE) = $GUI_HIDE Then GUICtrlSetState($g_aBsy_Info[$BSY_STATUSBAR], $GUI_SHOW)
        EndIf
    EndIf
    Return 0
EndFunc   ;==>_Busy_Update

; #FUNCTION# ====================================================================================================================
; Name...........: _Busy_UseTheme
; Description ...: Use a custom theme for the busy window
; Syntax.........: _Busy_UseTheme($sThemeName)
; Parameters ....: $sThemeName - The name of the theme to use
; Return values .: Success - Returns a 0
;                  Failure - Returns a -1
;                  @Error  - 0 = No error.
;                  |1 = Invalid busy array
;                  |2 = Theme directory does not exist
;                  |3 = Settings file does not exist
; Author ........: zorphnog
; Remarks .......: Themes must be created in a folder named after theme located in the Busy folder of the script directory. Each
;                  theme must contain a settings.ini file with color hex values for the background, text, and progress bar. The
;                  animated gif must be named loader.gif. Each theme can also contain four images for the corners of the busy
;                  window. See default theme for an example.
; ===============================================================================================================================
Func _Busy_UseTheme($sThemeName)
    If Not IsArray($g_aBsy_Info) Or UBound($g_aBsy_Info) <> $BSY_SIZE Then Return SetError(1, 0, -1)
    Local $sDir, $sSettingsFile, $sTemp
    $sDir = @ScriptDir & "\Busy\" & $sThemeName
    If Not FileExists($sDir) Then Return SetError(2, 0, -1)
    $sSettingsFile = $sDir & "\settings.ini"
    If Not FileExists($sSettingsFile) Then Return SetError(3, 0, -1)
    $g_aBsy_Info[$BSY_THEME_DIR] = $sDir
    $g_aBsy_Info[$BSY_THEME_BGCOLOR] = __ValidateThemeEntry(IniRead($sSettingsFile, "colors", "bg", -1))
    If @error Then $g_aBsy_Info[$BSY_THEME_BGCOLOR] = 0x000000
    $g_aBsy_Info[$BSY_THEME_TEXT] = __ValidateThemeEntry(IniRead($sSettingsFile, "colors", "text", -1))
    If @error Then $g_aBsy_Info[$BSY_THEME_TEXT] = 0xFFFFFF
    $g_aBsy_Info[$BSY_THEME_BAR] = __ValidateThemeEntry(IniRead($sSettingsFile, "colors", "bar", -1))
    If @error Then $g_aBsy_Info[$BSY_THEME_BAR] = 0xFFFFFF
    $g_aBsy_Info[$BSY_THEME_BGBAR] = __ValidateThemeEntry(IniRead($sSettingsFile, "colors", "bgbar", -1))
    If @error Then $g_aBsy_Info[$BSY_THEME_BGBAR] = 0x000000
    $g_aBsy_Info[$BSY_THEME_SCREEN] = __ValidateThemeEntry(IniRead($sSettingsFile, "colors", "screen", -1))
    If @error Then $g_aBsy_Info[$BSY_THEME_SCREEN] = 0xFFFFFF
    $g_aBsy_Info[$BSY_THEME_CORNERS] = IniRead($sSettingsFile, "theme", "corners", False)
    If $g_aBsy_Info[$BSY_THEME_CORNERS] = "true" Then
        $g_aBsy_Info[$BSY_THEME_CORNERS] = True
    Else
        $g_aBsy_Info[$BSY_THEME_CORNERS] = False
    EndIf
    $g_aBsy_Info[$BSY_THEME_GIF] = $sDir & "\loader.gif"
    __Busy_Reset()
EndFunc   ;==>_Busy_UseTheme

#Region internal functions

Func __ValidateThemeEntry($sEntry)
    If $sEntry = -1 Then Return SetError(1, 0, -1)
    Local $aResult = StringRegExp($sEntry, "(?i)([a-f0-9]{6})", 3)
    If Not @error Then Return "0x" & $aResult[0]
    Return SetError(2, 0, -1)
EndFunc  ;==__ValidateThemeEntry

Func __Busy_Reset()
    $g_aBsy_Info[$BSY_MAINWIN]    = 0
    $g_aBsy_Info[$BSY_STATUSTEXT] = 0
    $g_aBsy_Info[$BSY_STATUSBAR]  = 0
    $g_aBsy_Info[$BSY_SCREENWIN]  = 0
    $g_aBsy_Info[$BSY_GIFOBJ]     = 0
EndFunc   ;==>__Busy_Reset

Func __GetGifPixSize($s_gif, ByRef $pwidth, ByRef $pheight)
    If FileGetSize($s_gif) > 9 Then
        Local $sizes = FileRead($s_gif, 10)
        $pwidth = Asc(StringMid($sizes, 8, 1)) * 256 + Asc(StringMid($sizes, 7, 1))
        $pheight = Asc(StringMid($sizes, 10, 1)) * 256 + Asc(StringMid($sizes, 9, 1))
    EndIf
EndFunc   ;==>__GetGifPixSize

Func __Busy_Refresh($hWnd, $iMsg, $wParam, $lParam)
    #forceref $hWnd, $iMsg, $wParam, $lParam
    _RefreshGIF($g_aBsy_Info[$BSY_GIFOBJ], $g_aBsy_GIFs, $g_hBsy_GIFThread, $g_iBsy_Transparency, $g_tBsy_CurrentFrame)
EndFunc  ;==>_Refresh
#EndRegion internal functions

Update 1 (31 MAR 2010)

I have restructured all gif animation functions to use the GIFAnimation UDF provided by trancexx http://www.autoitscript.com/forum/index.php?showtopic=96132. This means an end to having to use (register/unregister) the gif89.dll that some people reported having problems with. Also, Win7/Vista UAC prevents dll registration/unregistration so trancexx's UDF solves all of these problems (many thanks to trancexx :D). As a result, _Busy_Start and _Busy_Stop functions have been removed and are no longer needed.

I also updated the example script which should make figuring out all of the different options a little easier. Enjoy!

Busy UDF, GIFAnimation UDF (trancexx), example themes, and example script Busy.zip

Busy UDF, example themes, and example script Busy.zip

Edited by zorphnog
Posted

Updated original post:

Added support for transparency screen color specification in themes

Added theme entry validation code

Added parameter to _Busy_Create for specifying parent GUI

  • 3 months later...
  • 7 months later...
Posted

Great stuff! That's fantastic!

Programming today is a race between software engineers striving to
build bigger and better idiot-proof programs, and the Universe
trying to produce bigger and better idiots.
So far, the Universe is winning.

Posted (edited)

:(

For some reason your "regsvr32 /u" command from _Busy_Stop failed.

I wanted to reneme the folder where I've downloaded your script and I couldn't; it kept telling me that the folder is being used.

After I failed to find which app is using that folder I ran "regsvr32 /u gif98.dll" and got the success message. The folder was not locked anymore.

Guess it wouldn't hurt a little debugging :)

Thanks :)

Edited by enaiman

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Posted

How difficult would it be to make this into the format of a control (so I can place it on a window like a button)? Is it easy, or should I not even try?

0x616e2069646561206973206c696b652061206d616e20776974686f7574206120626f64792c20746f206669676874206f6e6520697320746f206e657665722077696e2e2e2e2e

Posted

How difficult would it be to make this into the format of a control (so I can place it on a window like a button)? Is it easy, or should I not even try?

It wouldn't be that difficult. Basically, you would just take the relevant gui creation code from the _Busy_Create function.

Posted (edited)

Suggestion :

an option so title bar is unlocked ( now it's locked, can't move it)

and yes nice udf.

I'll look into that. The problem is that the busy gui is a separate window so if you were to move the parent window the busy window would lose focus and not move with the window. You could register the WM_MOVING message with the parent gui, but that is assuming that it is not already registered by the calling script. Another option would be to create the busy gui as a control of the parent window, but I would have to figure out another way of creating the screen effect for that to work.

Edited by zorphnog
  • 2 months later...
Posted

Nice update zorphnog, great to see the gif89 dependency given the boot, is was indeed a pain in the ass.

I'm have a bit of trouble running scripts with the new UDF from Scite. I'm running Win7 x64 and although if I compile the script (in x86) it works fine, running directly from Scite insists on using AutoIt3_x64.exe which crashes completely whenever the Busy aninamtion is switched off. Is there any way you can resolve the x64 crashing or alternatively, suggest a way to get Scite not to use AutoIt3_x64.exe? Thanks.

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
  • Recently Browsing   0 members

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