Below is the visual basic souce code for progress dots. Of course, it relies on a UserForm to get options from the user; this can be found in the powerpoint source for the macro.

' Progress Dots
' Version 0.1
'
' (C) Copyright 2007 Edward Lopr
'
' This macro adds a toolbar to PowerPoint that can be used to create a
' "progress bar" for your presentation.  A series of dots is drawn across
' the top border, corresponding to slides; and these dots change color
' as you advance through the presentation.  The dots can be grouped into
' "sections," to indicate the overall structure of your talk.  E.g., the
' generated progress bar could look something like this:
'
'         Intro     Topic 1        Topic 2      Conclusions
'        # # # #    # # * *    * * * * * * * * *    * *
'
' The toolbar includes four buttons:
'
'   - Create: opens an options dialogue to customize the progress bar;
'     and then draws the progress bar on each slide.  (This can be slow
'     for large powerpoint presentations.)
'
'   - Refresh: redraws the progress bar.  You will need to use this
'     after adding or removing slides, or section labels.
'
'   - Delete: removes the progress bar from each slide.
'
'   - Section: adds a section label to the current slide.  All slides
'     from the current slide to the next slide that you asssign a
'     section label to are considered to be part of the same section,
'     and will be displayed in a group.  E.g., in the example above,
'     four slides are marked with section labels: the first is marked
'     with "Intro," the fifth with "Topic 1," the ninth with "Topic 2,"
'     and the eighteenth with "Conclusions."
'
' This is the first program I've written in Visual Basic, so the code may
' not be as clean as it should be.
'
'                                License:
' =========================================================================
' Permission is hereby granted, free of charge, to any person obtaining
' a copy of this software and any associated documentation files (the
' "Software"), to deal in the Software without restriction, including
' without limitation the rights to use, copy, modify, merge, publish,
' distribute, sublicense, and/or sell copies of the Software, and to
' permit persons to whom the Software is furnished to do so, subject to
' the following conditions:
'
' The above copyright notice and this permission notice shall be included
' in all copies or substantial portions of the Software.
'
' The software is provided "as is", without warranty of any kind, express
' or implied, including but not limited to the warranties of
' merchantability, fitness for a particular purpose and noninfringement.
' In no event shall the authors or copyright holders be liable for any
' claim, damages or other liability, whether in an action of contract, tort
' or otherwise, arising from, out of or in connection with the software or
' the use or other dealings in the software.
' =========================================================================

Option Explicit

Public OptionsOk As Boolean

Type ColorType
    Red As Integer
    Green As Integer
    Blue As Integer
End Type

Type ProgressDotsOptions
    LeftMargin As Double
    RightMargin As Double
    yMargin As Double
    textHeight As Double
    dotSize As Double
    SectionGap As Double  ' = secMargin/dotMargin
    seenDotColor As ColorType
    unseenDotColor As ColorType
    seenTextColor As ColorType
    unseenTextColor As ColorType
    fontName As String
End Type

' We don't support more than 100 sections.
Type ProgressDotsSectionInfo
    startSlide As Long
    numSections As Long
    sectTitles(100) As String
    sectStart(100) As Long
End Type
Function SerializeColor(c As ColorType) As String
    SerializeColor = CStr(c.Red) & ":" & CStr(c.Green) & ":" & CStr(c.Blue)
End Function

Function DeserializeColor(s As String) As ColorType
    Dim words() As String
    words() = Split(s, ":")
    DeserializeColor.Red = CInt(words(0))
    DeserializeColor.Green = CInt(words(1))
    DeserializeColor.Blue = CInt(words(2))
End Function

Function ColorToRGB(c As ColorType) As Long
    ColorToRGB = RGB(c.Red, c.Green, c.Blue)
End Function

Function SerializeProgressOptions(theOptions As ProgressDotsOptions) As String
    With theOptions:
        SerializeProgressOptions = "version3 " & _
            .LeftMargin & " " & .RightMargin & " " & .yMargin & " " & _
            .textHeight & " " & .dotSize & " " & .SectionGap & " " & _
            SerializeColor(.seenDotColor) & " " & _
            SerializeColor(.unseenDotColor) & " " & _
            SerializeColor(.seenTextColor) & " " & _
            SerializeColor(.unseenTextColor) & " " & _
            Replace(.fontName, " ", "#")
    End With
