190 lines
6.1 KiB
Python
190 lines
6.1 KiB
Python
|
# Demo of using just windows, without documents and views.
|
||
|
|
||
|
# Also demo of a GUI thread, pretty much direct from the MFC C++ sample MTMDI.
|
||
|
|
||
|
import timer
|
||
|
import win32api
|
||
|
import win32con
|
||
|
import win32ui
|
||
|
from pywin.mfc import docview, thread, window
|
||
|
from pywin.mfc.thread import WinThread
|
||
|
|
||
|
WM_USER_PREPARE_TO_CLOSE = win32con.WM_USER + 32
|
||
|
|
||
|
# font is a dictionary in which the following elements matter:
|
||
|
# (the best matching font to supplied parameters is returned)
|
||
|
# name string name of the font as known by Windows
|
||
|
# size point size of font in logical units
|
||
|
# weight weight of font (win32con.FW_NORMAL, win32con.FW_BOLD)
|
||
|
# italic boolean; true if set to anything but None
|
||
|
# underline boolean; true if set to anything but None
|
||
|
|
||
|
|
||
|
# This window is a child window of a frame. It is not the frame window itself.
|
||
|
class FontWindow(window.Wnd):
|
||
|
def __init__(self, text="Python Rules!"):
|
||
|
window.Wnd.__init__(self)
|
||
|
self.text = text
|
||
|
self.index = 0
|
||
|
self.incr = 1
|
||
|
self.width = self.height = 0
|
||
|
self.ChangeAttributes()
|
||
|
# set up message handlers
|
||
|
|
||
|
def Create(self, title, style, rect, parent):
|
||
|
classStyle = win32con.CS_HREDRAW | win32con.CS_VREDRAW
|
||
|
className = win32ui.RegisterWndClass(
|
||
|
classStyle, 0, win32con.COLOR_WINDOW + 1, 0
|
||
|
)
|
||
|
self._obj_ = win32ui.CreateWnd()
|
||
|
self._obj_.AttachObject(self)
|
||
|
self._obj_.CreateWindow(
|
||
|
className, title, style, rect, parent, win32ui.AFX_IDW_PANE_FIRST
|
||
|
)
|
||
|
self.HookMessage(self.OnSize, win32con.WM_SIZE)
|
||
|
self.HookMessage(self.OnPrepareToClose, WM_USER_PREPARE_TO_CLOSE)
|
||
|
self.HookMessage(self.OnDestroy, win32con.WM_DESTROY)
|
||
|
self.timerid = timer.set_timer(100, self.OnTimer)
|
||
|
self.InvalidateRect()
|
||
|
|
||
|
def OnDestroy(self, msg):
|
||
|
timer.kill_timer(self.timerid)
|
||
|
|
||
|
def OnTimer(self, id, timeVal):
|
||
|
self.index = self.index + self.incr
|
||
|
if self.index > len(self.text):
|
||
|
self.incr = -1
|
||
|
self.index = len(self.text)
|
||
|
elif self.index < 0:
|
||
|
self.incr = 1
|
||
|
self.index = 0
|
||
|
self.InvalidateRect()
|
||
|
|
||
|
def OnPaint(self):
|
||
|
# print "Paint message from thread", win32api.GetCurrentThreadId()
|
||
|
dc, paintStruct = self.BeginPaint()
|
||
|
self.OnPrepareDC(dc, None)
|
||
|
|
||
|
if self.width == 0 and self.height == 0:
|
||
|
left, top, right, bottom = self.GetClientRect()
|
||
|
self.width = right - left
|
||
|
self.height = bottom - top
|
||
|
x, y = self.width // 2, self.height // 2
|
||
|
dc.TextOut(x, y, self.text[: self.index])
|
||
|
self.EndPaint(paintStruct)
|
||
|
|
||
|
def ChangeAttributes(self):
|
||
|
font_spec = {"name": "Arial", "height": 42}
|
||
|
self.font = win32ui.CreateFont(font_spec)
|
||
|
|
||
|
def OnPrepareToClose(self, params):
|
||
|
self.DestroyWindow()
|
||
|
|
||
|
def OnSize(self, params):
|
||
|
lParam = params[3]
|
||
|
self.width = win32api.LOWORD(lParam)
|
||
|
self.height = win32api.HIWORD(lParam)
|
||
|
|
||
|
def OnPrepareDC(self, dc, printinfo):
|
||
|
# Set up the DC for forthcoming OnDraw call
|
||
|
dc.SetTextColor(win32api.RGB(0, 0, 255))
|
||
|
dc.SetBkColor(win32api.GetSysColor(win32con.COLOR_WINDOW))
|
||
|
dc.SelectObject(self.font)
|
||
|
dc.SetTextAlign(win32con.TA_CENTER | win32con.TA_BASELINE)
|
||
|
|
||
|
|
||
|
class FontFrame(window.MDIChildWnd):
|
||
|
def __init__(self):
|
||
|
pass # Dont call base class doc/view version...
|
||
|
|
||
|
def Create(self, title, rect=None, parent=None):
|
||
|
style = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_OVERLAPPEDWINDOW
|
||
|
self._obj_ = win32ui.CreateMDIChild()
|
||
|
self._obj_.AttachObject(self)
|
||
|
|
||
|
self._obj_.CreateWindow(None, title, style, rect, parent)
|
||
|
rect = self.GetClientRect()
|
||
|
rect = (0, 0, rect[2] - rect[0], rect[3] - rect[1])
|
||
|
self.child = FontWindow("Not threaded")
|
||
|
self.child.Create(
|
||
|
"FontDemo", win32con.WS_CHILD | win32con.WS_VISIBLE, rect, self
|
||
|
)
|
||
|
|
||
|
|
||
|
class TestThread(WinThread):
|
||
|
def __init__(self, parentWindow):
|
||
|
self.parentWindow = parentWindow
|
||
|
self.child = None
|
||
|
WinThread.__init__(self)
|
||
|
|
||
|
def InitInstance(self):
|
||
|
rect = self.parentWindow.GetClientRect()
|
||
|
rect = (0, 0, rect[2] - rect[0], rect[3] - rect[1])
|
||
|
|
||
|
self.child = FontWindow()
|
||
|
self.child.Create(
|
||
|
"FontDemo", win32con.WS_CHILD | win32con.WS_VISIBLE, rect, self.parentWindow
|
||
|
)
|
||
|
self.SetMainFrame(self.child)
|
||
|
return WinThread.InitInstance(self)
|
||
|
|
||
|
def ExitInstance(self):
|
||
|
return 0
|
||
|
|
||
|
|
||
|
class ThreadedFontFrame(window.MDIChildWnd):
|
||
|
def __init__(self):
|
||
|
pass # Dont call base class doc/view version...
|
||
|
self.thread = None
|
||
|
|
||
|
def Create(self, title, rect=None, parent=None):
|
||
|
style = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_OVERLAPPEDWINDOW
|
||
|
self._obj_ = win32ui.CreateMDIChild()
|
||
|
self._obj_.CreateWindow(None, title, style, rect, parent)
|
||
|
self._obj_.HookMessage(self.OnDestroy, win32con.WM_DESTROY)
|
||
|
self._obj_.HookMessage(self.OnSize, win32con.WM_SIZE)
|
||
|
|
||
|
self.thread = TestThread(self)
|
||
|
self.thread.CreateThread()
|
||
|
|
||
|
def OnSize(self, msg):
|
||
|
pass
|
||
|
|
||
|
def OnDestroy(self, msg):
|
||
|
win32ui.OutputDebugString("OnDestroy\n")
|
||
|
if self.thread and self.thread.child:
|
||
|
child = self.thread.child
|
||
|
child.SendMessage(WM_USER_PREPARE_TO_CLOSE, 0, 0)
|
||
|
win32ui.OutputDebugString("Destroyed\n")
|
||
|
|
||
|
|
||
|
def Demo():
|
||
|
f = FontFrame()
|
||
|
f.Create("Font Demo")
|
||
|
|
||
|
|
||
|
def ThreadedDemo():
|
||
|
rect = win32ui.GetMainFrame().GetMDIClient().GetClientRect()
|
||
|
rect = rect[0], int(rect[3] * 3 / 4), int(rect[2] / 4), rect[3]
|
||
|
incr = rect[2]
|
||
|
for i in range(4):
|
||
|
if i == 0:
|
||
|
f = FontFrame()
|
||
|
title = "Not threaded"
|
||
|
else:
|
||
|
f = ThreadedFontFrame()
|
||
|
title = "Threaded GUI Demo"
|
||
|
f.Create(title, rect)
|
||
|
rect = rect[0] + incr, rect[1], rect[2] + incr, rect[3]
|
||
|
# Givem a chance to start
|
||
|
win32api.Sleep(100)
|
||
|
win32ui.PumpWaitingMessages()
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
import demoutils
|
||
|
|
||
|
if demoutils.NeedGoodGUI():
|
||
|
ThreadedDemo()
|
||
|
# Demo()
|