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.
I don't have progdlg.tlb anywhere, nor an VBProgressDialog object registered. Where do you get those?