End Function

Function DeserializeProgressOptions(s As String) As ProgressDotsOptions
    ' Split the string into words
    Dim words() As String
    words() = Split(s)

    ' Use those words to populate theOptions.
    Dim theOptions As ProgressDotsOptions
    If words(0) <> "version3" Then
        theOptions = getDefaultOptions()
    Else
        theOptions.LeftMargin = CDbl(words(1))
        theOptions.RightMargin = CDbl(words(2))
        theOptions.yMargin = CDbl(words(3))
        theOptions.textHeight = CDbl(words(4))
        theOptions.dotSize = CDbl(words(5))
        theOptions.SectionGap = CDbl(words(6))
        theOptions.seenDotColor = DeserializeColor(words(7))
        theOptions.unseenDotColor = DeserializeColor(words(8))
        theOptions.seenTextColor = DeserializeColor(words(9))
        theOptions.unseenTextColor = DeserializeColor(words(10))
        theOptions.fontName = Replace(words(11), "#", " ")
    End If

    ' Return it
    DeserializeProgressOptions = theOptions

End Function

Function getDefaultOptions() As ProgressDotsOptions

With getDefaultOptions:
    .LeftMargin = 50
    .RightMargin = 50
    .yMargin = 5
    .textHeight = 12
    .dotSize = 7.8
    .seenDotColor.Red = 0
    .seenDotColor.Green = 128
    .seenDotColor.Blue = 128
    .unseenDotColor.Red = 186
    .unseenDotColor.Green = 223
    .unseenDotColor.Blue = 226
    .seenTextColor.Red = 0
    .seenTextColor.Green = 128
    .seenTextColor.Blue = 128
    .unseenTextColor.Red = 186
    .unseenTextColor.Green = 223
    .unseenTextColor.Blue = 226
    .SectionGap = 8
    .fontName = "arial"
End With
    End Function

Sub Auto_Open()
    Dim TOOLBAR_STYLE, DEBUG_TOOLBAR
    TOOLBAR_STYLE = msoButtonIconAndCaption
    DEBUG_TOOLBAR = True

    Dim oToolbar As CommandBar
    Dim oSetSectionButton As CommandBarButton
    Dim oAddProgressButton As CommandBarButton
    Dim oDelProgressButton As CommandBarButton
    Dim oRefreshButton As CommandBarButton
    Dim oOptionsButton As CommandBarButton
    Dim MyToolbar As String

    ' Give the toolbar a name
    MyToolbar = "Progress Dots"

    On Error Resume Next
    ' so that it doesn't stop on the next line if the toolbar's already there

    ' Create the toolbar; PowerPoint will error if it already exists
    Set oToolbar = CommandBars.Add(name:=MyToolbar, _
        Position:=msoBarFloating, Temporary:=True)
    If Err.Number <> 0 Then
        If DEBUG_TOOLBAR Then
            CommandBars(MyToolbar).Delete
        End If
        ' The toolbar's already there, so we have nothing to do
        Exit Sub
    End If

    On Error GoTo ErrorHandler

    Set oSetSectionButton = oToolbar.Controls.Add(Type:=msoControlButton)
    With oSetSectionButton
         .DescriptionText = "Begin progress bar section"
         .Caption = "Section"
         .OnAction = "SetSection"
         .Style = TOOLBAR_STYLE
         .FaceId = 598
    End With

     Set oAddProgressButton = oToolbar.Controls.Add(Type:=msoControlButton)
     With oAddProgressButton
         .DescriptionText = "Add a progress bar"
         .Caption = "Create"
         .OnAction = "AddProgressBar"
         .Style = TOOLBAR_STYLE
         .FaceId = 213
    End With

    Set oDelProgressButton = oToolbar.Controls.Add(Type:=msoControlButton)
    With oDelProgressButton
         .DescriptionText = "Remove the progress bar"
         .Caption = "Delete"
         .OnAction = "DelProgressBar"
         .Style = TOOLBAR_STYLE
         .FaceId = 214
    End With

    Set oRefreshButton = oToolbar.Controls.Add(Type:=msoControlButton)
    With oRefreshButton
         .DescriptionText = "Refresh progress bar"
         .Caption = "Refresh"
         .OnAction = "RefreshProgressBar"
         .Style = TOOLBAR_STYLE
         .FaceId = 1020
    End With

    oToolbar.Top = 150
    oToolbar.Left = 150
    oToolbar.Visible = True

