Welcome, guest | Sign In | My Account | Store | Cart
import win32gui

class COMprogressDialog(object):
    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)

        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

        License: GPL
        Requires: ctypes, comtypes, win32gui
        '''
        #
        # Save title so I can update it with % completed as I progress
        #
        self.title = title
        #
        # Get a list of topWindows
        #
        topWindows = []
        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
        #
        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 if present
        #
        if title:
            self.dialog.SetTitle(title)
        #
        # Start the dialog
        #
        self.dialog.StartProgressDialog(hwndParent, None, 0, 0)
        
    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 __del__(self):
        self.dialog.Release()
        del self.dialog
       
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
        #
        # Destroy the object (note: this is important!)
        #
        del DLGobj

History