Spaces:
Sleeping
Sleeping
File size: 6,272 Bytes
d12bc25 |
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 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# 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()
|