NormalExit:
    Exit Sub   ' so it doesn't go on to run the errorhandler code
ErrorHandler:
     'Just in case there is an error
     MsgBox Err.Number & vbCrLf & Err.Description
     Resume NormalExit:
End Sub

Sub SetSection()
    Dim curSlide As slide
    Dim strTitle As String

    ' Get the current slide.
    Set curSlide = Application.ActiveWindow.View.slide

    ' Ask for a tilte
    strTitle = InputBox("Enter a title for the section " & _
        "starting on slide " & curSlide.SlideNumber & ".", _
        "Progress Dots: Section Title", _
        curSlide.Tags.Item("progress dots title"))

    ' Store the title as a tag.
    Call curSlide.Tags.Add("progress dots title", strTitle)

End Sub

Sub optionsToForm(theOptions As ProgressDotsOptions)
    Dim sectNum As Long
    Dim sectionInfo As ProgressDotsSectionInfo

    ' Display the spacing parameters
    OptionsForm.LeftMargin.Text = CStr(theOptions.LeftMargin)
    OptionsForm.RightMargin.Text = CStr(theOptions.RightMargin)
    OptionsForm.TopMargin.Text = CStr(theOptions.yMargin)
    OptionsForm.SectionGap.Value = 10 * theOptions.SectionGap
    OptionsOk = False

    ' Display a combobox for the font.
    OptionsForm.fontName.Clear
    Call OptionsForm.fontName.AddItem("Times New Roman")
    Call OptionsForm.fontName.AddItem("Arial")
    Call OptionsForm.fontName.AddItem("Courier")
    OptionsForm.fontName.Value = theOptions.fontName
    OptionsForm.fontSize.Value = CStr(theOptions.textHeight)

    ' Display the colors
    OptionsForm.dotSeenR.Value = theOptions.seenDotColor.Red
    OptionsForm.dotSeenG.Value = theOptions.seenDotColor.Green
    OptionsForm.dotSeenB.Value = theOptions.seenDotColor.Blue
    OptionsForm.dotUnseenR.Value = theOptions.unseenDotColor.Red
    OptionsForm.dotUnseenG.Value = theOptions.unseenDotColor.Green
    OptionsForm.dotUnseenB.Value = theOptions.unseenDotColor.Blue
    OptionsForm.textSeenR.Value = theOptions.seenTextColor.Red
    OptionsForm.textSeenG.Value = theOptions.seenTextColor.Green
    OptionsForm.textSeenB.Value = theOptions.seenTextColor.Blue
    OptionsForm.textUnseenR.Value = theOptions.unseenTextColor.Red
    OptionsForm.textUnseenG.Value = theOptions.unseenTextColor.Green
    OptionsForm.textUnseenB.Value = theOptions.unseenTextColor.Blue
    OptionsForm.dotSize.Value = theOptions.dotSize * 5

    ' Display the list of sections.
    sectionInfo = findSections()
    OptionsForm.SectionList.Clear
    For sectNum = 1 To sectionInfo.numSections
        Call OptionsForm.SectionList.AddItem( _
        CStr(sectionInfo.sectStart(sectNum)) & ": " & _
        sectionInfo.sectTitles(sectNum))
    Next sectNum

End Sub

