You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Resources/WPy64-3720/python-3.7.2.amd64/Lib/site-packages/pythonwin/pywin/dialogs/status.py

228 lines
5.7 KiB

# No cancel button.
from pywin.mfc import dialog
from pywin.mfc.thread import WinThread
import threading
import win32ui
import win32con
import win32api
import time
def MakeProgressDlgTemplate(caption, staticText = ""):
style = (win32con.DS_MODALFRAME |
win32con.WS_POPUP |
win32con.WS_VISIBLE |
win32con.WS_CAPTION |
win32con.WS_SYSMENU |
win32con.DS_SETFONT)
cs = (win32con.WS_CHILD |
win32con.WS_VISIBLE)
w = 215
h = 36 # With button
h = 40
dlg = [[caption,
(0, 0, w, h),
style,
None,
(8, "MS Sans Serif")],
]
s = win32con.WS_TABSTOP | cs
dlg.append([130, staticText, 1000, (7, 7, w-7, h-32), cs | win32con.SS_LEFT])
# dlg.append([128,
# "Cancel",
# win32con.IDCANCEL,
# (w - 60, h - 18, 50, 14), s | win32con.BS_PUSHBUTTON])
return dlg
class CStatusProgressDialog(dialog.Dialog):
def __init__(self, title, msg = "", maxticks = 100, tickincr = 1):
self.initMsg = msg
templ = MakeProgressDlgTemplate(title, msg)
dialog.Dialog.__init__(self, templ)
self.maxticks = maxticks
self.tickincr = tickincr
self.pbar = None
def OnInitDialog(self):
rc = dialog.Dialog.OnInitDialog(self)
self.static = self.GetDlgItem(1000)
self.pbar = win32ui.CreateProgressCtrl()
self.pbar.CreateWindow (win32con.WS_CHILD |
win32con.WS_VISIBLE,
(10, 30, 310, 44),
self, 1001)
self.pbar.SetRange(0, self.maxticks)
self.pbar.SetStep(self.tickincr)
self.progress = 0
self.pincr = 5
return rc
def Close(self):
self.EndDialog(0)
def SetMaxTicks(self, maxticks):
if self.pbar is not None:
self.pbar.SetRange(0, maxticks)
def Tick(self):
if self.pbar is not None:
self.pbar.StepIt()
def SetTitle(self, text):
self.SetWindowText(text)
def SetText(self, text):
self.SetDlgItemText(1000, text)
def Set(self, pos, max = None):
if self.pbar is not None:
self.pbar.SetPos(pos)
if max is not None:
self.pbar.SetRange(0, max)
# a progress dialog created in a new thread - especially suitable for
# console apps with no message loop.
MYWM_SETTITLE = win32con.WM_USER+10
MYWM_SETMSG = win32con.WM_USER+11
MYWM_TICK = win32con.WM_USER+12
MYWM_SETMAXTICKS = win32con.WM_USER+13
MYWM_SET = win32con.WM_USER+14
class CThreadedStatusProcessDialog(CStatusProgressDialog):
def __init__(self, title, msg = "", maxticks = 100, tickincr = 1):
self.title = title
self.msg = msg
self.threadid = win32api.GetCurrentThreadId()
CStatusProgressDialog.__init__(self, title, msg, maxticks, tickincr)
def OnInitDialog(self):
rc = CStatusProgressDialog.OnInitDialog(self)
self.HookMessage(self.OnTitle, MYWM_SETTITLE)
self.HookMessage(self.OnMsg, MYWM_SETMSG)
self.HookMessage(self.OnTick, MYWM_TICK)
self.HookMessage(self.OnMaxTicks, MYWM_SETMAXTICKS)
self.HookMessage(self.OnSet, MYWM_SET)
return rc
def _Send(self, msg):
try:
self.PostMessage(msg)
except win32ui.error:
# the user closed the window - but this does not cancel the
# process - so just ignore it.
pass
def OnTitle(self, msg):
CStatusProgressDialog.SetTitle(self, self.title)
def OnMsg(self, msg):
CStatusProgressDialog.SetText(self, self.msg)
def OnTick(self, msg):
CStatusProgressDialog.Tick(self)
def OnMaxTicks(self, msg):
CStatusProgressDialog.SetMaxTicks(self, self.maxticks)
def OnSet(self, msg):
CStatusProgressDialog.Set(self, self.pos, self.max)
def Close(self):
assert self.threadid, "No thread!"
win32api.PostThreadMessage(self.threadid, win32con.WM_QUIT, 0, 0)
def SetMaxTicks(self, maxticks):
self.maxticks = maxticks
self._Send(MYWM_SETMAXTICKS)
def SetTitle(self, title):
self.title = title
self._Send(MYWM_SETTITLE)
def SetText(self, text):
self.msg = text
self._Send(MYWM_SETMSG)
def Tick(self):
self._Send(MYWM_TICK)
def Set(self, pos, max = None):
self.pos = pos
self.max = max
self._Send(MYWM_SET)
class ProgressThread(WinThread):
def __init__(self, title, msg = "", maxticks = 100, tickincr = 1):
self.title = title
self.msg = msg
self.maxticks = maxticks
self.tickincr = tickincr
self.dialog = None
WinThread.__init__(self)
self.createdEvent = threading.Event()
def InitInstance(self):
self.dialog = CThreadedStatusProcessDialog( self.title, self.msg, self.maxticks, self.tickincr)
self.dialog.CreateWindow()
try:
self.dialog.SetForegroundWindow()
except win32ui.error:
pass
self.createdEvent.set()
return WinThread.InitInstance(self)
def ExitInstance(self):
return 0
def StatusProgressDialog(title, msg = "", maxticks = 100, parent = None):
d = CStatusProgressDialog (title, msg, maxticks)
d.CreateWindow (parent)
return d
def ThreadedStatusProgressDialog(title, msg = "", maxticks = 100):
t = ProgressThread(title, msg, maxticks)
t.CreateThread()
# Need to run a basic "PumpWaitingMessages" loop just incase we are
# running inside Pythonwin.
# Basic timeout incase things go terribly wrong. Ideally we should use
# win32event.MsgWaitForMultipleObjects(), but we use a threading module
# event - so use a dumb strategy
end_time = time.time() + 10
while time.time() < end_time:
if t.createdEvent.isSet():
break
win32ui.PumpWaitingMessages()
time.sleep(0.1)
return t.dialog
def demo():
d = StatusProgressDialog("A Demo", "Doing something...")
import win32api
for i in range(100):
if i == 50:
d.SetText("Getting there...")
if i==90:
d.SetText("Nearly done...")
win32api.Sleep(20)
d.Tick()
d.Close()
def thread_demo():
d = ThreadedStatusProgressDialog("A threaded demo", "Doing something")
import win32api
for i in range(100):
if i == 50:
d.SetText("Getting there...")
if i==90:
d.SetText("Nearly done...")
win32api.Sleep(20)
d.Tick()
d.Close()
if __name__=='__main__':
thread_demo()
#demo()