A Flexible Progress Window in VBScript

I’ve seen a few variations over the years on how to create a progress bar and an update window in VBScript.  I’ve taken many of the ideas and some of my own to create what I hope is a flexible solution that not only allows you to display updates, reports, etc., but also a reasonable looking progress bar.   If you want to skip ahead then the code is at the bottom of this post and includes an example, but for those of you who want to know a little more about how to use it or how it works I’ll explain some of the whys and wherefores.

First of all I’ve created this progress window as a class.  This means that (certainly from a programming perspective at the least) everything is presented neatly and if necessary you can create a multiple instances.  So the first thing to do is to create a new instance using New ProgressWindow.  After doing this you then use the Initialise method for your object to create the window.

The window is a Microsoft Internet Explorer window.  I’ve chosen this because an HTML page allows me the greatest amount of flexibility in what to display and MSIE s found on pretty much every PC - although the recent EU / Microsoft dealings mean that the European version of Windows 7 may be bereft of this browser by default.  When initialising the window, you get parameters to specify a title, the size (width & height in pixels) and also a number of regions.

Each region is a section of the HTML page and you can independently update each region independently.  Because of this you can enter the content as HTML.  This allows you to not only enter text, but also create tables, insert images, hyperlinks, etc.  The method to use to set the content of a region is UpdateRegion.  There are also a couple of methods to clear one or all regions - ClearRegion and ClearAllRegions respectively.

The last area to be explained is the progress bar.  The “UpdateRegionProgress” method takes three parameters.  The first identifies which region is to host the progress bar.  The second parameter is the percentage of the progress bar that should be filled.  The final parameter is used to set the length of the progress bar (by number of characters).  The method doesn’t include any option to add anything before or after the progress bar, but it would be a simple modification to add in parameters for prefix and suffix HTML.

The method also has four constants that allow you to specify the characters to be used to form the progress bar and the colours of the characters.   This could be changed to any valid HTML and so you could specify images to be loaded for your progress bar.

The example code creates the progress window with three regions and populates them each with text.  The third region shows a simple example of HTML “rich” text with a word picked out in bold.  After a couple of seconds the second region’s text is updated.  Within a couple more seconds the content is cleared and then a new message is put into the first region.  The second and third regions are then set to display progress as a loop increments between 0 and 100.  The second region displays the progress as a numeric percentage whereas the third region displays this as a progress bar.  After a couple more seconds the window closes. The images below show what this looks like.

The initial window has three regions.

Each region’s content can be changed independently of the other regions.

The third region shows a progress bar.

So just drop the ProgressWindow class into your script and you’re ready to display your script progress.

Option Explicit

'Instantiate a progress window with three regions
Dim objThing
Set objThing = new ProgressWindow
objThing.Initialise "This is an example progress window", 4, 750, 250

'First population of window
objThing.UpdateRegion 1, "This is the first region"
objThing.UpdateRegion 2, "... wait for it ..."
objThing.UpdateRegion 3, "This is the third region"
WScript.Sleep 2000

'Show that we can simply update an individual region
objThing.UpdateRegion 2, "This is the second region"
WScript.Sleep 2000

'Clear everything and then put a new message up
objThing.ClearAllRegions
objThing.UpdateRegion 1, "This window will close in a few seconds..."

'This loop shows how to use a progress bar 60 characters long
Dim intPercentage
For intPercentage = 0 to 100
    objThing.UpdateRegion 2, "Progress: " & intPercentage & "%"
    objThing.UpdateRegionProgress 3, intPercentage, 60
    WScript.Sleep 75
Next

'Pause for a couple of seconds then get rid of the progress window
WScript.Sleep 2000
objThing.Destroy

