Welcome, guest | Sign In | My Account | Store | Cart
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()

Diff to Previous Revision

--- revision 1 2009-06-27 21:13:04
+++ revision 2 2011-02-17 23:04:04
@@ -1,6 +1,7 @@
 
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.
@@ -9,9 +10,11 @@
                             threading complexity to that program.
 
         title         - Dialog window title
-        animation_res - animation resource .AVI for interesting progress display
+        animation_res - animation resource .AVI for interesting
+                        progress display
+
                         animation_res=160 (move)
-                        animation_res=161 (copy)
+                        animation_res=161 (copy) [DEFAULT]
 
         COMprogressDialog.dialog class methods -
 
@@ -33,9 +36,16 @@
                     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
         
#
@@ -43,7 +53,7 @@
         
#
         
# Get a list of topWindows
         
#
-        topWindows = []
+        topWindows = list()
         win32gui
.EnumWindows(self._windowEnumerationHandler, topWindows)
         
#
         
# Isolate Program Manager window from all the other topWindows,
@@ -65,6 +75,9 @@
         
#
         
# 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
@@ -84,14 +97,15 @@
         
#
         
self.dialog.SetAnimation(m_hLibShell32, animation_res)
         
#
-        # Insert title into top of dialog if present
+        # Insert title into top of dialog
         
#
-        if title:
-            self.dialog.SetTitle(title)
+        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):
         
#
@@ -99,21 +113,20 @@
         
#
         resultList
.append((hwnd, win32gui.GetWindowText(hwnd)))
 
-    def __del__(self):
-        self.dialog.Release()
-        del self.dialog
-      
+    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'
-              ]
+    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)
+        title = "COMprogressDialot Unit Test %i" % (i+1)
         
#
         
# Create instance of the COMprogressDialog class
         
#
@@ -123,8 +136,8 @@
         
#
         
DLGobj.dialog.SetLine(1, filenames[0], compactPath, 0)
         
for j in xrange(total):
-            completed=int(100.0 / total * j)
-            completed="%s (%i%%)" % (title, completed)
+            completed = int(100.0 / total * j)
+            completed = "%s (%i%%)" % (title, completed)
             
#
             
# Update title to include (xx%) completed
             
#
@@ -136,7 +149,7 @@
             
#
             
# Set second line to ##### of ##### bytes uploaded
             
#
-            line2="%i of %i bytes uploaded" % (j, total)
+            line2 = "%i of %i bytes uploaded" % (j, total)
             
DLGobj.dialog.SetLine(2, line2, 0, 0)
             
#
             
# See if user pushed cancel button
@@ -148,17 +161,17 @@
             
# Simulate uploading two equal sized files
             
#
             
if j == 50:
-                compactPath=1
+                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
         
#
-        # Only necessary because of nested loops
+        # Have the COM dialog close and release it's resources
         
#
-        if DLGobj.dialog.HasUserCancelled():
-            break
-        #
-        # Destroy the object (note: this is important!)
-        #
-        del DLGobj
+        DLGobj.close()

History