Easy method to use Windows Explorer's ProgressDialog COM object to show progress of processing, uploads, downloads, etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177  | import win32gui
class COMprogressDialog(object):
    _trace = False
    def __init__(self, title='Progress Dialog', animation_res=161):
        '''
        COMprogressDialog - Windows COM object that shows progress of task.
                            This dialog runs in a separate thread so it can be
                            run from virtually any program without adding
                            threading complexity to that program.
        title         - Dialog window title
        animation_res - animation resource .AVI for interesting
                        progress display
                        animation_res=160 (move)
                        animation_res=161 (copy) [DEFAULT]
        COMprogressDialog.dialog class methods -
          StartProgressDialog(hwndParent, lEnableModeless, dwFlags, pvReserved)
          StopProgressDialog()
          SetTitle(sTitle)
          SetAnimation(hInstAnimation, idAnimation)
          HasUserCancelled()
          SetProgress(completed, total)
          SetProgress64(completed64, total64)
          SetLine(lineNum, sText, lCompactPath, pvReserved)
          SetCancelMsg(sCancelMsg, pvReserved)
          Timer() - Reset timer
          Release() - Close dialog, release resources
        Animation resource in shell32.dll that points to .AVIs
        Written by: Larry Bates (with substantial help from Thomas Heller and
                    Tim Golden on COM interfacing to IProgressDialog),
                    February 2008
                    Updated February 2011 - Added close() method to gracefully
                    close the dialog.
                    
        License: GPL
        Requires: ctypes, comtypes, win32gui
        '''
        LM = "COMprogressDialog.__init__"
        if self._trace:
            print "%s-Entering" % LM
        #
        # Save title so I can update it with % completed as I progress
        #
        self.title = title
        #
        # Get a list of topWindows
        #
        topWindows = list()
        win32gui.EnumWindows(self._windowEnumerationHandler, topWindows)
        #
        # Isolate Program Manager window from all the other topWindows,
        # this will be used as the parent window for the dialog.
        #
        hwndParent = [w[0] for w in topWindows if w[1] == 'Program Manager'][0]
        import comtypes.client
        try:
            import comtypes.gen.VBProgressDialog
            
        except ImportError:
            #
            # Create object from the progress tlb file for the COM Progress
            # Dialog
            #
            comtypes.client.GetModule('progdlg.tlb')
            
        vbpd = comtypes.gen.VBProgressDialog
        #
        # Create instance of progress dialog
        #
        if self._trace:
            print "%s-creating instance of progress dialog" % LM
        self.dialog = comtypes.client.CreateObject(vbpd.ProgressDialog)
        #
        # Set the animation for the dialog (default=copy) from shell32.dll
        #
        import ctypes
        #
        # Pointer to shell32.dll
        #
        shell32 = ctypes.windll.shell32
        #
        # Get handle for this
        #
        m_hLibShell32 = shell32._handle
        #
        # Set the animation based on animation_res number (default animation
        # is copy animation).
        #
        self.dialog.SetAnimation(m_hLibShell32, animation_res)
        #
        # Insert title into top of dialog
        #
        self.dialog.SetTitle(title)
        #
        # Start the dialog
        #
        self.dialog.StartProgressDialog(hwndParent, None, 0, 0)
        if self._trace:
            print "%s-Leaving" % LM
        
    def _windowEnumerationHandler(self, hwnd, resultList):
        #
        # Get a list of the top level windows so I can find Program Manager
        #
        resultList.append((hwnd, win32gui.GetWindowText(hwnd)))
    def close(self):
        self.dialog.StopProgressDialog()
if __name__ == "__main__":
    import time
    compactPath = 1
    total = 100
    filenames = ['C:/pagefile.sys',
                 'C:/Documents and Settings/All Users/Start Menu/' \
                 'Programs/Administrative Tools/Computer Management'
                ]
    for i in xrange(3):
        title = "COMprogressDialot Unit Test %i" % (i+1)
        #
        # Create instance of the COMprogressDialog class
        #
        DLGobj = COMprogressDialog(title=title)
        #
        # Set the first line of the dialog to the filename
        #
        DLGobj.dialog.SetLine(1, filenames[0], compactPath, 0)
        for j in xrange(total):
            completed = int(100.0 / total * j)
            completed = "%s (%i%%)" % (title, completed)
            #
            # Update title to include (xx%) completed
            #
            DLGobj.dialog.SetTitle(completed)
            #
            # Update the progress gauge
            #
            DLGobj.dialog.SetProgress(j, total)
            #
            # Set second line to ##### of ##### bytes uploaded
            #
            line2 = "%i of %i bytes uploaded" % (j, total)
            DLGobj.dialog.SetLine(2, line2, 0, 0)
            #
            # See if user pushed cancel button
            #
            if DLGobj.dialog.HasUserCancelled():
                break
            #
            # Simulate uploading two equal sized files
            #
            if j == 50:
                compactPath = 1
                DLGobj.dialog.SetLine(1, filenames[1], compactPath, 0)
                
            time.sleep(0.1)
##        #
##        # Only necessary because of nested loops
##        #
##        if DLGobj.dialog.HasUserCancelled():
##            break
        #
        # Have the COM dialog close and release it's resources
        #
        DLGobj.close()
 | 
Launches ProgressDialog in a separate thread for showing progress on long running tasks.
Download
Copy to clipboard
I don't have progdlg.tlb anywhere, nor an VBProgressDialog object registered. Where do you get those?