'################
'#### CLASSES ###
'################
'Create an instance of this class to create a progress window based on an HTML page
'displayed in an Internet Explorer window.
Class ProgressWindow

    'Progress Window Properties
    Dim intWidth
    Dim intHeight
    Dim intRegions
    Dim strTitle
    Dim objProgress

    'Create the progress window
    'The first parameter is the title of the progress window.
    'The second parameter is the number of regions on the page you wish to be able to update independently.
    'The third parameter is the width of the window in pixels.
    'The fourth parameter is the height of the window in pixels.
    Sub Initialise(p_strTitle, p_intRegions, p_intWidth, p_intHeight)
        'Set class properties
        strTitle = p_strTitle
        intRegions = p_intRegions
        intWidth = p_intWidth
        intHeight = p_intHeight

        'Create the progress window
        CreateMSIEWindow objProgress
    End Sub

    'Display the basic window
    Sub CreateMSIEWindow(p_objMSIE)
        Dim strHTML
        Dim intCounter

        strHTML = ""
        For intCounter = 1 to intRegions
            strHTML = strHTML & ""
        Next
        strHTML = "" & strHTML & ""

        Set p_objMSIE = CreateObject("InternetExplorer.Application")
        With p_objMSIE
            .Navigate2 "about:blank"
            Do While .readyState <> 4
                Wscript.sleep 10
            Loop
            .Document.Title = strTitle
            .Document.Body.InnerHTML = strHTML
            .Document.Body.Scroll = "no"
            .Toolbar = False
            .StatusBar = False
            .Resizable = False
            .Width = intWidth
            .Height = intHeight
            .Left = 0
            .Top = 0
            .Visible = True
        End With
    End Sub

    'This should be called to close the window
    Sub Destroy()
        objProgress.Quit
    End Sub

    'This method can be used to update the content of a specified region
    Sub UpdateRegion(p_intRegion, p_strContent)
        objProgress.Document.All("REGION" & Cstr(p_IntRegion)).innerHTML = p_strContent
    End Sub

    'This method clears a specified region.
    Sub ClearRegion(p_intRegion)
        UpdateRegion p_intRegion, ""
    End Sub

    'This method clears all of the regions at once.
    Sub ClearAllRegions()
        Dim intRegion

        For intRegion = 1 to intRegions
            UpdateRegion intRegion, ""
        Next
    End Sub

    'Set a progress bar as a region...
    'The first parameter is which region.
    'The second parameter is the percentage completion of the bar.
    'The third parameter is the number of characters that make up the bar.
    Sub UpdateRegionProgress(p_intRegion, p_intPrecentageProgress, p_intCharacterRange)
        'These constants are used to create the progress bar
        Const SOLID_BLOCK_CHARACTER = "?"
        Const EMPTY_BLOCK_CHARACTER = "?"
        Const SOLID_BLOCK_COLOUR = "#ffcc33;"
        Const EMPTY_BLOCK_COLOUR = "#666666;"

        Dim intSolidBlocks, intEmptyBlocks, intCounter
        Dim strProgress

        'Calculate how many blocks we need to create
        intSolidBlocks = round(p_intPrecentageProgress / 100 * p_intCharacterRange)
        intEmptyBlocks = p_intCharacterRange - intSolidBlocks
 
        intCounter = 0
        'Build the progress so far blocks
        strProgress = ""
        While intCounter < intSolidBlocks
            strProgress = strProgress & SOLID_BLOCK_CHARACTER
            intCounter = intCounter + 1
        Wend
 
        strProgress = strProgress &  ""
        
        'Build the progress to be met blocks
        strProgress = strProgress & ""
        intCounter = 0
        While intCounter < intEmptyBlocks
            strProgress = strProgress & EMPTY_BLOCK_CHARACTER
            intCounter = intCounter + 1
        Wend
        strProgress = strProgress &  ""
 
        'Set the specified region to be the blocks
        UpdateRegion p_intRegion, strProgress
    End Sub

End Class
Author: Stephen Millard
Tags: | vbs |

Buy me a coffeeBuy me a coffee



Related posts that you may also like to read