Function optionsFromForm() As ProgressDotsOptions
    optionsFromForm = getDefaultOptions()
    ' Copy the user input back to the options structure.
    optionsFromForm.LeftMargin = CDbl(OptionsForm.LeftMargin.Text)
    optionsFromForm.RightMargin = CDbl(OptionsForm.RightMargin.Text)
    optionsFromForm.yMargin = CDbl(OptionsForm.TopMargin.Text)
    optionsFromForm.SectionGap = OptionsForm.SectionGap.Value * 0.1
    optionsFromForm.fontName = OptionsForm.fontName.Value
    optionsFromForm.textHeight = CInt(OptionsForm.fontSize.Value)
    optionsFromForm.seenDotColor.Red = CInt(OptionsForm.dotSeenR.Value)
    optionsFromForm.seenDotColor.Green = CInt(OptionsForm.dotSeenG.Value)
    optionsFromForm.seenDotColor.Blue = CInt(OptionsForm.dotSeenB.Value)
    optionsFromForm.unseenDotColor.Red = CInt(OptionsForm.dotUnseenR.Value)
    optionsFromForm.unseenDotColor.Green = CInt(OptionsForm.dotUnseenG.Value)
    optionsFromForm.unseenDotColor.Blue = CInt(OptionsForm.dotUnseenB.Value)
    optionsFromForm.seenTextColor.Red = CInt(OptionsForm.textSeenR.Value)
    optionsFromForm.seenTextColor.Green = CInt(OptionsForm.textSeenG.Value)
    optionsFromForm.seenTextColor.Blue = CInt(OptionsForm.textSeenB.Value)
    optionsFromForm.unseenTextColor.Red = CInt(OptionsForm.textUnseenR.Value)
    optionsFromForm.unseenTextColor.Green = CInt(OptionsForm.textUnseenG.Value)
    optionsFromForm.unseenTextColor.Blue = CInt(OptionsForm.textUnseenB.Value)
    optionsFromForm.dotSize = OptionsForm.dotSize.Value * 0.2
End Function

Sub customizeOptions()
    Dim s As String
    Dim theOptions As ProgressDotsOptions
    Dim thePresentation As Presentation

    ' Load the options.
    Set thePresentation = ActivePresentation
    s = thePresentation.Tags.Item("__progress-dots-config__")
    If s = "" Then s = SerializeProgressOptions(getDefaultOptions())
    theOptions = DeserializeProgressOptions(s)

    ' Copy them to the form
    Call optionsToForm(theOptions)

    ' Show the form.
    OptionsForm.Show

    ' Save the options
    If OptionsOk Then
        theOptions = optionsFromForm()
        Debug.Print "Saving options..."
        s = SerializeProgressOptions(theOptions)
        Call thePresentation.Tags.Add("__progress-dots-config__", s)
    End If
End Sub



Sub AddProgressBar()
    ' make sure there's something to do.
    If ActivePresentation.Slides.Count = 1 Then
        MsgBox ("Add some more slides first")
        Exit Sub
    End If
    ' Set options.
    Call customizeOptions
    ' If everything went well, draw the progress bar.
    If OptionsOk Then
        Call RefreshProgressBar
    End If
End Sub


Sub RefreshProgressBar()
    Dim s As String
    Dim theOptions As ProgressDotsOptions

    If ActivePresentation.Slides.Count = 1 Then
        MsgBox ("Add some more slides first")
        Exit Sub
    End If

    ' Load the options.
    s = ActivePresentation.Tags.Item("__progress-dots-config__")
    If s = "" Then s = SerializeProgressOptions(getDefaultOptions())
    theOptions = DeserializeProgressOptions(s)

    ' Update the progress bar.
    Call DelProgressBar
    Call MakeProgressBar(theOptions)
End Sub

Function findSections() As ProgressDotsSectionInfo
    Dim slideNum, sectionNum As Long
    Dim curTitle As String

    ' Initialize the 0th group.
    findSections.sectTitles(0) = ""
    findSections.sectStart(0) = 1

    ' Scan for section titles.
    sectionNum = 0
    Debug.Print "Scanning for sections..."
    For slideNum = 1 To ActivePresentation.Slides.Count
        curTitle = ActivePresentation.Slides(slideNum).Tags.Item("progress dots title")
        If (curTitle <> "") Then
            sectionNum = sectionNum + 1
            findSections.sectTitles(sectionNum) = curTitle
            findSections.sectStart(sectionNum) = slideNum
            If sectionNum = 1 Then findSections.startSlide = slideNum
        End If
    Next slideNum

    ' If no sections were found, make a single "fake" section
    If sectionNum = 0 And ActivePresentation.Slides.Count > 1 Then
        sectionNum = 1
        findSections.sectTitles(1) = ""
        findSections.sectStart(1) = 2
        findSections.startSlide = 2
    End If

    ' Record the end slide as the "next" section start -- this makes
    ' calculations easier.
    findSections.sectStart(sectionNum + 1) = _
        ActivePresentation.Slides.Count + 1

    ' Return the information we found.
    findSections.numSections = sectionNum

