|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- # 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()
|