End Function


Sub MakeProgressBar(theOptions As ProgressDotsOptions)
    Dim sectinfo As ProgressDotsSectionInfo
    Dim slideNum As Long

    ' Scan for sections.
    sectinfo = findSections()

    ' If we didn't find any sections, there's nothing more to do.
    If sectinfo.numSections = 0 Then
        MsgBox ("Add some more slides first!")
        Exit Sub
    End If

    ' Loop through slides, and draw a progress bar on each one.
    Debug.Print "Drawing Progress bars..."
    For slideNum = sectinfo.startSlide To ActivePresentation.Slides.Count
        Debug.Print "  Slide " & slideNum
        Call DrawProgressBarOnSlide(slideNum, sectinfo, _
                theOptions, "__progress-dots__")
    Next slideNum
End Sub

Sub DrawProgressBarOnSlide(slideNum As Long, _
        sectinfo As ProgressDotsSectionInfo, _
        theOptions As ProgressDotsOptions, _
        shapeTag As String)
    Dim x, labelWidth, labelLeft, sectionMargin, dotMargin As Double
    Dim numDotsInSection, dotNum, sectNum, numDots As Long
    Dim dot, sectTitle As Shape
    Dim slideWidth, gapSize As Double
    Dim firstShape As Long

    ' Record the index of the first shape we'll be creating.  We'll use this
    ' later to select the whole range of shapes & group them.
    firstShape = ActivePresentation.Slides(slideNum).Shapes.Count + 1

    ' Calculate dotMargin & sectionMargin, which are used to layout the
    ' dots & section titles.
    numDots = ActivePresentation.Slides.Count - sectinfo.startSlide + 1
    slideWidth = ActivePresentation.PageSetup.slideWidth
    gapSize = (slideWidth - theOptions.LeftMargin - theOptions.RightMargin _
                     - theOptions.dotSize * numDots)
    If sectinfo.numSections = 1 Or numDots = sectinfo.numSections Then
        If sectinfo.numSections = 1 And numDots = sectinfo.numSections Then
            dotMargin = 0
            sectionMargin = 0
        Else
            dotMargin = gapSize / (numDots - 1)
            sectionMargin = dotMargin
        End If
    Else
        sectionMargin = gapSize / _
            ((numDots - sectinfo.numSections) / theOptions.SectionGap + _
               (sectinfo.numSections - 1))
        dotMargin = sectionMargin / theOptions.SectionGap
    End If

    x = theOptions.LeftMargin   ' our current x position.
    sectNum = 1                 ' our current section num

    ' Loop through the slides, and draw a dot for each one.
    For dotNum = sectinfo.startSlide To ActivePresentation.Slides.Count

        ' Draw the dot.
        Set dot = ActivePresentation.Slides(slideNum).Shapes.AddShape( _
            msoShapeOval, x, _
            theOptions.yMargin + theOptions.textHeight + 2, _
            theOptions.dotSize, theOptions.dotSize)
        Call dot.Tags.Add(shapeTag, "yes")
        ' Color the dot.
        If dotNum <= slideNum Then
            dot.Fill.ForeColor.RGB = ColorToRGB(theOptions.seenDotColor)
            dot.Line.ForeColor.RGB = ColorToRGB(theOptions.seenDotColor)
        Else
            dot.Fill.ForeColor.RGB = ColorToRGB(theOptions.unseenDotColor)
            dot.Line.ForeColor.RGB = ColorToRGB(theOptions.unseenDotColor)
        End If

        ' If this dot starts a section, then draw the section title.
        If sectinfo.sectStart(sectNum) = dotNum Then
            numDotsInSection = (sectinfo.sectStart(sectNum + 1) - dotNum)
            labelWidth = numDotsInSection * theOptions.dotSize + _
                         (numDotsInSection - 1) * dotMargin
            labelLeft = x
            ' Add some extra space
            labelWidth = labelWidth + 400
            labelLeft = labelLeft - 200
            ' But don't fall off either edge.
            If labelLeft < 0 Then
                labelWidth = labelWidth + labelLeft * 2
                labelLeft = 0
            End If
            If labelWidth + labelLeft > slideWidth Then
                labelWidth = labelWidth + (slideWidth - labelLeft - labelWidth) * 2
                labelLeft = slideWidth - labelWidth
            End If

            Set sectTitle = ActivePresentation.Slides(slideNum). _
               Shapes.AddTextbox(msoTextOrientationHorizontal, _
               labelLeft, theOptions.yMargin, labelWidth, _
               theOptions.textHeight + 10)
            Call sectTitle.Tags.Add(shapeTag, "yes")
            ' Style the section title.
            With sectTitle.TextFrame
                .TextRange.Text = sectinfo.sectTitles(sectNum)
                .TextRange.Font.Size = theOptions.textHeight
                .TextRange.Font.name = theOptions.fontName
                .HorizontalAnchor = msoAnchorCenter
                .MarginBottom = 0
                .MarginTop = 0
                .MarginLeft = 0
                .MarginRight = 0
                If dotNum <= slideNum Then
                    .TextRange.Font.Color = ColorToRGB(theOptions.seenTextColor)
                Else
                    .TextRange.Font.Color = ColorToRGB(theOptions.unseenTextColor)
                End If
            End With

            ' Update our section counter
            sectNum = sectNum + 1
        End If

        ' Update our x position.
        If sectinfo.sectStart(sectNum) = dotNum + 1 Then
            x = x + sectionMargin + theOptions.dotSize
        Else
            x = x + dotMargin + theOptions.dotSize
        End If

    Next dotNum

    ' Group all the new shapes.
    Dim numShapes, i As Long
    Dim oShapeArray() As Long
    Dim oGroupShape As Shape
    numShapes = ActivePresentation.Slides(slideNum).Shapes.Count - firstShape + 1
    If numShapes > 1 Then
        ReDim oShapeArray(numShapes)
        For i = 0 To numShapes - 1
            oShapeArray(i) = firstShape + i
        Next i
        Set oGroupShape = ActivePresentation.Slides(slideNum). _
                            Shapes.Range(oShapeArray).Group
        Call oGroupShape.Tags.Add(shapeTag, "yes")
    End If
    ' Testing:
    'Dim oShapeArray(500) As Long
    'Dim iShapeCount As Integer

    'Dim z As ShapeRange
    'Dim ss As slide
    'Set ss = ActivePresentation.Slides(slideNum)
    'Set z = ss.Shapes.Range(oShapeArray)
    'z.Group

    ' Group it all together, and deselect it.
    'If Application.ActiveWindow.Selection.ShapeRange.Count > 1 Then
    '    oGroupShape = Application.ActiveWindow.Selection.ShapeRange.Group
    '    Call oGroupShape.Tags.Add(shapeTag, "yes")
    'End If
    'Application.ActiveWindow.Selection.Unselect

End Sub


Sub DelProgressBar()
    Dim slideNum As Long
    Debug.Print "Deleting old progress bar..."
    For slideNum = 1 To ActivePresentation.Slides.Count
        Call DelProgressBarOnSlide(slideNum, "__progress-dots__")
    Next slideNum
End Sub

Sub DelProgressBarOnSlide(slideNum As Long, shapeTag As String)
    Dim shapeNum As Long
    shapeNum = 1
    Do While shapeNum <= ActivePresentation.Slides(slideNum).Shapes.Count
        If ActivePresentation.Slides(slideNum).Shapes(shapeNum). _
                    Tags.Item(shapeTag) = "yes" Then
            ActivePresentation.Slides(slideNum).Shapes(shapeNum).Delete
        Else
            shapeNum = shapeNum + 1
        End If
    Loop
End Sub



Sub PreviewProgressBar(theOptions As ProgressDotsOptions)
    Dim curSlide As slide
    Dim sectinfo As ProgressDotsSectionInfo


    Set curSlide = Application.ActiveWindow.View.slide
    sectinfo = findSections()

    ' Delete any progress bar on this slide.
    Call DelProgressBarOnSlide(curSlide.SlideNumber, "__progress-dots__")

    ' Draw the new one.
    Call DrawProgressBarOnSlide(curSlide.SlideNumber, sectinfo, theOptions, _
            "__progress-dots__")
End Sub