Uploaded Test files

This commit is contained in:
Batuhan Berk Başoğlu 2020-11-12 11:05:57 -05:00
parent f584ad9d97
commit 2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions

View file

@ -0,0 +1,221 @@
# basictimerapp - a really simple timer application.
# This should be run using the command line:
# pythonwin /app demos\basictimerapp.py
import win32ui
import win32api
import win32con
import sys
from pywin.framework import app, cmdline, dlgappcore, cmdline
import timer
import time
import string
class TimerAppDialog(dlgappcore.AppDialog):
softspace=1
def __init__(self, appName = ""):
dlgappcore.AppDialog.__init__(self, win32ui.IDD_GENERAL_STATUS)
self.timerAppName = appName
self.argOff = 0
if len(self.timerAppName)==0:
if len(sys.argv)>1 and sys.argv[1][0]!='/':
self.timerAppName = sys.argv[1]
self.argOff = 1
def PreDoModal(self):
# sys.stderr = sys.stdout
pass
def ProcessArgs(self, args):
for arg in args:
if arg=="/now":
self.OnOK()
def OnInitDialog(self):
win32ui.SetProfileFileName('pytimer.ini')
self.title = win32ui.GetProfileVal(self.timerAppName, "Title", "Remote System Timer")
self.buildTimer = win32ui.GetProfileVal(self.timerAppName, "Timer", "EachMinuteIntervaler()")
self.doWork = win32ui.GetProfileVal(self.timerAppName, "Work", "DoDemoWork()")
# replace "\n" with real \n.
self.doWork = self.doWork.replace('\\n','\n')
dlgappcore.AppDialog.OnInitDialog(self)
self.SetWindowText(self.title)
self.prompt1 = self.GetDlgItem(win32ui.IDC_PROMPT1)
self.prompt2 = self.GetDlgItem(win32ui.IDC_PROMPT2)
self.prompt3 = self.GetDlgItem(win32ui.IDC_PROMPT3)
self.butOK = self.GetDlgItem(win32con.IDOK)
self.butCancel = self.GetDlgItem(win32con.IDCANCEL)
self.prompt1.SetWindowText("Python Timer App")
self.prompt2.SetWindowText("")
self.prompt3.SetWindowText("")
self.butOK.SetWindowText("Do it now")
self.butCancel.SetWindowText("Close")
self.timerManager = TimerManager(self)
self.ProcessArgs(sys.argv[self.argOff:])
self.timerManager.go()
return 1
def OnDestroy(self,msg):
dlgappcore.AppDialog.OnDestroy(self, msg)
self.timerManager.stop()
def OnOK(self):
# stop the timer, then restart after setting special boolean
self.timerManager.stop()
self.timerManager.bConnectNow = 1
self.timerManager.go()
return
# def OnCancel(self): default behaviour - cancel == close.
# return
class TimerManager:
def __init__(self, dlg):
self.dlg = dlg
self.timerId = None
self.intervaler = eval(self.dlg.buildTimer)
self.bConnectNow = 0
self.bHaveSetPrompt1 = 0
def CaptureOutput(self):
self.oldOut = sys.stdout
self.oldErr = sys.stderr
sys.stdout = sys.stderr = self
self.bHaveSetPrompt1 = 0
def ReleaseOutput(self):
sys.stdout = self.oldOut
sys.stderr = self.oldErr
def write(self, str):
s = str.strip()
if len(s):
if self.bHaveSetPrompt1:
dest = self.dlg.prompt3
else:
dest = self.dlg.prompt1
self.bHaveSetPrompt1 = 1
dest.SetWindowText(s)
def go(self):
self.OnTimer(None,None)
def stop(self):
if self.timerId: timer.kill_timer (self.timerId)
self.timerId = None
def OnTimer(self, id, timeVal):
if id: timer.kill_timer (id)
if self.intervaler.IsTime() or self.bConnectNow :
# do the work.
try:
self.dlg.SetWindowText(self.dlg.title + " - Working...")
self.dlg.butOK.EnableWindow(0)
self.dlg.butCancel.EnableWindow(0)
self.CaptureOutput()
try:
exec(self.dlg.doWork)
print("The last operation completed successfully.")
except:
t, v, tb = sys.exc_info()
str = "Failed: %s: %s" % (t, repr(v))
print(str)
self.oldErr.write(str)
tb = None # Prevent cycle
finally:
self.ReleaseOutput()
self.dlg.butOK.EnableWindow()
self.dlg.butCancel.EnableWindow()
self.dlg.SetWindowText(self.dlg.title)
else:
now = time.time()
nextTime = self.intervaler.GetNextTime()
if nextTime:
timeDiffSeconds = nextTime - now
timeDiffMinutes = int(timeDiffSeconds / 60)
timeDiffSeconds = timeDiffSeconds % 60
timeDiffHours = int(timeDiffMinutes / 60)
timeDiffMinutes = timeDiffMinutes % 60
self.dlg.prompt1.SetWindowText("Next connection due in %02d:%02d:%02d" % (timeDiffHours,timeDiffMinutes,timeDiffSeconds))
self.timerId = timer.set_timer (self.intervaler.GetWakeupInterval(), self.OnTimer)
self.bConnectNow = 0
class TimerIntervaler:
def __init__(self):
self.nextTime = None
self.wakeUpInterval = 2000
def GetWakeupInterval(self):
return self.wakeUpInterval
def GetNextTime(self):
return self.nextTime
def IsTime(self):
now = time.time()
if self.nextTime is None:
self.nextTime = self.SetFirstTime(now)
ret = 0
if now >= self.nextTime:
ret = 1
self.nextTime = self.SetNextTime(self.nextTime, now)
# do the work.
return ret
class EachAnyIntervaler(TimerIntervaler):
def __init__(self, timeAt, timePos, timeAdd, wakeUpInterval = None):
TimerIntervaler.__init__(self)
self.timeAt = timeAt
self.timePos = timePos
self.timeAdd = timeAdd
if wakeUpInterval:
self.wakeUpInterval = wakeUpInterval
def SetFirstTime(self, now):
timeTup = time.localtime(now)
lst = []
for item in timeTup:
lst.append(item)
bAdd = timeTup[self.timePos] > self.timeAt
lst[self.timePos] = self.timeAt
for pos in range(self.timePos+1, 6):
lst[pos]=0
ret = time.mktime(tuple(lst))
if (bAdd):
ret = ret + self.timeAdd
return ret;
def SetNextTime(self, lastTime, now):
return lastTime + self.timeAdd
class EachMinuteIntervaler(EachAnyIntervaler):
def __init__(self, at=0):
EachAnyIntervaler.__init__(self, at, 5, 60, 2000)
class EachHourIntervaler(EachAnyIntervaler):
def __init__(self, at=0):
EachAnyIntervaler.__init__(self, at, 4, 3600, 10000)
class EachDayIntervaler(EachAnyIntervaler):
def __init__(self,at=0):
EachAnyIntervaler.__init__(self, at, 3, 86400, 10000)
class TimerDialogApp(dlgappcore.DialogApp):
def CreateDialog(self):
return TimerAppDialog()
def DoDemoWork():
print("Doing the work...")
print("About to connect")
win32api.MessageBeep(win32con.MB_ICONASTERISK)
win32api.Sleep(2000)
print("Doing something else...")
win32api.MessageBeep(win32con.MB_ICONEXCLAMATION)
win32api.Sleep(2000)
print("More work.")
win32api.MessageBeep(win32con.MB_ICONHAND)
win32api.Sleep(2000)
print("The last bit.")
win32api.MessageBeep(win32con.MB_OK)
win32api.Sleep(2000)
app = TimerDialogApp()
def t():
t = TimerAppDialog("Test Dialog")
t.DoModal()
return t
if __name__=='__main__':
import demoutils
demoutils.NeedApp()

View file

@ -0,0 +1,194 @@
# A demo of an Application object that has some custom print functionality.
# If you desire, you can also run this from inside Pythonwin, in which
# case it will do the demo inside the Pythonwin environment.
# This sample was contributed by Roger Burnham.
from pywin.mfc import docview, dialog, afxres
from pywin.framework import app
import win32con
import win32ui
import win32api
PRINTDLGORD = 1538
IDC_PRINT_MAG_EDIT = 1010
class PrintDemoTemplate(docview.DocTemplate):
def _SetupSharedMenu_(self):
pass
class PrintDemoView(docview.ScrollView):
def OnInitialUpdate(self):
ret = self._obj_.OnInitialUpdate()
self.colors = {'Black' : (0x00<<0) + (0x00<<8) + (0x00<<16),
'Red' : (0xff<<0) + (0x00<<8) + (0x00<<16),
'Green' : (0x00<<0) + (0xff<<8) + (0x00<<16),
'Blue' : (0x00<<0) + (0x00<<8) + (0xff<<16),
'Cyan' : (0x00<<0) + (0xff<<8) + (0xff<<16),
'Magenta': (0xff<<0) + (0x00<<8) + (0xff<<16),
'Yellow' : (0xff<<0) + (0xff<<8) + (0x00<<16),
}
self.pens = {}
for name, color in self.colors.items():
self.pens[name] = win32ui.CreatePen(win32con.PS_SOLID,
5, color)
self.pen = None
self.size = (128,128)
self.SetScaleToFitSize(self.size)
self.HookCommand(self.OnFilePrint, afxres.ID_FILE_PRINT)
self.HookCommand(self.OnFilePrintPreview,
win32ui.ID_FILE_PRINT_PREVIEW)
return ret
def OnDraw(self, dc):
oldPen = None
x,y = self.size
delta = 2
colors = list(self.colors.keys())
colors.sort()
colors = colors*2
for color in colors:
if oldPen is None:
oldPen = dc.SelectObject(self.pens[color])
else:
dc.SelectObject(self.pens[color])
dc.MoveTo(( delta, delta))
dc.LineTo((x-delta, delta))
dc.LineTo((x-delta, y-delta))
dc.LineTo(( delta, y-delta))
dc.LineTo(( delta, delta))
delta = delta + 4
if x-delta <= 0 or y-delta <= 0:
break
dc.SelectObject(oldPen)
def OnPrepareDC (self, dc, pInfo):
if dc.IsPrinting():
mag = self.prtDlg['mag']
dc.SetMapMode(win32con.MM_ANISOTROPIC);
dc.SetWindowOrg((0, 0))
dc.SetWindowExt((1, 1))
dc.SetViewportOrg((0, 0))
dc.SetViewportExt((mag, mag))
def OnPreparePrinting(self, pInfo):
flags = (win32ui.PD_USEDEVMODECOPIES|
win32ui.PD_PAGENUMS|
win32ui.PD_NOPAGENUMS|
win32ui.PD_NOSELECTION)
self.prtDlg = ImagePrintDialog(pInfo, PRINTDLGORD, flags)
pInfo.SetPrintDialog(self.prtDlg)
pInfo.SetMinPage(1)
pInfo.SetMaxPage(1)
pInfo.SetFromPage(1)
pInfo.SetToPage(1)
ret = self.DoPreparePrinting(pInfo)
return ret
def OnBeginPrinting(self, dc, pInfo):
return self._obj_.OnBeginPrinting(dc, pInfo)
def OnEndPrinting(self, dc, pInfo):
del self.prtDlg
return self._obj_.OnEndPrinting(dc, pInfo)
def OnFilePrintPreview(self, *arg):
self._obj_.OnFilePrintPreview()
def OnFilePrint(self, *arg):
self._obj_.OnFilePrint()
def OnPrint(self, dc, pInfo):
doc = self.GetDocument()
metrics = dc.GetTextMetrics()
cxChar = metrics['tmAveCharWidth']
cyChar = metrics['tmHeight']
left, top, right, bottom = pInfo.GetDraw()
dc.TextOut(0, 2*cyChar, doc.GetTitle())
top = top + (7*cyChar)/2
dc.MoveTo(left, top)
dc.LineTo(right, top)
top = top + cyChar
# this seems to have not effect...
# get what I want with the dc.SetWindowOrg calls
pInfo.SetDraw((left, top, right, bottom))
dc.SetWindowOrg((0, -top))
self.OnDraw(dc)
dc.SetTextAlign(win32con.TA_LEFT|win32con.TA_BOTTOM)
rect = self.GetWindowRect()
rect = self.ScreenToClient(rect)
height = (rect[3]-rect[1])
dc.SetWindowOrg((0, -(top+height+cyChar)))
dc.MoveTo(left, 0)
dc.LineTo(right, 0)
x = 0
y = (3*cyChar)/2
dc.TextOut(x, y, doc.GetTitle())
y = y + cyChar
class PrintDemoApp(app.CApp):
def __init__(self):
app.CApp.__init__(self)
def InitInstance(self):
template = PrintDemoTemplate(None, None,
None, PrintDemoView)
self.AddDocTemplate(template)
self._obj_.InitMDIInstance()
self.LoadMainFrame()
doc = template.OpenDocumentFile(None)
doc.SetTitle('Custom Print Document')
class ImagePrintDialog(dialog.PrintDialog):
sectionPos = 'Image Print Demo'
def __init__(self, pInfo, dlgID, flags=win32ui.PD_USEDEVMODECOPIES):
dialog.PrintDialog.__init__(self, pInfo, dlgID, flags=flags)
mag = win32ui.GetProfileVal(self.sectionPos,
'Document Magnification',
0)
if mag <= 0:
mag = 2
win32ui.WriteProfileVal(self.sectionPos,
'Document Magnification',
mag)
self['mag'] = mag
def OnInitDialog(self):
self.magCtl = self.GetDlgItem(IDC_PRINT_MAG_EDIT)
self.magCtl.SetWindowText(repr(self['mag']))
return dialog.PrintDialog.OnInitDialog(self)
def OnOK(self):
dialog.PrintDialog.OnOK(self)
strMag = self.magCtl.GetWindowText()
try:
self['mag'] = int(strMag)
except:
pass
win32ui.WriteProfileVal(self.sectionPos,
'Document Magnification',
self['mag'])
if __name__=='__main__':
# Running under Pythonwin
def test():
template = PrintDemoTemplate(None, None,
None, PrintDemoView)
template.OpenDocumentFile(None)
test()
else:
app = PrintDemoApp()

View file

@ -0,0 +1,52 @@
# Utilities for the demos
import sys, win32api, win32con, win32ui
NotScriptMsg = """\
This demo program is not designed to be run as a Script, but is
probably used by some other test program. Please try another demo.
"""
NeedGUIMsg = """\
This demo program can only be run from inside of Pythonwin
You must start Pythonwin, and select 'Run' from the toolbar or File menu
"""
NeedAppMsg = """\
This demo program is a 'Pythonwin Application'.
It is more demo code than an example of Pythonwin's capabilities.
To run it, you must execute the command:
pythonwin.exe /app "%s"
Would you like to execute it now?
"""
def NotAScript():
import win32ui
win32ui.MessageBox(NotScriptMsg, "Demos")
def NeedGoodGUI():
from pywin.framework.app import HaveGoodGUI
rc = HaveGoodGUI()
if not rc:
win32ui.MessageBox(NeedGUIMsg, "Demos")
return rc
def NeedApp():
import win32ui
rc = win32ui.MessageBox(NeedAppMsg % sys.argv[0], "Demos", win32con.MB_YESNO)
if rc==win32con.IDYES:
try:
parent = win32ui.GetMainFrame().GetSafeHwnd()
win32api.ShellExecute(parent, None, 'pythonwin.exe', '/app "%s"' % sys.argv[0], None, 1)
except win32api.error as details:
win32ui.MessageBox("Error executing command - %s" % (details), "Demos")
if __name__=='__main__':
import demoutils
demoutils.NotAScript()

View file

@ -0,0 +1,46 @@
# dlgappdemo - a demo of a dialog application.
# This is a demonstration of both a custom "application" module,
# and a Python program in a dialog box.
#
# NOTE: You CAN NOT import this module from either PythonWin or Python.
# This module must be specified on the commandline to PythonWin only.
# eg, PythonWin /app dlgappdemo.py
from pywin.framework import dlgappcore, app
import win32ui
import sys
class TestDialogApp(dlgappcore.DialogApp):
def CreateDialog(self):
return TestAppDialog()
class TestAppDialog(dlgappcore.AppDialog):
def __init__(self):
self.edit = None
dlgappcore.AppDialog.__init__(self, win32ui.IDD_LARGE_EDIT)
def OnInitDialog(self):
self.SetWindowText('Test dialog application')
self.edit = self.GetDlgItem(win32ui.IDC_EDIT1)
print("Hello from Python")
print("args are:", end=' ')
for arg in sys.argv:
print(arg)
return 1
def PreDoModal(self):
sys.stdout = sys.stderr = self
def write(self, str):
if self.edit:
self.edit.SetSel(-2)
# translate \n to \n\r
self.edit.ReplaceSel(str.replace('\n','\r\n'))
else:
win32ui.OutputDebug("dlgapp - no edit control! >>\n%s\n<<\n" % str )
app.AppBuilder = TestDialogApp
if __name__=='__main__':
import demoutils
demoutils.NeedApp()

View file

@ -0,0 +1,62 @@
# dojobapp - do a job, show the result in a dialog, and exit.
#
# Very simple - faily minimal dialog based app.
#
# This should be run using the command line:
# pythonwin /app demos\dojobapp.py
import win32ui
import win32api
import win32con
import sys
from pywin.framework import app, dlgappcore
import string
class DoJobAppDialog(dlgappcore.AppDialog):
softspace=1
def __init__(self, appName = ""):
self.appName = appName
dlgappcore.AppDialog.__init__(self, win32ui.IDD_GENERAL_STATUS)
def PreDoModal(self):
pass
def ProcessArgs(self, args):
pass
def OnInitDialog(self):
self.SetWindowText(self.appName)
butCancel = self.GetDlgItem(win32con.IDCANCEL)
butCancel.ShowWindow(win32con.SW_HIDE)
p1 = self.GetDlgItem(win32ui.IDC_PROMPT1)
p2 = self.GetDlgItem(win32ui.IDC_PROMPT2)
# Do something here!
p1.SetWindowText("Hello there")
p2.SetWindowText("from the demo")
def OnDestroy(self,msg):
pass
# def OnOK(self):
# pass
# def OnCancel(self): default behaviour - cancel == close.
# return
class DoJobDialogApp(dlgappcore.DialogApp):
def CreateDialog(self):
return DoJobAppDialog("Do Something")
class CopyToDialogApp(DoJobDialogApp):
def __init__(self):
DoJobDialogApp.__init__(self)
app.AppBuilder = DoJobDialogApp
def t():
t = DoJobAppDialog("Copy To")
t.DoModal()
return t
if __name__=='__main__':
import demoutils
demoutils.NeedApp()

View file

@ -0,0 +1,45 @@
##
## helloapp.py
##
##
## A nice, small 'hello world' Pythonwin application.
## NOT an MDI application - just a single, normal, top-level window.
##
## MUST be run with the command line "pythonwin.exe /app helloapp.py"
## (or if you are really keen, rename "pythonwin.exe" to something else, then
## using MSVC or similar, edit the string section in the .EXE to name this file)
##
## Originally by Willy Heineman <wheineman@uconect.net>
import win32con
import win32ui
from pywin.mfc import window, dialog, afxres
from pywin.mfc.thread import WinApp
# The main frame.
# Does almost nothing at all - doesnt even create a child window!
class HelloWindow(window.Wnd):
def __init__(self):
# The window.Wnd ctor creates a Window object, and places it in
# self._obj_. Note the window object exists, but the window itself
# does not!
window.Wnd.__init__(self, win32ui.CreateWnd())
# Now we ask the window object to create the window itself.
self._obj_.CreateWindowEx(win32con.WS_EX_CLIENTEDGE, \
win32ui.RegisterWndClass(0, 0, win32con.COLOR_WINDOW + 1), \
'Hello World!', win32con.WS_OVERLAPPEDWINDOW, \
(100, 100, 400, 300), None, 0, None)
# The application object itself.
class HelloApp(WinApp):
def InitInstance(self):
self.frame = HelloWindow()
self.frame.ShowWindow(win32con.SW_SHOWNORMAL)
# We need to tell MFC what our main frame is.
self.SetMainFrame(self.frame)
# Now create the application object itself!
app = HelloApp()

View file

@ -0,0 +1,108 @@
# cmdserver.py
# Demo code that is not Pythonwin related, but too good to throw away...
import win32api
import sys
from pywin.framework import winout
import _thread, sys
import traceback
class ThreadWriter:
"Assign an instance to sys.stdout for per-thread printing objects - Courtesy Guido!"
def __init__(self):
"Constructor -- initialize the table of writers"
self.writers = {}
self.origStdOut = None
def register(self, writer):
"Register the writer for the current thread"
self.writers[_thread.get_ident()] = writer
if self.origStdOut is None:
self.origStdOut = sys.stdout
sys.stdout = self
def unregister(self):
"Remove the writer for the current thread, if any"
try:
del self.writers[_thread.get_ident()]
except KeyError:
pass
if len(self.writers)==0:
sys.stdout = self.origStdOut
self.origStdOut = None
def getwriter(self):
"Return the current thread's writer, default sys.stdout"
try:
return self.writers[_thread.get_ident()]
except KeyError:
return self.origStdOut
def write(self, str):
"Write to the current thread's writer, default sys.stdout"
self.getwriter().write(str)
def Test():
num=1
while num<1000:
print('Hello there no ' + str(num))
win32api.Sleep(50)
num = num + 1
class flags:
SERVER_BEST = 0
SERVER_IMMEDIATE = 1
SERVER_THREAD = 2
SERVER_PROCESS = 3
def StartServer( cmd, title=None, bCloseOnEnd=0, serverFlags = flags.SERVER_BEST ):
out = winout.WindowOutput( title, None, winout.flags.WQ_IDLE )
if not title:
title=cmd
out.Create(title)
# ServerThread((out, cmd, title, bCloseOnEnd))
# out = sys.stdout
_thread.start_new_thread( ServerThread, (out, cmd, title, bCloseOnEnd) )
def ServerThread(myout, cmd, title, bCloseOnEnd):
try:
writer.register(myout)
print('Executing "%s"\n' % cmd)
bOK = 1
try:
import __main__
exec (cmd+'\n', __main__.__dict__)
except:
bOK = 0
if bOK:
print("Command terminated without errors.")
else:
t, v, tb = sys.exc_info()
print(t, ': ', v)
traceback.print_tb(tb)
tb = None # prevent a cycle
print("Command terminated with an unhandled exception")
writer.unregister()
if bOK and bCloseOnEnd:
myout.frame.DestroyWindow()
# Unhandled exception of any kind in a thread kills the gui!
except:
t, v, tb = sys.exc_info()
print(t, ': ', v)
traceback.print_tb(tb)
tb = None
print("Thread failed")
# assist for reloading (when debugging) - use only 1 tracer object,
# else a large chain of tracer objects will exist.
#try:
# writer
#except NameError:
# writer=ThreadWriter()
if __name__=='__main__':
import demoutils
demoutils.NotAScript()

View file

@ -0,0 +1,98 @@
#
# Window creation example
#
# This example creates a minimal "control" that just fills in its
# window with red. To make your own control, subclass Control and
# write your own OnPaint() method. See PyCWnd.HookMessage for what
# the parameters to OnPaint are.
#
from pywin.mfc import dialog, window
import win32ui
import win32con
import win32api
class Control(window.Wnd):
"""Generic control class"""
def __init__ (self):
window.Wnd.__init__(self, win32ui.CreateWnd ())
def OnPaint (self):
dc, paintStruct = self.BeginPaint()
self.DoPaint(dc)
self.EndPaint(paintStruct)
def DoPaint (self, dc): # Override this!
pass
class RedBox (Control):
def DoPaint (self, dc):
dc.FillSolidRect (self.GetClientRect(), win32api.RGB(255,0,0))
class RedBoxWithPie (RedBox):
def DoPaint (self, dc):
RedBox.DoPaint(self, dc)
r = self.GetClientRect()
dc.Pie(r[0], r[1], r[2], r[3], 0,0,r[2], r[3]//2)
def MakeDlgTemplate():
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 = 64
h = 64
dlg = [["Red box",
(0, 0, w, h),
style,
None,
(8, "MS Sans Serif")],
]
s = win32con.WS_TABSTOP | cs
dlg.append([128,
"Cancel",
win32con.IDCANCEL,
(7, h - 18, 50, 14), s | win32con.BS_PUSHBUTTON])
return dlg
class TestDialog(dialog.Dialog):
def OnInitDialog(self):
rc = dialog.Dialog.OnInitDialog(self)
self.redbox = RedBox ()
self.redbox.CreateWindow (None, "RedBox",
win32con.WS_CHILD |
win32con.WS_VISIBLE,
(5, 5, 90, 68),
self, 1003)
return rc
class TestPieDialog(dialog.Dialog):
def OnInitDialog(self):
rc = dialog.Dialog.OnInitDialog(self)
self.control = RedBoxWithPie()
self.control.CreateWindow (None, "RedBox with Pie",
win32con.WS_CHILD |
win32con.WS_VISIBLE,
(5, 5, 90, 68),
self, 1003)
def demo(modal=0):
d = TestPieDialog (MakeDlgTemplate())
if modal:
d.DoModal()
else:
d.CreateWindow()
if __name__=='__main__':
demo(1)

View file

@ -0,0 +1,54 @@
# Utilities for the demos
import sys, win32api, win32con, win32ui
NotScriptMsg = """\
This demo program is not designed to be run as a Script, but is
probably used by some other test program. Please try another demo.
"""
NeedGUIMsg = """\
This demo program can only be run from inside of Pythonwin
You must start Pythonwin, and select 'Run' from the toolbar or File menu
"""
NeedAppMsg = """\
This demo program is a 'Pythonwin Application'.
It is more demo code than an example of Pythonwin's capabilities.
To run it, you must execute the command:
pythonwin.exe /app "%s"
Would you like to execute it now?
"""
def NotAScript():
import win32ui
win32ui.MessageBox(NotScriptMsg, "Demos")
def NeedGoodGUI():
from pywin.framework.app import HaveGoodGUI
rc = HaveGoodGUI()
if not rc:
win32ui.MessageBox(NeedGUIMsg, "Demos")
return rc
def NeedApp():
import win32ui
rc = win32ui.MessageBox(NeedAppMsg % sys.argv[0], "Demos", win32con.MB_YESNO)
if rc==win32con.IDYES:
try:
parent = win32ui.GetMainFrame().GetSafeHwnd()
win32api.ShellExecute(parent, None, 'pythonwin.exe', '/app "%s"' % sys.argv[0], None, 1)
except win32api.error as details:
win32ui.MessageBox("Error executing command - %s" % (details), "Demos")
from pywin.framework.app import HaveGoodGUI
if __name__=='__main__':
import demoutils
demoutils.NotAScript()

View file

@ -0,0 +1,69 @@
# A demo which creates a view and a frame which displays a PPM format bitmap
#
# This hasnnt been run in a while, as I dont have many of that format around!
import win32ui
import win32con
import win32api
import string
class DIBView:
def __init__(self, doc, dib):
self.dib = dib
self.view = win32ui.CreateView(doc)
self.width = self.height = 0
# set up message handlers
# self.view.OnPrepareDC = self.OnPrepareDC
self.view.HookMessage (self.OnSize, win32con.WM_SIZE)
def OnSize (self, params):
lParam = params[3]
self.width = win32api.LOWORD(lParam)
self.height = win32api.HIWORD(lParam)
def OnDraw (self, ob, dc):
# set sizes used for "non strecth" mode.
self.view.SetScrollSizes(win32con.MM_TEXT, self.dib.GetSize())
dibSize = self.dib.GetSize()
dibRect = (0,0,dibSize[0], dibSize[1])
# stretch BMP.
#self.dib.Paint(dc, (0,0,self.width, self.height),dibRect)
# non stretch.
self.dib.Paint(dc)
class DIBDemo:
def __init__(self, filename, * bPBM):
# init data members
f = open(filename, 'rb')
dib=win32ui.CreateDIBitmap()
if len(bPBM)>0:
magic=f.readline()
if magic != "P6\n":
print("The file is not a PBM format file")
raise ValueError("Failed - The file is not a PBM format file")
# check magic?
rowcollist=f.readline().split()
cols=int(rowcollist[0])
rows=int(rowcollist[1])
f.readline() # whats this one?
dib.LoadPBMData(f,(cols,rows))
else:
dib.LoadWindowsFormatFile(f)
f.close()
# create doc/view
self.doc = win32ui.CreateDoc()
self.dibView = DIBView( self.doc, dib )
self.frame = win32ui.CreateMDIFrame()
self.frame.LoadFrame() # this will force OnCreateClient
self.doc.SetTitle ('DIB Demo')
self.frame.ShowWindow()
# display the sucka
self.frame.ActivateFrame()
def OnCreateClient( self, createparams, context ):
self.dibView.view.CreateWindow(self.frame)
return 1
if __name__=='__main__':
import demoutils
demoutils.NotAScript()

View file

@ -0,0 +1,137 @@
# A Demo of Pythonwin's Dialog and Property Page support.
###################
#
# First demo - use the built-in to Pythonwin "Tab Stop" dialog, but
# customise it heavily.
#
# ID's for the tabstop dialog - out test.
#
from win32ui import IDD_SET_TABSTOPS
from win32ui import IDC_EDIT_TABS
from win32ui import IDC_PROMPT_TABS
from win32con import IDOK
from win32con import IDCANCEL
import win32ui
import win32con
from pywin.mfc import dialog
class TestDialog(dialog.Dialog):
def __init__(self, modal=1):
dialog.Dialog.__init__(self, IDD_SET_TABSTOPS)
self.counter=0
if modal:
self.DoModal()
else:
self.CreateWindow()
def OnInitDialog(self):
# Set the caption of the dialog itself.
self.SetWindowText("Used to be Tab Stops!")
# Get a child control, remember it, and change its text.
self.edit=self.GetDlgItem(IDC_EDIT_TABS) # the text box.
self.edit.SetWindowText("Test")
# Hook a Windows message for the dialog.
self.edit.HookMessage(self.KillFocus, win32con.WM_KILLFOCUS)
# Get the prompt control, and change its next.
prompt=self.GetDlgItem(IDC_PROMPT_TABS) # the prompt box.
prompt.SetWindowText("Prompt")
# And the same for the button..
cancel=self.GetDlgItem(IDCANCEL) # the cancel button
cancel.SetWindowText("&Kill me")
# And just for demonstration purposes, we hook the notify message for the dialog.
# This allows us to be notified when the Edit Control text changes.
self.HookCommand(self.OnNotify, IDC_EDIT_TABS)
def OnNotify(self, controlid, code):
if code==win32con.EN_CHANGE:
print("Edit text changed!")
return 1 # I handled this, so no need to call defaults!
# kill focus for the edit box.
# Simply increment the value in the text box.
def KillFocus(self,msg):
self.counter=self.counter+1
if self.edit != None:
self.edit.SetWindowText(str(self.counter))
# Called when the dialog box is terminating...
def OnDestroy(self,msg):
del self.edit
del self.counter
# A very simply Property Sheet.
# We only make a new class for demonstration purposes.
class TestSheet(dialog.PropertySheet):
def __init__(self, title):
dialog.PropertySheet.__init__(self, title)
self.HookMessage(self.OnActivate, win32con.WM_ACTIVATE)
def OnActivate(self, msg):
pass
# A very simply Property Page, which will be "owned" by the above
# Property Sheet.
# We create a new class, just so we can hook a control notification.
class TestPage(dialog.PropertyPage):
def OnInitDialog(self):
# We use the HookNotify function to allow Python to respond to
# Windows WM_NOTIFY messages.
# In this case, we are interested in BN_CLICKED messages.
self.HookNotify(self.OnNotify, win32con.BN_CLICKED)
def OnNotify(self, std, extra):
print("OnNotify", std, extra)
# Some code that actually uses these objects.
def demo(modal = 0):
TestDialog(modal)
# property sheet/page demo
ps=win32ui.CreatePropertySheet('Property Sheet/Page Demo')
# Create a completely standard PropertyPage.
page1=win32ui.CreatePropertyPage(win32ui.IDD_PROPDEMO1)
# Create our custom property page.
page2=TestPage(win32ui.IDD_PROPDEMO2)
ps.AddPage(page1)
ps.AddPage(page2)
if modal:
ps.DoModal()
else:
style = win32con.WS_SYSMENU|win32con.WS_POPUP|win32con.WS_CAPTION|win32con.DS_MODALFRAME|win32con.WS_VISIBLE
styleex = win32con.WS_EX_DLGMODALFRAME | win32con.WS_EX_PALETTEWINDOW
ps.CreateWindow(win32ui.GetMainFrame(), style, styleex)
def test(modal=1):
# dlg=dialog.Dialog(1010)
# dlg.CreateWindow()
# dlg.EndDialog(0)
# del dlg
# return
# property sheet/page demo
ps=TestSheet('Property Sheet/Page Demo')
page1=win32ui.CreatePropertyPage(win32ui.IDD_PROPDEMO1)
page2=win32ui.CreatePropertyPage(win32ui.IDD_PROPDEMO2)
ps.AddPage(page1)
ps.AddPage(page2)
del page1
del page2
if modal:
ps.DoModal()
else:
ps.CreateWindow(win32ui.GetMainFrame())
return ps
def d():
dlg = win32ui.CreateDialog(win32ui.IDD_DEBUGGER)
dlg.datalist.append((win32ui.IDC_DBG_RADIOSTACK, "radio"))
print("data list is ", dlg.datalist)
dlg.data['radio']=1
dlg.DoModal()
print(dlg.data['radio'])
if __name__=='__main__':
demo(1)

View file

@ -0,0 +1,73 @@
# dyndlg.py
# contributed by Curt Hagenlocher <chi@earthlink.net>
# Dialog Template params:
# Parameter 0 - Window caption
# Parameter 1 - Bounds (rect tuple)
# Parameter 2 - Window style
# Parameter 3 - Extended style
# Parameter 4 - Font tuple
# Parameter 5 - Menu name
# Parameter 6 - Window class
# Dialog item params:
# Parameter 0 - Window class
# Parameter 1 - Text
# Parameter 2 - ID
# Parameter 3 - Bounds
# Parameter 4 - Style
# Parameter 5 - Extended style
# Parameter 6 - Extra data
import win32ui
import win32con
from pywin.mfc import dialog, window
def MakeDlgTemplate():
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
dlg = [ ["Select Warehouse", (0, 0, 177, 93), style, None, (8, "MS Sans Serif")], ]
dlg.append([130, "Current Warehouse:", -1, (7, 7, 69, 9), cs | win32con.SS_LEFT])
dlg.append([130, "ASTORIA", 128, (16, 17, 99, 7), cs | win32con.SS_LEFT])
dlg.append([130, "New &Warehouse:", -1, (7, 29, 69, 9), cs | win32con.SS_LEFT])
s = win32con.WS_TABSTOP | cs
# dlg.append([131, None, 130, (5, 40, 110, 48),
# s | win32con.LBS_NOTIFY | win32con.LBS_SORT | win32con.LBS_NOINTEGRALHEIGHT | win32con.WS_VSCROLL | win32con.WS_BORDER])
dlg.append(["{8E27C92B-1264-101C-8A2F-040224009C02}", None, 131, (5, 40, 110, 48),win32con.WS_TABSTOP])
dlg.append([128, "OK", win32con.IDOK, (124, 5, 50, 14), s | win32con.BS_DEFPUSHBUTTON])
s = win32con.BS_PUSHBUTTON | s
dlg.append([128, "Cancel", win32con.IDCANCEL, (124, 22, 50, 14), s])
dlg.append([128, "&Help", 100, (124, 74, 50, 14), s])
return dlg
def test1():
win32ui.CreateDialogIndirect( MakeDlgTemplate() ).DoModal()
def test2():
dialog.Dialog( MakeDlgTemplate() ).DoModal()
def test3():
dlg = win32ui.LoadDialogResource(win32ui.IDD_SET_TABSTOPS)
dlg[0][0] = 'New Dialog Title'
dlg[0][1] = (80, 20, 161, 60)
dlg[1][1] = '&Confusion:'
cs = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_TABSTOP | win32con.BS_PUSHBUTTON
dlg.append([128, "&Help", 100, (111, 41, 40, 14), cs])
dialog.Dialog( dlg ).DoModal()
def test4():
page1=dialog.PropertyPage(win32ui.LoadDialogResource(win32ui.IDD_PROPDEMO1))
page2=dialog.PropertyPage(win32ui.LoadDialogResource(win32ui.IDD_PROPDEMO2))
ps=dialog.PropertySheet('Property Sheet/Page Demo', None, [page1, page2])
ps.DoModal()
def testall():
test1()
test2()
test3()
test4()
if __name__=='__main__':
testall()

View file

@ -0,0 +1,79 @@
# Demo of Generic document windows, DC, and Font usage
# by Dave Brennan (brennan@hal.com)
# usage examples:
# >>> from fontdemo import *
# >>> d = FontDemo('Hello, Python')
# >>> f1 = { 'name':'Arial', 'height':36, 'weight':win32con.FW_BOLD}
# >>> d.SetFont(f1)
# >>> f2 = {'name':'Courier New', 'height':24, 'italic':1}
# >>> d.SetFont (f2)
import win32ui
import win32con
import win32api
from pywin.mfc import docview
# 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
class FontView(docview.ScrollView):
def __init__(self, doc, text = 'Python Rules!', font_spec = {'name':'Arial', 'height':42}):
docview.ScrollView.__init__(self, doc)
self.font = win32ui.CreateFont (font_spec)
self.text = text
self.width = self.height = 0
# set up message handlers
self.HookMessage (self.OnSize, win32con.WM_SIZE)
def OnAttachedObjectDeath(self):
docview.ScrollView.OnAttachedObjectDeath(self)
del self.font
def SetFont (self, new_font):
# Change font on the fly
self.font = win32ui.CreateFont (new_font)
# redraw the entire client window
selfInvalidateRect (None)
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
self.SetScrollSizes(win32con.MM_TEXT, (100,100))
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)
def OnDraw (self, dc):
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)
def FontDemo():
# create doc/view
template = docview.DocTemplate(win32ui.IDR_PYTHONTYPE, None, None, FontView)
doc=template.OpenDocumentFile(None)
doc.SetTitle ('Font Demo')
# print "template is ", template, "obj is", template._obj_
template.close()
# print "closed"
# del template
if __name__=='__main__':
import demoutils
if demoutils.NeedGoodGUI():
FontDemo()

View file

@ -0,0 +1,68 @@
# GUI Demo - just a worker script to invoke all the other demo/test scripts.
import win32ui
import __main__
import sys
import regutil
import win32api
demos = [ \
# ('Font', 'import fontdemo;fontdemo.FontDemo()'),
('Open GL Demo', 'import openGLDemo;openGLDemo.test()'),
('Threaded GUI', 'import threadedgui;threadedgui.ThreadedDemo()'),
('Tree View Demo', 'import hiertest;hiertest.demoboth()'),
('3-Way Splitter Window', 'import splittst;splittst.demo()'),
('Custom Toolbars and Tooltips', 'import toolbar;toolbar.test()'),
('Progress Bar', 'import progressbar;progressbar.demo()'),
('Slider Control', 'import sliderdemo;sliderdemo.demo()'),
('Dynamic window creation', 'import createwin;createwin.demo()'),
('Various Dialog demos', 'import dlgtest;dlgtest.demo()'),
('OCX Control Demo', 'from ocx import ocxtest;ocxtest.demo()'),
('OCX Serial Port Demo', 'from ocx import ocxserialtest; ocxserialtest.test()'),
('IE4 Control Demo', 'from ocx import webbrowser; webbrowser.Demo("http://www.python.org")'),
]
def demo():
try:
# seeif I can locate the demo files.
import fontdemo
except ImportError:
# else put the demos direectory on the path (if not already)
try:
instPath = regutil.GetRegistryDefaultValue(regutil.BuildDefaultPythonKey() + "\\InstallPath")
except win32api.error:
print("The InstallPath can not be located, and the Demos directory is not on the path")
instPath="."
demosDir = win32ui.FullPath(instPath + "\\Demos")
for path in sys.path:
if win32ui.FullPath(path)==demosDir:
break
else:
sys.path.append(demosDir)
import fontdemo
import sys
if "/go" in sys.argv:
for name, cmd in demos:
try:
exec(cmd)
except:
print("Demo of %s failed - %s:%s" % (cmd,sys.exc_info()[0], sys.exc_info()[1]))
return
# Otherwise allow the user to select the demo to run
import pywin.dialogs.list
while 1:
rc = pywin.dialogs.list.SelectFromLists( "Select a Demo", demos, ['Demo Title'] )
if rc is None:
break
title, cmd = demos[rc]
try:
exec(cmd)
except:
print("Demo of %s failed - %s:%s" % (title,sys.exc_info()[0], sys.exc_info()[1]))
if __name__==__main__.__name__:
import demoutils
if demoutils.NeedGoodGUI():
demo()

View file

@ -0,0 +1,104 @@
import win32ui
import os
import commctrl
from pywin.tools import hierlist
from pywin.mfc import docview, window
# directory listbox
# This has obvious limitations - doesnt track subdirs, etc. Demonstrates
# simple use of Python code for querying the tree as needed.
# Only use strings, and lists of strings (from curdir())
class DirHierList(hierlist.HierList):
def __init__(self, root, listBoxID = win32ui.IDC_LIST1):
hierlist.HierList.__init__(self, root, win32ui.IDB_HIERFOLDERS, listBoxID)
def GetText(self, item):
return os.path.basename(item)
def GetSubList(self, item):
if os.path.isdir(item):
ret = [os.path.join(item, fname) for fname in os.listdir(item)]
else:
ret = None
return ret
# if the item is a dir, it is expandable.
def IsExpandable(self, item):
return os.path.isdir(item)
def GetSelectedBitmapColumn(self, item):
return self.GetBitmapColumn(item)+6 # Use different color for selection
class TestDocument(docview.Document):
def __init__(self, template):
docview.Document.__init__(self, template)
self.hierlist = hierlist.HierListWithItems(HLIFileDir("\\"), win32ui.IDB_HIERFOLDERS, win32ui.AFX_IDW_PANE_FIRST)
class HierListView(docview.TreeView):
def OnInitialUpdate(self):
rc = self._obj_.OnInitialUpdate()
self.hierList = self.GetDocument().hierlist
self.hierList.HierInit(self.GetParent())
self.hierList.SetStyle(commctrl.TVS_HASLINES | commctrl.TVS_LINESATROOT | commctrl.TVS_HASBUTTONS)
return rc
class HierListFrame(window.MDIChildWnd):
pass
def GetTestRoot():
tree1 = ('Tree 1',[('Item 1','Item 1 data'),'Item 2',3])
tree2 = ('Tree 2',[('Item 2.1','Item 2 data'),'Item 2.2',2.3])
return ('Root',[tree1,tree2,'Item 3'])
def demoboth():
template = docview.DocTemplate(win32ui.IDR_PYTHONTYPE, TestDocument, HierListFrame, HierListView)
template.OpenDocumentFile(None).SetTitle("Hierlist demo")
demomodeless()
def demomodeless():
testList2=DirHierList("\\")
dlg=hierlist.HierDialog('hier list test',testList2)
dlg.CreateWindow()
def demodlg ():
testList2=DirHierList("\\")
dlg=hierlist.HierDialog('hier list test',testList2)
dlg.DoModal()
def demo():
template = docview.DocTemplate(win32ui.IDR_PYTHONTYPE, TestDocument, HierListFrame, HierListView)
template.OpenDocumentFile(None).SetTitle("Hierlist demo")
#
# Demo/Test for HierList items.
#
# Easy to make a better directory program.
#
class HLIFileDir(hierlist.HierListItem):
def __init__( self, filename ):
self.filename = filename
hierlist.HierListItem.__init__(self)
def GetText(self):
try:
return "%-20s %d bytes" % (os.path.basename(self.filename), os.stat(self.filename)[6])
except os.error as details:
return "%-20s - %s" % (self.filename, details[1])
def IsExpandable(self):
return os.path.isdir(self.filename)
def GetSubList(self):
ret = []
for newname in os.listdir(self.filename):
if newname not in ['.', '..']:
ret.append( HLIFileDir( os.path.join(self.filename,newname ) ) )
return ret
def demohli():
template = docview.DocTemplate(win32ui.IDR_PYTHONTYPE, TestDocument, hierlist.HierListFrame, hierlist.HierListView)
template.OpenDocumentFile(None).SetTitle("Hierlist demo")
if __name__=='__main__':
import demoutils
if demoutils.HaveGoodGUI():
demoboth()
else:
demodlg()

View file

@ -0,0 +1,12 @@
# Run this as a python script, to gray "close" off the edit window system menu.
from pywin.framework import interact
import win32con
if __name__=='__main__':
import demoutils
if demoutils.NeedGoodGUI():
win=interact.edit.currentView.GetParent()
menu=win.GetSystemMenu()
id=menu.GetMenuItemID(6)
menu.EnableMenuItem(id,win32con.MF_BYCOMMAND|win32con.MF_GRAYED)
print("The interactive window's 'Close' menu item is now disabled.")

View file

@ -0,0 +1,49 @@
# This is a sample file, and shows the basic framework for using an "Object" based
# document, rather than a "filename" based document.
# This is referenced by the Pythonwin .html documentation.
# In the example below, the OpenObject() method is used instead of OpenDocumentFile,
# and all the core MFC document open functionality is retained.
import win32ui
from pywin.mfc import docview
class object_template (docview.DocTemplate):
def __init__(self):
docview.DocTemplate.__init__(self, None, None, None, object_view)
def OpenObject(self, object): # Use this instead of OpenDocumentFile.
# Look for existing open document
for doc in self.GetDocumentList():
print("document is ", doc)
if doc.object is object:
doc.GetFirstView().ActivateFrame()
return doc
# not found - new one.
doc = object_document(self, object)
frame = self.CreateNewFrame(doc)
doc.OnNewDocument()
doc.SetTitle(str(object))
self.InitialUpdateFrame(frame, doc)
return doc
class object_document (docview.Document):
def __init__(self, template, object):
docview.Document.__init__(self, template)
self.object = object
def OnOpenDocument (self, name):
raise RuntimeError("Should not be called if template strings set up correctly")
return 0
class object_view (docview.EditView):
def OnInitialUpdate (self):
self.ReplaceSel("Object is %s" % repr(self.GetDocument().object))
def demo ():
t = object_template()
d = t.OpenObject(win32ui)
return (t, d)
if __name__=='__main__':
import demoutils
if demoutils.NeedGoodGUI():
demo()

View file

@ -0,0 +1,54 @@
# Utilities for the demos
import sys, win32api, win32con, win32ui
NotScriptMsg = """\
This demo program is not designed to be run as a Script, but is
probably used by some other test program. Please try another demo.
"""
NeedGUIMsg = """\
This demo program can only be run from inside of Pythonwin
You must start Pythonwin, and select 'Run' from the toolbar or File menu
"""
NeedAppMsg = """\
This demo program is a 'Pythonwin Application'.
It is more demo code than an example of Pythonwin's capabilities.
To run it, you must execute the command:
pythonwin.exe /app "%s"
Would you like to execute it now?
"""
def NotAScript():
import win32ui
win32ui.MessageBox(NotScriptMsg, "Demos")
def NeedGoodGUI():
from pywin.framework.app import HaveGoodGUI
rc = HaveGoodGUI()
if not rc:
win32ui.MessageBox(NeedGUIMsg, "Demos")
return rc
def NeedApp():
import win32ui
rc = win32ui.MessageBox(NeedAppMsg % sys.argv[0], "Demos", win32con.MB_YESNO)
if rc==win32con.IDYES:
try:
parent = win32ui.GetMainFrame().GetSafeHwnd()
win32api.ShellExecute(parent, None, 'pythonwin.exe', '/app "%s"' % sys.argv[0], None, 1)
except win32api.error as details:
win32ui.MessageBox("Error executing command - %s" % (details), "Demos")
from pywin.framework.app import HaveGoodGUI
if __name__=='__main__':
import demoutils
demoutils.NotAScript()

View file

@ -0,0 +1,84 @@
# By Bradley Schatz
# simple flash/python application demonstrating bidirectional
# communicaion between flash and python. Click the sphere to see
# behavior. Uses Bounce.swf from FlashBounce.zip, available from
# http://pages.cpsc.ucalgary.ca/~saul/vb_examples/tutorial12/
# Update to the path of the .swf file (note it could be a true URL)
flash_url = "c:\\bounce.swf"
import win32ui, win32con, win32api, regutil
from pywin.mfc import window, activex
from win32com.client import gencache
import sys
FlashModule = gencache.EnsureModule("{D27CDB6B-AE6D-11CF-96B8-444553540000}", 0, 1, 0)
if FlashModule is None:
raise ImportError("Flash does not appear to be installed.")
class MyFlashComponent(activex.Control, FlashModule.ShockwaveFlash):
def __init__(self):
activex.Control.__init__(self)
FlashModule.ShockwaveFlash.__init__(self)
self.x = 50
self.y = 50
self.angle = 30
self.started = 0
def OnFSCommand(self, command, args):
print("FSCommend" , command, args)
self.x = self.x + 20
self.y = self.y + 20
self.angle = self.angle + 20
if self.x > 200 or self.y > 200:
self.x = 0
self.y = 0
if self.angle > 360:
self.angle = 0
self.SetVariable("xVal", self.x)
self.SetVariable("yVal", self.y)
self.SetVariable("angle", self.angle)
self.TPlay("_root.mikeBall")
def OnProgress(self, percentDone):
print("PercentDone", percentDone)
def OnReadyStateChange(self, newState):
# 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete
print("State", newState)
class BrowserFrame(window.MDIChildWnd):
def __init__(self, url = None):
if url is None:
self.url = regutil.GetRegisteredHelpFile("Main Python Documentation")
else:
self.url = url
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.ocx = MyFlashComponent()
self.ocx.CreateControl("Flash Player", win32con.WS_VISIBLE | win32con.WS_CHILD, rect, self, 1000)
self.ocx.LoadMovie(0,flash_url)
self.ocx.Play()
self.HookMessage (self.OnSize, win32con.WM_SIZE)
def OnSize (self, params):
rect = self.GetClientRect()
rect = (0,0,rect[2]-rect[0], rect[3]-rect[1])
self.ocx.SetWindowPos(0, rect, 0)
def Demo():
url = None
if len(sys.argv)>1:
url = win32api.GetFullPathName(sys.argv[1])
f = BrowserFrame(url)
f.Create("Flash Player")
if __name__=='__main__':
Demo()

View file

@ -0,0 +1,127 @@
# This demo uses some of the Microsoft Office components.
#
# It was taken from an MSDN article showing how to embed excel.
# It is not comlpete yet, but it _does_ show an Excel spreadsheet in a frame!
#
import win32ui, win32uiole, win32con, regutil
from pywin.mfc import window, activex, object, docview
from win32com.client import gencache
#WordModule = gencache.EnsureModule('{00020905-0000-0000-C000-000000000046}', 1033, 8, 0)
#if WordModule is None:
# raise ImportError, "Microsoft Word version 8 does not appear to be installed."
class OleClientItem(object.CmdTarget):
def __init__(self, doc):
object.CmdTarget.__init__(self, win32uiole.CreateOleClientItem(doc))
def OnGetItemPosition(self):
# For now return a hard-coded rect.
return (10, 10, 210, 210)
def OnActivate(self):
# Allow only one inplace activate item per frame
view = self.GetActiveView()
item = self.GetDocument().GetInPlaceActiveItem(view)
if item is not None and item._obj_ != self._obj_:
item.Close()
self._obj_.OnActivate()
def OnChange(self, oleNotification, dwParam):
self._obj_.OnChange(oleNotification, dwParam)
self.GetDocument().UpdateAllViews(None)
def OnChangeItemPosition(self, rect):
# During in-place activation CEmbed_ExcelCntrItem::OnChangeItemPosition
# is called by the server to change the position of the in-place
# window. Usually, this is a result of the data in the server
# document changing such that the extent has changed or as a result
# of in-place resizing.
#
# The default here is to call the base class, which will call
# COleClientItem::SetItemRects to move the item
# to the new position.
if not self._obj_.OnChangeItemPosition(self, rect):
return 0
# TODO: update any cache you may have of the item's rectangle/extent
return 1
class OleDocument(object.CmdTarget):
def __init__(self, template):
object.CmdTarget.__init__(self, win32uiole.CreateOleDocument(template))
self.EnableCompoundFile()
class ExcelView(docview.ScrollView):
def OnInitialUpdate(self):
self.HookMessage(self.OnSetFocus, win32con.WM_SETFOCUS)
self.HookMessage (self.OnSize, win32con.WM_SIZE)
self.SetScrollSizes(win32con.MM_TEXT, (100, 100))
rc = self._obj_.OnInitialUpdate()
self.EmbedExcel()
return rc
def EmbedExcel(self):
doc = self.GetDocument()
self.clientItem = OleClientItem(doc)
self.clientItem.CreateNewItem("Excel.Sheet")
self.clientItem.DoVerb(-1, self)
doc.UpdateAllViews(None)
def OnDraw(self, dc):
doc = self.GetDocument()
pos = doc.GetStartPosition()
clientItem, pos = doc.GetNextItem(pos)
clientItem.Draw(dc, (10, 10, 210, 210) )
# Special handling of OnSetFocus and OnSize are required for a container
# when an object is being edited in-place.
def OnSetFocus(self, msg):
item = self.GetDocument().GetInPlaceActiveItem(self)
if item is not None and item.GetItemState()==win32uiole.COleClientItem_activeUIState:
wnd = item.GetInPlaceWindow()
if wnd is not None:
wnd.SetFocus()
return 0 # Dont get the base version called.
return 1 # Call the base version.
def OnSize (self, params):
item = self.GetDocument().GetInPlaceActiveItem(self)
if item is not None:
item.SetItemRects()
return 1 # do call the base!
class OleTemplate(docview.DocTemplate):
def __init__(self, resourceId=None, MakeDocument=None, MakeFrame=None, MakeView=None):
if MakeDocument is None: MakeDocument = OleDocument
if MakeView is None: MakeView = ExcelView
docview.DocTemplate.__init__(self, resourceId, MakeDocument, MakeFrame, MakeView)
class WordFrame(window.MDIChildWnd):
def __init__(self, doc = None):
self._obj_ = win32ui.CreateMDIChild()
self._obj_.AttachObject(self)
# 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_.CreateWindow(None, title, style, rect, parent)
rect = self.GetClientRect()
rect = (0,0,rect[2]-rect[0], rect[3]-rect[1])
self.ocx = MyWordControl()
self.ocx.CreateControl("Microsoft Word", win32con.WS_VISIBLE | win32con.WS_CHILD, rect, self, 20000)
def Demo():
import sys, win32api
docName = None
if len(sys.argv)>1:
docName = win32api.GetFullPathName(sys.argv[1])
OleTemplate().OpenDocumentFile(None)
# f = WordFrame(docName)
# f.Create("Microsoft Office")
if __name__=='__main__':
Demo()

View file

@ -0,0 +1,101 @@
# ocxserialtest.py
#
# Sample that uses the mscomm OCX to talk to a serial
# device.
# Very simple - queries a modem for ATI responses
import win32ui, win32uiole
import win32con
from pywin.mfc import dialog, activex
from win32com.client import gencache
import pythoncom
SERIAL_SETTINGS = '19200,n,8,1'
SERIAL_PORT = 2
win32ui.DoWaitCursor(1)
serialModule = gencache.EnsureModule("{648A5603-2C6E-101B-82B6-000000000014}", 0, 1, 1)
win32ui.DoWaitCursor(0)
if serialModule is None:
raise ImportError("MS COMM Control does not appear to be installed on the PC")
def MakeDlgTemplate():
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
dlg = [ ["Very Basic Terminal",
(0, 0, 350, 180), style, None, (8, "MS Sans Serif")], ]
s = win32con.WS_TABSTOP | cs
dlg.append(["RICHEDIT", None, 132, (5, 5, 340, 170),s | win32con.ES_WANTRETURN | win32con.ES_MULTILINE | win32con.ES_AUTOVSCROLL | win32con.WS_VSCROLL])
return dlg
####################################
#
# Serial Control
#
class MySerialControl(activex.Control, serialModule.MSComm):
def __init__(self, parent):
activex.Control.__init__(self)
serialModule.MSComm.__init__(self)
self.parent = parent
def OnComm(self):
self.parent.OnComm()
class TestSerDialog(dialog.Dialog):
def __init__(self, *args):
dialog.Dialog.__init__(*(self,)+args)
self.olectl = None
def OnComm(self):
event = self.olectl.CommEvent
if event == serialModule.OnCommConstants.comEvReceive:
self.editwindow.ReplaceSel(self.olectl.Input)
def OnKey(self, key):
if self.olectl:
self.olectl.Output = chr(key)
def OnInitDialog(self):
rc = dialog.Dialog.OnInitDialog(self)
self.editwindow = self.GetDlgItem(132)
self.editwindow.HookAllKeyStrokes(self.OnKey)
self.olectl = MySerialControl(self)
try:
self.olectl.CreateControl("OCX",
win32con.WS_TABSTOP | win32con.WS_VISIBLE,
(7,43,500,300), self._obj_, 131)
except win32ui.error:
self.MessageBox("The Serial Control could not be created")
self.olectl = None
self.EndDialog(win32con.IDCANCEL)
if self.olectl:
self.olectl.Settings = SERIAL_SETTINGS
self.olectl.CommPort = SERIAL_PORT
self.olectl.RThreshold = 1
try:
self.olectl.PortOpen = 1
except pythoncom.com_error as details:
print("Could not open the specified serial port - %s" % (details.excepinfo[2]))
self.EndDialog(win32con.IDCANCEL)
return rc
def OnDestroy(self, msg):
if self.olectl:
try:
self.olectl.PortOpen = 0
except pythoncom.com_error as details:
print("Error closing port - %s" % (details.excepinfo[2]))
return dialog.Dialog.OnDestroy(self, msg)
def test():
d = TestSerDialog(MakeDlgTemplate() )
d.DoModal()
if __name__ == "__main__":
import demoutils
if demoutils.NeedGoodGUI():
test()

View file

@ -0,0 +1,186 @@
# OCX Tester for Pythonwin
#
# This file _is_ ready to run. All that is required is that the OCXs being tested
# are installed on your machine.
#
# The .py files behind the OCXs will be automatically generated and imported.
from pywin.mfc import dialog, window, activex
import win32ui, win32uiole
import win32con
import os, sys, win32api, glob
from win32com.client import gencache
def MakeDlgTemplate():
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
dlg = [ ["OCX Demos", (0, 0, 350, 350), style, None, (8, "MS Sans Serif")], ]
s = win32con.WS_TABSTOP | cs
# dlg.append([131, None, 130, (5, 40, 110, 48),
# s | win32con.LBS_NOTIFY | win32con.LBS_SORT | win32con.LBS_NOINTEGRALHEIGHT | win32con.WS_VSCROLL | win32con.WS_BORDER])
# dlg.append(["{8E27C92B-1264-101C-8A2F-040224009C02}", None, 131, (5, 40, 110, 48),win32con.WS_TABSTOP])
dlg.append([128, "About", win32con.IDOK, (124, 5, 50, 14), s | win32con.BS_DEFPUSHBUTTON])
s = win32con.BS_PUSHBUTTON | s
dlg.append([128, "Close", win32con.IDCANCEL, (124, 22, 50, 14), s])
return dlg
####################################
#
# Calendar test code
#
def GetTestCalendarClass():
global calendarParentModule
win32ui.DoWaitCursor(1)
calendarParentModule = gencache.EnsureModule("{8E27C92E-1264-101C-8A2F-040224009C02}", 0, 7, 0)
win32ui.DoWaitCursor(0)
if calendarParentModule is None:
return None
class TestCalDialog(dialog.Dialog):
def OnInitDialog(self):
class MyCal(activex.Control, calendarParentModule.Calendar):
def OnAfterUpdate(self):
print("OnAfterUpdate")
def OnClick(self):
print("OnClick")
def OnDblClick(self):
print("OnDblClick")
def OnKeyDown(self, KeyCode, Shift):
print("OnKeyDown", KeyCode, Shift)
def OnKeyPress(self, KeyAscii):
print("OnKeyPress", KeyAscii)
def OnKeyUp(self, KeyCode, Shift):
print("OnKeyUp", KeyCode, Shift)
def OnBeforeUpdate(self, Cancel):
print("OnBeforeUpdate", Cancel)
def OnNewMonth(self):
print("OnNewMonth")
def OnNewYear(self):
print("OnNewYear")
rc = dialog.Dialog.OnInitDialog(self)
self.olectl = MyCal()
try:
self.olectl.CreateControl("OCX", win32con.WS_TABSTOP | win32con.WS_VISIBLE, (7,43,500,300), self._obj_, 131)
except win32ui.error:
self.MessageBox("The Calendar Control could not be created")
self.olectl = None
self.EndDialog(win32con.IDCANCEL)
return rc
def OnOK(self):
self.olectl.AboutBox()
return TestCalDialog
####################################
#
# Video Control
#
def GetTestVideoModule():
global videoControlModule, videoControlFileName
win32ui.DoWaitCursor(1)
videoControlModule = gencache.EnsureModule("{05589FA0-C356-11CE-BF01-00AA0055595A}", 0, 2, 0)
win32ui.DoWaitCursor(0)
if videoControlModule is None:
return None
fnames = glob.glob(os.path.join(win32api.GetWindowsDirectory(), "*.avi"))
if not fnames:
print("No AVI files available in system directory")
return None
videoControlFileName = fnames[0]
return videoControlModule
def GetTestVideoDialogClass():
if GetTestVideoModule() is None:
return None
class TestVideoDialog(dialog.Dialog):
def OnInitDialog(self):
rc = dialog.Dialog.OnInitDialog(self)
try:
self.olectl = activex.MakeControlInstance(videoControlModule.ActiveMovie)
self.olectl.CreateControl("", win32con.WS_TABSTOP | win32con.WS_VISIBLE, (7,43,500,300), self._obj_, 131)
except win32ui.error:
self.MessageBox("The Video Control could not be created")
self.olectl = None
self.EndDialog(win32con.IDCANCEL)
return
self.olectl.FileName = videoControlFileName
# self.olectl.Run()
return rc
def OnOK(self):
self.olectl.AboutBox()
return TestVideoDialog
###############
#
# An OCX in an MDI Frame
#
class OCXFrame(window.MDIChildWnd):
def __init__(self):
pass # Dont call base class doc/view version...
def Create(self, controlClass, 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.ocx = controlClass()
self.ocx.CreateControl("", win32con.WS_VISIBLE | win32con.WS_CHILD, rect, self, 1000)
def MDITest():
calendarParentModule = gencache.EnsureModule("{8E27C92E-1264-101C-8A2F-040224009C02}", 0, 7, 0)
class MyCal(activex.Control, calendarParentModule.Calendar):
def OnAfterUpdate(self):
print("OnAfterUpdate")
def OnClick(self):
print("OnClick")
f = OCXFrame()
f.Create(MyCal, "Calendar Test")
def test1():
klass = GetTestCalendarClass()
if klass is None:
print("Can not test the MSAccess Calendar control - it does not appear to be installed")
return
d = klass(MakeDlgTemplate() )
d.DoModal()
def test2():
klass = GetTestVideoDialogClass()
if klass is None:
print("Can not test the Video OCX - it does not appear to be installed,")
print("or no AVI files can be found.")
return
d = klass(MakeDlgTemplate() )
d.DoModal()
d = None
def test3():
d = TestCOMMDialog(MakeDlgTemplate() )
d.DoModal()
d = None
def testall():
test1()
test2()
def demo():
testall()
if __name__=='__main__':
import demoutils
if demoutils.NeedGoodGUI():
testall()

View file

@ -0,0 +1,55 @@
# This demo uses the IE4 Web Browser control.
# It catches an "OnNavigate" event, and updates the frame title.
# (event stuff by Neil Hodgson)
import win32ui, win32con, win32api, regutil
from pywin.mfc import window, activex
from win32com.client import gencache
import sys
WebBrowserModule = gencache.EnsureModule("{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}", 0, 1, 1)
if WebBrowserModule is None:
raise ImportError("IE4 does not appear to be installed.")
class MyWebBrowser(activex.Control, WebBrowserModule.WebBrowser):
def OnBeforeNavigate2(self, pDisp, URL, Flags, TargetFrameName, PostData, Headers, Cancel):
self.GetParent().OnNavigate(URL)
#print "BeforeNavigate2", pDisp, URL, Flags, TargetFrameName, PostData, Headers, Cancel
class BrowserFrame(window.MDIChildWnd):
def __init__(self, url = None):
if url is None:
self.url = regutil.GetRegisteredHelpFile("Main Python Documentation")
if self.url is None:
self.url = "http://www.python.org"
else:
self.url = url
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.ocx = MyWebBrowser()
self.ocx.CreateControl("Web Browser", win32con.WS_VISIBLE | win32con.WS_CHILD, rect, self, 1000)
self.ocx.Navigate(self.url)
self.HookMessage (self.OnSize, win32con.WM_SIZE)
def OnSize (self, params):
rect = self.GetClientRect()
rect = (0,0,rect[2]-rect[0], rect[3]-rect[1])
self.ocx.SetWindowPos(0, rect, 0)
def OnNavigate(self, url):
title = "Web Browser - %s" % (url,)
self.SetWindowText(title)
def Demo(url=None):
if url is None and len(sys.argv)>1:
url = win32api.GetFullPathName(sys.argv[1])
f = BrowserFrame(url)
f.Create("Web Browser")
if __name__=='__main__':
Demo()

View file

@ -0,0 +1,358 @@
# Ported from the win32 and MFC OpenGL Samples.
from pywin.mfc import docview
import sys
try:
from OpenGL.GL import *
from OpenGL.GLU import *
except ImportError:
print("The OpenGL extensions do not appear to be installed.")
print("This Pythonwin demo can not run")
sys.exit(1)
import win32con
import win32ui
import win32api
import timer
PFD_TYPE_RGBA = 0
PFD_TYPE_COLORINDEX = 1
PFD_MAIN_PLANE = 0
PFD_OVERLAY_PLANE = 1
PFD_UNDERLAY_PLANE = (-1)
PFD_DOUBLEBUFFER = 0x00000001
PFD_STEREO = 0x00000002
PFD_DRAW_TO_WINDOW = 0x00000004
PFD_DRAW_TO_BITMAP = 0x00000008
PFD_SUPPORT_GDI = 0x00000010
PFD_SUPPORT_OPENGL = 0x00000020
PFD_GENERIC_FORMAT = 0x00000040
PFD_NEED_PALETTE = 0x00000080
PFD_NEED_SYSTEM_PALETTE = 0x00000100
PFD_SWAP_EXCHANGE = 0x00000200
PFD_SWAP_COPY = 0x00000400
PFD_SWAP_LAYER_BUFFERS = 0x00000800
PFD_GENERIC_ACCELERATED = 0x00001000
PFD_DEPTH_DONTCARE = 0x20000000
PFD_DOUBLEBUFFER_DONTCARE = 0x40000000
PFD_STEREO_DONTCARE = 0x80000000
#threeto8 = [0, 0o111>>1, 0o222>>1, 0o333>>1, 0o444>>1, 0o555>>1, 0o666>>1, 0o377]
threeto8 = [0, 73>>1, 146>>1, 219>>1, 292>>1, 365>>1, 438>>1, 255]
twoto8 = [0, 0x55, 0xaa, 0xff]
oneto8 = [0, 255]
def ComponentFromIndex(i, nbits, shift):
# val = (unsigned char) (i >> shift);
val = (i >> shift) & 0xF;
if nbits==1:
val = val & 0x1
return oneto8[val]
elif nbits==2:
val = val & 0x3
return twoto8[val]
elif nbits==3:
val = val & 0x7
return threeto8[val]
else:
return 0;
OpenGLViewParent=docview.ScrollView
class OpenGLView(OpenGLViewParent):
def PreCreateWindow(self, cc):
self.HookMessage (self.OnSize, win32con.WM_SIZE)
# An OpenGL window must be created with the following flags and must not
# include CS_PARENTDC for the class style. Refer to SetPixelFormat
# documentation in the "Comments" section for further information.
style = cc[5]
style = style | win32con.WS_CLIPSIBLINGS | win32con.WS_CLIPCHILDREN
cc = cc[0], cc[1], cc[2], cc[3], cc[4], style, cc[6], cc[7], cc[8]
cc = self._obj_.PreCreateWindow(cc)
return cc
def OnSize (self, params):
lParam = params[3]
cx = win32api.LOWORD(lParam)
cy = win32api.HIWORD(lParam)
glViewport(0, 0, cx, cy)
if self.oldrect[2] > cx or self.oldrect[3] > cy:
self.RedrawWindow()
self.OnSizeChange(cx, cy)
self.oldrect = self.oldrect[0], self.oldrect[1], cx, cy
def OnInitialUpdate(self):
self.SetScaleToFitSize((100,100)) # or SetScrollSizes() - A Pythonwin requirement
return self._obj_.OnInitialUpdate()
# return rc
def OnCreate(self, cs):
self.oldrect = self.GetClientRect()
self._InitContexts()
self.Init()
def OnDestroy(self, msg):
self.Term()
self._DestroyContexts()
return OpenGLViewParent.OnDestroy(self, msg)
def OnDraw(self, dc):
self.DrawScene()
def OnEraseBkgnd(self, dc):
return 1
# The OpenGL helpers
def _SetupPixelFormat(self):
dc = self.dc.GetSafeHdc()
pfd = CreatePIXELFORMATDESCRIPTOR()
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER
pfd.iPixelType = PFD_TYPE_RGBA
pfd.cColorBits = 24
pfd.cDepthBits = 32
pfd.iLayerType = PFD_MAIN_PLANE
pixelformat = ChoosePixelFormat(dc, pfd)
SetPixelFormat(dc, pixelformat, pfd)
self._CreateRGBPalette()
def _CreateRGBPalette(self):
dc = self.dc.GetSafeHdc()
n = GetPixelFormat(dc)
pfd = DescribePixelFormat(dc, n)
if pfd.dwFlags & PFD_NEED_PALETTE:
n = 1 << pfd.cColorBits
pal = []
for i in range(n):
this = ComponentFromIndex(i, pfd.cRedBits, pfd.cRedShift), \
ComponentFromIndex(i, pfd.cGreenBits, pfd.cGreenShift), \
ComponentFromIndex(i, pfd.cBlueBits, pfd.cBlueShift), \
0
pal.append(this)
hpal = win32ui.CreatePalette(pal)
self.dc.SelectPalette(hpal, 0)
self.dc.RealizePalette()
def _InitContexts(self):
self.dc = self.GetDC()
self._SetupPixelFormat()
hrc = wglCreateContext(self.dc.GetSafeHdc())
wglMakeCurrent(self.dc.GetSafeHdc(), hrc)
def _DestroyContexts(self):
hrc = wglGetCurrentContext()
wglMakeCurrent(0, 0)
if hrc: wglDeleteContext(hrc)
# The methods to support OpenGL
def DrawScene(self):
assert 0, "You must override this method"
def Init(self):
assert 0, "You must override this method"
def OnSizeChange(self, cx, cy):
pass
def Term(self):
pass
class TestView(OpenGLView):
def OnSizeChange(self, right, bottom):
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glClearDepth( 1.0 );
glEnable(GL_DEPTH_TEST)
glMatrixMode( GL_PROJECTION )
if bottom:
aspect = right / bottom
else:
aspect = 0 # When window created!
glLoadIdentity()
gluPerspective( 45.0, aspect, 3.0, 7.0 )
glMatrixMode( GL_MODELVIEW )
near_plane = 3.0;
far_plane = 7.0;
maxObjectSize = 3.0;
self.radius = near_plane + maxObjectSize/2.0;
def Init(self):
pass
def DrawScene(self):
glClearColor(0.0, 0.0, 0.0, 1.0)
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
glPushMatrix()
glTranslatef(0.0, 0.0, -self.radius);
self._DrawCone()
self._DrawPyramid()
glPopMatrix()
glFinish()
SwapBuffers( wglGetCurrentDC() )
def _DrawCone(self):
glColor3f(0.0, 1.0, 0.0)
glPushMatrix()
glTranslatef(-1.0, 0.0, 0.0);
quadObj = gluNewQuadric();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
gluCylinder(quadObj, 1.0, 0.0, 1.0, 20, 10);
# gluDeleteQuadric(quadObj);
glPopMatrix();
def _DrawPyramid(self):
glPushMatrix()
glTranslatef(1.0, 0.0, 0.0)
glBegin(GL_TRIANGLE_FAN)
glColor3f(1.0, 0.0, 0.0)
glVertex3f(0.0, 1.0, 0.0)
glColor3f(0.0, 1.0, 0.0)
glVertex3f(-1.0, 0.0, 0.0)
glColor3f(0.0, 0.0, 1.0)
glVertex3f(0.0, 0.0, 1.0)
glColor3f(0.0, 1.0, 0.0)
glVertex3f(1.0, 0.0, 0.0)
glEnd()
glPopMatrix()
class CubeView(OpenGLView):
def OnSizeChange(self, right, bottom):
glClearColor( 0.0, 0.0, 0.0, 1.0 );
glClearDepth( 1.0 );
glEnable(GL_DEPTH_TEST)
glMatrixMode( GL_PROJECTION )
if bottom:
aspect = right / bottom
else:
aspect = 0 # When window created!
glLoadIdentity()
gluPerspective( 45.0, aspect, 3.0, 7.0 )
glMatrixMode( GL_MODELVIEW )
near_plane = 3.0;
far_plane = 7.0;
maxObjectSize = 3.0;
self.radius = near_plane + maxObjectSize/2.0;
def Init(self):
self.busy = 0
self.wAngleY = 10.0
self.wAngleX = 1.0
self.wAngleZ = 5.0
self.timerid = timer.set_timer (150, self.OnTimer)
def OnTimer(self, id, timeVal):
self.DrawScene()
def Term(self):
timer.kill_timer(self.timerid)
def DrawScene(self):
if self.busy: return
self.busy = 1
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0.0, 0.0, -self.radius);
glRotatef(self.wAngleX, 1.0, 0.0, 0.0);
glRotatef(self.wAngleY, 0.0, 1.0, 0.0);
glRotatef(self.wAngleZ, 0.0, 0.0, 1.0);
self.wAngleX = self.wAngleX + 1.0
self.wAngleY = self.wAngleY + 10.0
self.wAngleZ = self.wAngleZ + 5.0;
glBegin(GL_QUAD_STRIP);
glColor3f(1.0, 0.0, 1.0);
glVertex3f(-0.5, 0.5, 0.5);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0.5);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.5, 0.5, 0.5);
glColor3f(1.0, 1.0, 0.0);
glVertex3f(0.5, -0.5, 0.5);
glColor3f(0.0, 1.0, 1.0);
glVertex3f(0.5, 0.5, -0.5);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.5, -0.5, -0.5);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(-0.5, 0.5, -0.5);
glColor3f(0.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, -0.5);
glColor3f(1.0, 0.0, 1.0);
glVertex3f(-0.5, 0.5, 0.5);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0.5);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0, 0.0, 1.0);
glVertex3f(-0.5, 0.5, 0.5);
glColor3f(1.0, 1.0, 1.0);
glVertex3f(0.5, 0.5, 0.5);
glColor3f(0.0, 1.0, 1.0);
glVertex3f(0.5, 0.5, -0.5);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(-0.5, 0.5, -0.5);
glEnd();
glBegin(GL_QUADS);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, 0.5);
glColor3f(1.0, 1.0, 0.0);
glVertex3f(0.5, -0.5, 0.5);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.5, -0.5, -0.5);
glColor3f(0.0, 0.0, 0.0);
glVertex3f(-0.5, -0.5, -0.5);
glEnd();
glPopMatrix();
glFinish();
SwapBuffers(wglGetCurrentDC());
self.busy = 0
def test():
template = docview.DocTemplate(None, None, None, CubeView )
# template = docview.DocTemplate(None, None, None, TestView )
template.OpenDocumentFile(None)
if __name__=='__main__':
test()

View file

@ -0,0 +1,88 @@
#
# Progress bar control example
#
# PyCProgressCtrl encapsulates the MFC CProgressCtrl class. To use it,
# you:
#
# - Create the control with win32ui.CreateProgressCtrl()
# - Create the control window with PyCProgressCtrl.CreateWindow()
# - Initialize the range if you want it to be other than (0, 100) using
# PyCProgressCtrl.SetRange()
# - Either:
# - Set the step size with PyCProgressCtrl.SetStep(), and
# - Increment using PyCProgressCtrl.StepIt()
# or:
# - Set the amount completed using PyCProgressCtrl.SetPos()
#
# Example and progress bar code courtesy of KDL Technologies, Ltd., Hong Kong SAR, China.
#
from pywin.mfc import dialog
import win32ui
import win32con
def MakeDlgTemplate():
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
dlg = [["Progress bar control example",
(0, 0, w, h),
style,
None,
(8, "MS Sans Serif")],
]
s = win32con.WS_TABSTOP | cs
dlg.append([128,
"Tick",
win32con.IDOK,
(10, h - 18, 50, 14), s | win32con.BS_DEFPUSHBUTTON])
dlg.append([128,
"Cancel",
win32con.IDCANCEL,
(w - 60, h - 18, 50, 14), s | win32con.BS_PUSHBUTTON])
return dlg
class TestDialog(dialog.Dialog):
def OnInitDialog(self):
rc = dialog.Dialog.OnInitDialog(self)
self.pbar = win32ui.CreateProgressCtrl()
self.pbar.CreateWindow (win32con.WS_CHILD |
win32con.WS_VISIBLE,
(10, 10, 310, 24),
self, 1001)
# self.pbar.SetStep (5)
self.progress = 0
self.pincr = 5
return rc
def OnOK(self):
# NB: StepIt wraps at the end if you increment past the upper limit!
# self.pbar.StepIt()
self.progress = self.progress + self.pincr
if self.progress > 100:
self.progress = 100
if self.progress <= 100:
self.pbar.SetPos(self.progress)
def demo(modal = 0):
d = TestDialog (MakeDlgTemplate())
if modal:
d.DoModal()
else:
d.CreateWindow ()
if __name__=='__main__':
demo(1)

View file

@ -0,0 +1,54 @@
# sliderdemo.py
# Demo of the slider control courtesy of Mike Fletcher.
import win32con, win32ui
from pywin.mfc import dialog
class MyDialog(dialog.Dialog):
'''
Example using simple controls
'''
_dialogstyle = (win32con.WS_MINIMIZEBOX | win32con.WS_DLGFRAME |
win32con.DS_MODALFRAME | win32con.WS_POPUP | win32con.WS_VISIBLE |
win32con.WS_CAPTION | win32con.WS_SYSMENU | win32con.DS_SETFONT )
_buttonstyle = (win32con.BS_PUSHBUTTON | win32con.WS_TABSTOP |
win32con.WS_CHILD | win32con.WS_VISIBLE)
### The static template, contains all "normal" dialog items
DIALOGTEMPLATE = [
# the dialog itself is the first element in the template
["Example slider", (0, 0, 50, 43), _dialogstyle, None, (8, "MS SansSerif")],
# rest of elements are the controls within the dialog
# standard "Close" button
[128, "Close", win32con.IDCANCEL, (0, 30, 50, 13), _buttonstyle], ]
### ID of the control to be created during dialog initialisation
IDC_SLIDER = 9500
def __init__(self ):
dialog.Dialog.__init__(self, self.DIALOGTEMPLATE)
def OnInitDialog(self):
rc = dialog.Dialog.OnInitDialog(self)
# now initialise your controls that you want to create
# programmatically, including those which are OLE controls
# those created directly by win32ui.Create*
# and your "custom controls" which are subclasses/whatever
win32ui.EnableControlContainer()
self.slider = win32ui.CreateSliderCtrl( )
self.slider.CreateWindow( win32con.WS_TABSTOP | win32con.WS_VISIBLE,
(0,0,100,30),
self._obj_,
self.IDC_SLIDER)
self.HookMessage(self.OnSliderMove, win32con.WM_HSCROLL)
return rc
def OnSliderMove(self, params):
print("Slider moved")
def OnCancel(self):
print("The slider control is at position", self.slider.GetPos())
self._obj_.OnCancel()
###
def demo():
dia = MyDialog()
dia.DoModal()
if __name__ == "__main__":
demo()

View file

@ -0,0 +1,72 @@
import win32ui
import win32con
import fontdemo
from pywin.mfc import window, docview
import commctrl
# derive from CMDIChild. This does much work for us.
class SplitterFrame(window.MDIChildWnd):
def __init__(self):
# call base CreateFrame
self.images = None
window.MDIChildWnd.__init__(self)
def OnCreateClient(self, cp, context):
splitter = win32ui.CreateSplitter()
doc = context.doc
frame_rect = self.GetWindowRect()
size = ((frame_rect[2] - frame_rect[0]),
(frame_rect[3] - frame_rect[1])//2)
sub_size = (size[0]//2, size[1])
splitter.CreateStatic (self, 2, 1)
self.v1 = win32ui.CreateEditView(doc)
self.v2 = fontdemo.FontView(doc)
# CListControl view
self.v3 = win32ui.CreateListView(doc)
sub_splitter = win32ui.CreateSplitter()
# pass "splitter" so each view knows how to get to the others
sub_splitter.CreateStatic (splitter, 1, 2)
sub_splitter.CreateView(self.v1, 0, 0, (sub_size))
sub_splitter.CreateView(self.v2, 0, 1, (0,0)) # size ignored.
splitter.SetRowInfo(0, size[1] ,0)
splitter.CreateView (self.v3, 1, 0, (0,0)) # size ignored.
# Setup items in the imagelist
self.images = win32ui.CreateImageList(32,32,1,5,5)
self.images.Add(win32ui.GetApp().LoadIcon(win32ui.IDR_MAINFRAME))
self.images.Add(win32ui.GetApp().LoadIcon(win32ui.IDR_PYTHONCONTYPE))
self.images.Add(win32ui.GetApp().LoadIcon(win32ui.IDR_TEXTTYPE))
self.v3.SetImageList(self.images, commctrl.LVSIL_NORMAL)
self.v3.InsertItem(0, "Icon 1", 0)
self.v3.InsertItem(0, "Icon 2", 1)
self.v3.InsertItem(0, "Icon 3", 2)
# self.v3.Arrange(commctrl.LVA_DEFAULT) Hmmm - win95 aligns left always???
return 1
def OnDestroy(self, msg):
window.MDIChildWnd.OnDestroy(self, msg)
if self.images:
self.images.DeleteImageList()
self.images = None
def InitialUpdateFrame(self, doc, makeVisible):
self.v1.ReplaceSel("Hello from Edit Window 1")
self.v1.SetModifiedFlag(0)
class SampleTemplate(docview.DocTemplate):
def __init__(self):
docview.DocTemplate.__init__(self, win32ui.IDR_PYTHONTYPE, None, SplitterFrame, None)
def InitialUpdateFrame(self, frame, doc, makeVisible):
# print "frame is ", frame, frame._obj_
# print "doc is ", doc, doc._obj_
self._obj_.InitialUpdateFrame(frame, doc, makeVisible) # call default handler.
frame.InitialUpdateFrame(doc, makeVisible)
def demo():
template = SampleTemplate()
doc=template.OpenDocumentFile(None)
doc.SetTitle("Splitter Demo")
if __name__=='__main__':
import demoutils
if demoutils.NeedGoodGUI():
demo()

View file

@ -0,0 +1,174 @@
# 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 win32ui
import win32con
import win32api
import timer
from pywin.mfc import window, docview, thread
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()

View file

@ -0,0 +1,93 @@
# Demo of ToolBars
# Shows the toolbar control.
# Demos how to make custom tooltips, etc.
import win32ui
import win32con
import win32api
from pywin.mfc import docview, window, afxres
import commctrl
class GenericFrame(window.MDIChildWnd):
def OnCreateClient(self, cp, context):
# handlers for toolbar buttons
self.HookCommand (self.OnPrevious, 401)
self.HookCommand (self.OnNext, 402)
# Its not necessary for us to hook both of these - the
# common controls should fall-back all by themselves.
# Indeed, given we hook TTN_NEEDTEXTW, commctrl.TTN_NEEDTEXTA
# will not be called.
self.HookNotify(self.GetTTText, commctrl.TTN_NEEDTEXT)
self.HookNotify(self.GetTTText, commctrl.TTN_NEEDTEXTW)
# parent = win32ui.GetMainFrame()
parent = self
style = win32con.WS_CHILD | win32con.WS_VISIBLE | \
afxres.CBRS_SIZE_DYNAMIC | afxres.CBRS_TOP | afxres.CBRS_TOOLTIPS | afxres.CBRS_FLYBY
buttons = (win32ui.ID_APP_ABOUT,win32ui.ID_VIEW_INTERACTIVE)
bitmap = win32ui.IDB_BROWSER_HIER
tbid = 0xE840
self.toolbar = tb = win32ui.CreateToolBar (parent, style, tbid)
tb.LoadBitmap(bitmap)
tb.SetButtons(buttons)
tb.EnableDocking(afxres.CBRS_ALIGN_ANY)
tb.SetWindowText("Test")
parent.EnableDocking(afxres.CBRS_ALIGN_ANY)
parent.DockControlBar(tb)
parent.LoadBarState("ToolbarTest")
window.MDIChildWnd.OnCreateClient(self, cp, context)
return 1
def OnDestroy(self, msg):
self.SaveBarState("ToolbarTest")
def GetTTText(self, std, extra):
(hwndFrom, idFrom, code) = std
text, hinst, flags = extra
if flags & commctrl.TTF_IDISHWND:
return # Not handled
if (idFrom==win32ui.ID_APP_ABOUT):
# our 'extra' return value needs to be the following
# entries from a NMTTDISPINFO[W] struct:
# (szText, hinst, uFlags). None means 'don't change
# the value'
return 0, ("It works!", None, None)
return None # not handled.
def GetMessageString(self, id):
if id==win32ui.ID_APP_ABOUT:
return "Dialog Test\nTest"
else:
return self._obj_.GetMessageString(id)
def OnSize (self, params):
print('OnSize called with ', params)
def OnNext (self, id, cmd):
print('OnNext called')
def OnPrevious (self, id, cmd):
print('OnPrevious called')
msg = """\
This toolbar was dynamically created.\r
\r
The first item's tooltips is provided by Python code.\r
\r
(Dont close the window with the toolbar in a floating state - it may not re-appear!)\r
"""
def test():
template = docview.DocTemplate( win32ui.IDR_PYTHONTYPE, None, GenericFrame, docview.EditView)
doc = template.OpenDocumentFile(None)
doc.SetTitle("Toolbar Test")
view = doc.GetFirstView()
view.SetWindowText(msg)
if __name__=='__main__':
import demoutils
if demoutils.NeedGoodGUI():
test()

View file

@ -0,0 +1,29 @@
[General]
# We base this configuration on the default config.
# You can list "Based On" as many times as you like
Based On = default
[Keys]
# Only list keys different to default.
# Note you may wish to rebind some of the default
# Pythonwin keys to "Beep" or "DoNothing"
Alt+L = LocateSelectedFile
Ctrl+Q = AppExit
# Other non-default Pythonwin keys
Alt+A = EditSelectAll
Alt+M = LocateModule
# Movement
Ctrl+D = GotoEndOfFile
# Tabs and other indent features
Alt+T = <<toggle-tabs>>
Ctrl+[ = <<indent-region>>
Ctrl+] = <<dedent-region>>
[Keys:Interactive]
Alt+P = <<history-previous>>
Alt+N = <<history-next>>

View file

@ -0,0 +1,10 @@
# is_platform_unicode is an old variable that was never correctly used and
# is no longer referenced in pywin32. It is staying for a few releases incase
# others are looking at it, but it will go away soon!
is_platform_unicode = 0
# Ditto default_platform_encoding - not referenced and will die.
default_platform_encoding = "mbcs"
# This one *is* real and used - but in practice can't be changed.
default_scintilla_encoding = "utf-8" # Scintilla _only_ supports this ATM

View file

@ -0,0 +1,113 @@
import sys
# Some cruft to deal with the Pythonwin GUI booting up from a non GUI app.
def _MakeDebuggerGUI():
app.InitInstance()
isInprocApp = -1
def _CheckNeedGUI():
global isInprocApp
if isInprocApp==-1:
import win32ui
isInprocApp = win32ui.GetApp().IsInproc()
if isInprocApp:
# MAY Need it - may already have one
need = "pywin.debugger.dbgpyapp" not in sys.modules
else:
need = 0
if need:
import pywin.framework.app
from . import dbgpyapp
pywin.framework.app.CreateDefaultGUI(dbgpyapp.DebuggerPythonApp)
else:
# Check we have the appropriate editor
# No longer necessary!
pass
return need
# Inject some methods in the top level name-space.
currentDebugger = None # Wipe out any old one on reload.
def _GetCurrentDebugger():
global currentDebugger
if currentDebugger is None:
_CheckNeedGUI()
from . import debugger
currentDebugger = debugger.Debugger()
return currentDebugger
def GetDebugger():
# An error here is not nice - as we are probably trying to
# break into the debugger on a Python error, any
# error raised by this is usually silent, and causes
# big problems later!
try:
rc = _GetCurrentDebugger()
rc.GUICheckInit()
return rc
except:
print("Could not create the debugger!")
import traceback
traceback.print_exc()
return None
def close():
if currentDebugger is not None:
currentDebugger.close()
def run(cmd,globals=None, locals=None, start_stepping = 1):
_GetCurrentDebugger().run(cmd, globals,locals, start_stepping)
def runeval(expression, globals=None, locals=None):
return _GetCurrentDebugger().runeval(expression, globals, locals)
def runcall(*args):
return _GetCurrentDebugger().runcall(*args)
def set_trace():
import sys
d = _GetCurrentDebugger()
if d.frameShutdown: return # App closing
if d.stopframe != d.botframe:
# If im not "running"
return
sys.settrace(None) # May be hooked
d.reset()
d.set_trace()
# "brk" is an alias for "set_trace" ("break" is a reserved word :-(
brk = set_trace
# Post-Mortem interface
def post_mortem(t=None):
if t is None:
t = sys.exc_info()[2] # Will be valid if we are called from an except handler.
if t is None:
try:
t = sys.last_traceback
except AttributeError:
print("No traceback can be found from which to perform post-mortem debugging!")
print("No debugging can continue")
return
p = _GetCurrentDebugger()
if p.frameShutdown: return # App closing
# No idea why I need to settrace to None - it should have been reset by now?
sys.settrace(None)
p.reset()
while t.tb_next != None: t = t.tb_next
p.bAtPostMortem = 1
p.prep_run(None)
try:
p.interaction(t.tb_frame, t)
finally:
t = None
p.bAtPostMortem = 0
p.done_run()
def pm(t=None):
post_mortem(t)

View file

@ -0,0 +1,31 @@
from . import dbgcon
from pywin.mfc import dialog
import win32ui
class DebuggerOptionsPropPage(dialog.PropertyPage):
def __init__(self):
dialog.PropertyPage.__init__(self, win32ui.IDD_PP_DEBUGGER)
def OnInitDialog(self):
options = self.options = dbgcon.LoadDebuggerOptions()
self.AddDDX(win32ui.IDC_CHECK1, dbgcon.OPT_HIDE)
self[dbgcon.OPT_STOP_EXCEPTIONS] = options[dbgcon.OPT_STOP_EXCEPTIONS]
self.AddDDX(win32ui.IDC_CHECK2, dbgcon.OPT_STOP_EXCEPTIONS)
self[dbgcon.OPT_HIDE] = options[dbgcon.OPT_HIDE]
return dialog.PropertyPage.OnInitDialog(self)
def OnOK(self):
self.UpdateData()
dirty = 0
for key, val in list(self.items()):
if key in self.options:
if self.options[key] != val:
self.options[key] = val
dirty = 1
if dirty:
dbgcon.SaveDebuggerOptions(self.options)
# If there is a debugger open, then set its options.
import pywin.debugger
if pywin.debugger.currentDebugger is not None:
pywin.debugger.currentDebugger.options = self.options
return 1

View file

@ -0,0 +1,28 @@
# General constants for the debugger
DBGSTATE_NOT_DEBUGGING = 0
DBGSTATE_RUNNING = 1
DBGSTATE_BREAK = 2
DBGSTATE_QUITTING = 3 # Attempting to back out of the debug session.
LINESTATE_CURRENT = 0x1 # This line is where we are stopped
LINESTATE_BREAKPOINT = 0x2 # This line is a breakpoint
LINESTATE_CALLSTACK = 0x4 # This line is in the callstack.
OPT_HIDE = 'hide'
OPT_STOP_EXCEPTIONS = 'stopatexceptions'
import win32api, win32ui
def DoGetOption(optsDict, optName, default):
optsDict[optName] = win32ui.GetProfileVal("Debugger Options", optName, default)
def LoadDebuggerOptions():
opts = {}
DoGetOption(opts, OPT_HIDE, 0)
DoGetOption(opts, OPT_STOP_EXCEPTIONS, 1)
return opts
def SaveDebuggerOptions(opts):
for key, val in opts.items():
win32ui.WriteProfileVal("Debugger Options", key, val)

View file

@ -0,0 +1,47 @@
# dbgpyapp.py - Debugger Python application class
#
import win32con
import win32ui
import sys
import string
import os
from pywin.framework import intpyapp
version = '0.3.0'
class DebuggerPythonApp(intpyapp.InteractivePythonApp):
def LoadMainFrame(self):
" Create the main applications frame "
self.frame = self.CreateMainFrame()
self.SetMainFrame(self.frame)
self.frame.LoadFrame(win32ui.IDR_DEBUGGER, win32con.WS_OVERLAPPEDWINDOW)
self.frame.DragAcceptFiles() # we can accept these.
self.frame.ShowWindow(win32con.SW_HIDE);
self.frame.UpdateWindow();
# but we do rehook, hooking the new code objects.
self.HookCommands()
def InitInstance(self):
# Use a registry path of "Python\Pythonwin Debugger
win32ui.SetAppName(win32ui.LoadString(win32ui.IDR_DEBUGGER))
win32ui.SetRegistryKey("Python %s" % (sys.winver,))
# We _need_ the Scintilla color editor.
# (and we _always_ get it now :-)
numMRU = win32ui.GetProfileVal("Settings","Recent File List Size", 10)
win32ui.LoadStdProfileSettings(numMRU)
self.LoadMainFrame()
# Display the interactive window if the user wants it.
from pywin.framework import interact
interact.CreateInteractiveWindowUserPreference()
# Load the modules we use internally.
self.LoadSystemModules()
# Load additional module the user may want.
self.LoadUserModules()
# win32ui.CreateDebuggerThread()
win32ui.EnableControlContainer()

View file

@ -0,0 +1,985 @@
# debugger.py
# A debugger for Pythonwin. Built from pdb.
# Mark Hammond (MHammond@skippinet.com.au) - Dec 94.
# usage:
# >>> import pywin.debugger
# >>> pywin.debugger.GetDebugger().run("command")
import pdb
import bdb
import sys
import string
import os
import types
import win32ui
import win32api
import win32con
import pywin.docking.DockingBar
from pywin.mfc import dialog, object, afxres, window
from pywin.framework import app, interact, editor, scriptutils
from pywin.framework.editor.color.coloreditor import MARKER_CURRENT, MARKER_BREAKPOINT
from pywin.tools import browser, hierlist
import commctrl
import traceback
#import win32traceutil
if win32ui.UNICODE:
LVN_ENDLABELEDIT = commctrl.LVN_ENDLABELEDITW
else:
LVN_ENDLABELEDIT = commctrl.LVN_ENDLABELEDITA
from .dbgcon import *
error = "pywin.debugger.error"
def SetInteractiveContext(globs, locs):
if interact.edit is not None and interact.edit.currentView is not None:
interact.edit.currentView.SetContext(globs, locs)
def _LineStateToMarker(ls):
if ls==LINESTATE_CURRENT:
return MARKER_CURRENT
# elif ls == LINESTATE_CALLSTACK:
# return MARKER_CALLSTACK
return MARKER_BREAKPOINT
class HierListItem(browser.HLIPythonObject):
pass
class HierFrameItem(HierListItem):
def __init__(self, frame, debugger):
HierListItem.__init__(self, frame, repr(frame))
self.debugger = debugger
def GetText(self):
name = self.myobject.f_code.co_name
if not name or name == '?' :
# See if locals has a '__name__' (ie, a module)
if '__name__' in self.myobject.f_locals:
name = str(self.myobject.f_locals['__name__']) + " module"
else:
name = '<Debugger Context>'
return "%s (%s:%d)" % (name, os.path.split(self.myobject.f_code.co_filename)[1], self.myobject.f_lineno)
def GetBitmapColumn(self):
if self.debugger.curframe is self.myobject:
return 7
else:
return 8
def GetSubList(self):
ret = []
ret.append(HierFrameDict(self.myobject.f_locals, "Locals", 2))
ret.append(HierFrameDict(self.myobject.f_globals, "Globals", 1))
return ret
def IsExpandable(self):
return 1
def TakeDefaultAction(self):
# Set the default frame to be this frame.
self.debugger.set_cur_frame(self.myobject)
return 1
class HierFrameDict(browser.HLIDict):
def __init__(self, dict, name, bitmapColumn):
self.bitmapColumn=bitmapColumn
browser.HLIDict.__init__(self, dict, name)
def GetBitmapColumn(self):
return self.bitmapColumn
class NoStackAvailableItem(HierListItem):
def __init__(self, why):
HierListItem.__init__(self, None, why)
def IsExpandable(self):
return 0
def GetText(self):
return self.name
def GetBitmapColumn(self):
return 8
class HierStackRoot(HierListItem):
def __init__( self, debugger ):
HierListItem.__init__(self, debugger, None)
self.last_stack = []
## def __del__(self):
## print "HierStackRoot dieing"
def GetSubList(self):
debugger = self.myobject
# print self.debugger.stack, self.debugger.curframe
ret = []
if debugger.debuggerState==DBGSTATE_BREAK:
stackUse=debugger.stack[:]
stackUse.reverse()
self.last_stack = []
for frame, lineno in stackUse:
self.last_stack.append( (frame, lineno) )
if frame is debugger.userbotframe: # Dont bother showing frames below our bottom frame.
break
for frame, lineno in self.last_stack:
ret.append( HierFrameItem( frame, debugger ) )
## elif debugger.debuggerState==DBGSTATE_NOT_DEBUGGING:
## ret.append(NoStackAvailableItem('<nothing is being debugged>'))
## else:
## ret.append(NoStackAvailableItem('<stack not available while running>'))
return ret
def GetText(self):
return 'root item'
def IsExpandable(self):
return 1
class HierListDebugger(hierlist.HierListWithItems):
""" Hier List of stack frames, breakpoints, whatever """
def __init__(self):
hierlist.HierListWithItems.__init__(self, None, win32ui.IDB_DEBUGGER_HIER, None, win32api.RGB(255,0,0))
def Setup(self, debugger):
root = HierStackRoot(debugger)
self.AcceptRoot(root)
# def Refresh(self):
# self.Setup()
class DebuggerWindow(window.Wnd):
def __init__(self, ob):
window.Wnd.__init__(self, ob)
self.debugger = None
def Init(self, debugger):
self.debugger = debugger
def GetDefRect(self):
defRect = app.LoadWindowSize("Debugger Windows\\" + self.title)
if defRect[2]-defRect[0]==0:
defRect = 0, 0, 150, 150
return defRect
def OnDestroy(self, msg):
newSize = self.GetWindowPlacement()[4]
pywin.framework.app.SaveWindowSize("Debugger Windows\\" + self.title, newSize)
return window.Wnd.OnDestroy(self, msg)
def OnKeyDown(self, msg):
key = msg[2]
if key in [13, 27, 32]: return 1
if key in [46,8]: # delete/BS key
self.DeleteSelected()
return 0
view = scriptutils.GetActiveView()
try:
firer = view.bindings.fire_key_event
except AttributeError:
firer = None
if firer is not None:
return firer(msg)
else:
return 1
def DeleteSelected(self):
win32api.MessageBeep()
def EditSelected(self):
win32api.MessageBeep()
class DebuggerStackWindow(DebuggerWindow):
title = "Stack"
def __init__(self):
DebuggerWindow.__init__(self, win32ui.CreateTreeCtrl())
self.list = HierListDebugger()
self.listOK = 0
def SaveState(self):
self.list.DeleteAllItems()
self.listOK = 0
win32ui.WriteProfileVal("Debugger Windows\\" + self.title, "Visible", self.IsWindowVisible())
def CreateWindow(self, parent):
style = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_BORDER | commctrl.TVS_HASLINES | commctrl.TVS_LINESATROOT | commctrl.TVS_HASBUTTONS
self._obj_.CreateWindow(style, self.GetDefRect(), parent, win32ui.IDC_LIST1)
self.HookMessage(self.OnKeyDown, win32con.WM_KEYDOWN)
self.HookMessage(self.OnKeyDown, win32con.WM_SYSKEYDOWN)
self.list.HierInit (parent, self)
self.listOK = 0 # delayed setup
#self.list.Setup()
def RespondDebuggerState(self, state):
assert self.debugger is not None, "Init not called"
if not self.listOK:
self.listOK = 1
self.list.Setup(self.debugger)
else:
self.list.Refresh()
def RespondDebuggerData(self):
try:
handle = self.GetChildItem(0)
except win32ui.error:
return # No items
while 1:
item = self.list.ItemFromHandle(handle)
col = self.list.GetBitmapColumn(item)
selCol = self.list.GetSelectedBitmapColumn(item)
if selCol is None: selCol = col
if self.list.GetItemImage(handle)!= (col, selCol):
self.list.SetItemImage(handle, col, selCol)
try:
handle = self.GetNextSiblingItem(handle)
except win32ui.error:
break
class DebuggerListViewWindow(DebuggerWindow):
def __init__(self):
DebuggerWindow.__init__(self, win32ui.CreateListCtrl())
def CreateWindow(self, parent):
list = self
style = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_BORDER | commctrl.LVS_EDITLABELS | commctrl.LVS_REPORT
self._obj_.CreateWindow(style, self.GetDefRect(), parent, win32ui.IDC_LIST1)
self.HookMessage(self.OnKeyDown, win32con.WM_KEYDOWN)
self.HookMessage(self.OnKeyDown, win32con.WM_SYSKEYDOWN)
list = self
title, width = self.columns[0]
itemDetails = (commctrl.LVCFMT_LEFT, width, title, 0)
list.InsertColumn(0, itemDetails)
col = 1
for title, width in self.columns[1:]:
col = col + 1
itemDetails = (commctrl.LVCFMT_LEFT, width, title, 0)
list.InsertColumn(col, itemDetails)
parent.HookNotify(self.OnListEndLabelEdit, LVN_ENDLABELEDIT)
parent.HookNotify(self.OnItemRightClick, commctrl.NM_RCLICK)
parent.HookNotify(self.OnItemDoubleClick, commctrl.NM_DBLCLK)
def RespondDebuggerData(self):
pass
def RespondDebuggerState(self, state):
pass
def EditSelected(self):
try:
sel = self.GetNextItem(-1, commctrl.LVNI_SELECTED)
except win32ui.error:
return
self.EditLabel(sel)
def OnKeyDown(self, msg):
key = msg[2]
# If someone starts typing, they probably are trying to edit the text!
if chr(key) in string.ascii_uppercase:
self.EditSelected()
return 0
return DebuggerWindow.OnKeyDown(self, msg)
def OnItemDoubleClick(self, notify_data, extra):
self.EditSelected()
def OnItemRightClick(self, notify_data, extra):
# First select the item we right-clicked on.
pt = self.ScreenToClient(win32api.GetCursorPos())
flags, hItem, subitem = self.HitTest(pt)
if hItem==-1 or commctrl.TVHT_ONITEM & flags==0:
return None
self.SetItemState(hItem, commctrl.LVIS_SELECTED, commctrl.LVIS_SELECTED)
menu = win32ui.CreatePopupMenu()
menu.AppendMenu(win32con.MF_STRING|win32con.MF_ENABLED,1000, "Edit item")
menu.AppendMenu(win32con.MF_STRING|win32con.MF_ENABLED,1001, "Delete item")
dockbar = self.GetParent()
if dockbar.IsFloating():
hook_parent = win32ui.GetMainFrame()
else:
hook_parent = self.GetParentFrame()
hook_parent.HookCommand(self.OnEditItem, 1000)
hook_parent.HookCommand(self.OnDeleteItem, 1001)
menu.TrackPopupMenu(win32api.GetCursorPos()) # track at mouse position.
return None
def OnDeleteItem(self,command, code):
self.DeleteSelected()
def OnEditItem(self, command, code):
self.EditSelected()
class DebuggerBreakpointsWindow(DebuggerListViewWindow):
title = "Breakpoints"
columns = [ ("Condition", 70), ("Location", 1024)]
def SaveState(self):
items = []
for i in range(self.GetItemCount()):
items.append(self.GetItemText(i,0))
items.append(self.GetItemText(i,1))
win32ui.WriteProfileVal("Debugger Windows\\" + self.title, "BreakpointList", "\t".join(items))
win32ui.WriteProfileVal("Debugger Windows\\" + self.title, "Visible", self.IsWindowVisible())
return 1
def OnListEndLabelEdit(self, std, extra):
item = extra[0]
text = item[4]
if text is None: return
item_id = self.GetItem(item[0])[6]
from bdb import Breakpoint
for bplist in Breakpoint.bplist.values():
for bp in bplist:
if id(bp)==item_id:
if text.strip().lower()=="none":
text = None
bp.cond = text
break
self.RespondDebuggerData()
def DeleteSelected(self):
try:
num = self.GetNextItem(-1, commctrl.LVNI_SELECTED)
item_id = self.GetItem(num)[6]
from bdb import Breakpoint
for bplist in list(Breakpoint.bplist.values()):
for bp in bplist:
if id(bp)==item_id:
self.debugger.clear_break(bp.file, bp.line)
break
except win32ui.error:
win32api.MessageBeep()
self.RespondDebuggerData()
def RespondDebuggerData(self):
l = self
l.DeleteAllItems()
index = -1
from bdb import Breakpoint
for bplist in Breakpoint.bplist.values():
for bp in bplist:
baseName = os.path.split(bp.file)[1]
cond = bp.cond
item = index+1, 0, 0, 0, str(cond), 0, id(bp)
index = l.InsertItem(item)
l.SetItemText(index, 1, "%s: %s" % (baseName, bp.line))
class DebuggerWatchWindow(DebuggerListViewWindow):
title = "Watch"
columns = [ ("Expression", 70), ("Value", 1024)]
def CreateWindow(self, parent):
DebuggerListViewWindow.CreateWindow(self, parent)
items = win32ui.GetProfileVal("Debugger Windows\\" + self.title, "Items", "").split("\t")
index = -1
for item in items:
if item:
index = self.InsertItem(index+1, item)
self.InsertItem(index+1, "<New Item>")
def SaveState(self):
items = []
for i in range(self.GetItemCount()-1):
items.append(self.GetItemText(i,0))
win32ui.WriteProfileVal("Debugger Windows\\" + self.title, "Items", "\t".join(items))
win32ui.WriteProfileVal("Debugger Windows\\" + self.title, "Visible", self.IsWindowVisible())
return 1
def OnListEndLabelEdit(self, std, extra):
item = extra[0]
itemno = item[0]
text = item[4]
if text is None: return
self.SetItemText(itemno, 0, text)
if itemno == self.GetItemCount()-1:
self.InsertItem(itemno+1, "<New Item>")
self.RespondDebuggerState(self.debugger.debuggerState)
def DeleteSelected(self):
try:
num = self.GetNextItem(-1, commctrl.LVNI_SELECTED)
if num < self.GetItemCount()-1: # We cant delete the last
self.DeleteItem(num)
except win32ui.error:
win32api.MessageBeep()
def RespondDebuggerState(self, state):
globs = locs = None
if state==DBGSTATE_BREAK:
if self.debugger.curframe:
globs = self.debugger.curframe.f_globals
locs = self.debugger.curframe.f_locals
elif state==DBGSTATE_NOT_DEBUGGING:
import __main__
globs = locs = __main__.__dict__
for i in range(self.GetItemCount()-1):
text = self.GetItemText(i, 0)
if globs is None:
val = ""
else:
try:
val = repr( eval( text, globs, locs) )
except SyntaxError:
val = "Syntax Error"
except:
t, v, tb = sys.exc_info()
val = traceback.format_exception_only(t, v)[0].strip()
tb = None # prevent a cycle.
self.SetItemText(i, 1, val)
def CreateDebuggerDialog(parent, klass):
control = klass()
control.CreateWindow(parent)
return control
DebuggerDialogInfos = (
(0xe810, DebuggerStackWindow, None),
(0xe811, DebuggerBreakpointsWindow, (10, 10)),
(0xe812, DebuggerWatchWindow, None),
)
# Prepare all the "control bars" for this package.
# If control bars are not all loaded when the toolbar-state functions are
# called, things go horribly wrong.
def PrepareControlBars(frame):
style = win32con.WS_CHILD | afxres.CBRS_SIZE_DYNAMIC | afxres.CBRS_TOP | afxres.CBRS_TOOLTIPS | afxres.CBRS_FLYBY
tbd = win32ui.CreateToolBar (frame, style, win32ui.ID_VIEW_TOOLBAR_DBG)
tbd.ModifyStyle(0, commctrl.TBSTYLE_FLAT)
tbd.LoadToolBar(win32ui.IDR_DEBUGGER)
tbd.EnableDocking(afxres.CBRS_ALIGN_ANY)
tbd.SetWindowText("Debugger")
frame.DockControlBar(tbd)
# and the other windows.
for id, klass, float in DebuggerDialogInfos:
try:
frame.GetControlBar(id)
exists=1
except win32ui.error:
exists=0
if exists: continue
bar = pywin.docking.DockingBar.DockingBar()
style=win32con.WS_CHILD | afxres.CBRS_LEFT # don't create visible.
bar.CreateWindow(frame, CreateDebuggerDialog, klass.title, id, style, childCreatorArgs=(klass,))
bar.SetBarStyle( bar.GetBarStyle()|afxres.CBRS_TOOLTIPS|afxres.CBRS_FLYBY|afxres.CBRS_SIZE_DYNAMIC)
bar.EnableDocking(afxres.CBRS_ALIGN_ANY)
if float is None:
frame.DockControlBar(bar)
else:
frame.FloatControlBar(bar, float, afxres.CBRS_ALIGN_ANY)
## frame.ShowControlBar(bar, 0, 1)
SKIP_NONE=0
SKIP_STEP=1
SKIP_RUN=2
debugger_parent=pdb.Pdb
class Debugger(debugger_parent):
def __init__(self):
self.inited = 0
self.skipBotFrame = SKIP_NONE
self.userbotframe = None
self.frameShutdown = 0
self.pumping = 0
self.debuggerState = DBGSTATE_NOT_DEBUGGING # Assume so, anyway.
self.shownLineCurrent = None # The last filename I highlighted.
self.shownLineCallstack = None # The last filename I highlighted.
self.last_cmd_debugged = ""
self.abortClosed = 0
self.isInitialBreakpoint = 0
debugger_parent.__init__(self)
# See if any break-points have been set in the editor
for doc in editor.editorTemplate.GetDocumentList():
lineNo = -1
while 1:
lineNo = doc.MarkerGetNext(lineNo+1, MARKER_BREAKPOINT)
if lineNo <= 0: break
self.set_break(doc.GetPathName(), lineNo)
self.reset()
self.inForcedGUI = win32ui.GetApp().IsInproc()
self.options = LoadDebuggerOptions()
self.bAtException = self.bAtPostMortem = 0
def __del__(self):
self.close()
def close(self, frameShutdown = 0):
# abortClose indicates if we have total shutdown
# (ie, main window is dieing)
if self.pumping:
# Can stop pump here, as it only posts a message, and
# returns immediately.
if not self.StopDebuggerPump(): # User cancelled close.
return 0
# NOTE - from this point on the close can not be
# stopped - the WM_QUIT message is already in the queue.
self.frameShutdown = frameShutdown
if not self.inited: return 1
self.inited = 0
SetInteractiveContext(None, None)
frame = win32ui.GetMainFrame()
# Hide the debuger toolbars (as they wont normally form part of the main toolbar state.
for id, klass, float in DebuggerDialogInfos:
try:
tb = frame.GetControlBar(id)
if tb.dialog is not None: # We may never have actually been shown.
tb.dialog.SaveState()
frame.ShowControlBar(tb, 0, 1)
except win32ui.error:
pass
self._UnshowCurrentLine()
self.set_quit()
return 1
def StopDebuggerPump(self):
assert self.pumping, "Can't stop the debugger pump if Im not pumping!"
# After stopping a pump, I may never return.
if self.GUIAboutToFinishInteract():
self.pumping = 0
win32ui.StopDebuggerPump() # Posts a message, so we do return.
return 1
return 0
def get_option(self, option):
"""Public interface into debugger options
"""
try:
return self.options[option]
except KeyError:
raise error("Option %s is not a valid option" % option)
def prep_run(self, cmd):
pass
def done_run(self, cmd=None):
self.RespondDebuggerState(DBGSTATE_NOT_DEBUGGING)
self.close()
def canonic(self, fname):
return os.path.abspath(fname).lower()
def reset(self):
debugger_parent.reset(self)
self.userbotframe = None
self.UpdateAllLineStates()
self._UnshowCurrentLine()
def setup(self, f, t):
debugger_parent.setup(self, f, t)
self.bAtException = t is not None
def set_break(self, filename, lineno, temporary=0, cond = None):
filename = self.canonic(filename)
self.SetLineState(filename, lineno, LINESTATE_BREAKPOINT)
return debugger_parent.set_break(self, filename, lineno, temporary, cond)
def clear_break(self, filename, lineno):
filename = self.canonic(filename)
self.ResetLineState(filename, lineno, LINESTATE_BREAKPOINT)
return debugger_parent.clear_break(self, filename, lineno)
def cmdloop(self):
if self.frameShutdown: return # App in the process of closing - never break in!
self.GUIAboutToBreak()
def print_stack_entry(self, frame):
# We dont want a stack printed - our GUI is better :-)
pass
def user_return(self, frame, return_value):
# Same as parent, just no "print"
# This function is called when a return trap is set here
frame.f_locals['__return__'] = return_value
self.interaction(frame, None)
def user_call(self, frame, args):
# base class has an annoying 'print' that adds no value to us...
if self.stop_here(frame):
self.interaction(frame, None)
def user_exception(self, frame, exc_info):
# This function is called if an exception occurs,
# but only if we are to stop at or just below this level
(exc_type, exc_value, exc_traceback) = exc_info
if self.get_option(OPT_STOP_EXCEPTIONS):
frame.f_locals['__exception__'] = exc_type, exc_value
print("Unhandled exception while debugging...")
# on both py2k and py3k, we may be called with exc_value
# being the args to the exception, or it may already be
# instantiated (IOW, PyErr_Normalize() hasn't been
# called on the args). In py2k this is fine, but in
# py3k, traceback.print_exception fails. So on py3k
# we instantiate an exception instance to print.
if sys.version_info > (3,) and not isinstance(exc_value, BaseException):
# they are args - may be a single item or already a tuple
if not isinstance(exc_value, tuple):
exc_value = (exc_value,)
exc_value = exc_type(*exc_value)
traceback.print_exception(exc_type, exc_value, exc_traceback)
self.interaction(frame, exc_traceback)
def user_line(self, frame):
if frame.f_lineno==0: return
debugger_parent.user_line(self, frame)
def stop_here(self, frame):
if self.isInitialBreakpoint:
self.isInitialBreakpoint = 0
self.set_continue()
return 0
if frame is self.botframe and self.skipBotFrame == SKIP_RUN:
self.set_continue()
return 0
if frame is self.botframe and self.skipBotFrame == SKIP_STEP:
self.set_step()
return 0
return debugger_parent.stop_here(self, frame)
def run(self, cmd,globals=None, locals=None, start_stepping = 1):
if not isinstance(cmd, (str, types.CodeType)):
raise TypeError("Only strings can be run")
self.last_cmd_debugged = cmd
if start_stepping:
self.isInitialBreakpoint = 0
else:
self.isInitialBreakpoint = 1
try:
if globals is None:
import __main__
globals = __main__.__dict__
if locals is None:
locals = globals
self.reset()
self.prep_run(cmd)
sys.settrace(self.trace_dispatch)
if type(cmd) != types.CodeType:
cmd = cmd+'\n'
try:
try:
if start_stepping: self.skipBotFrame = SKIP_STEP
else: self.skipBotFrame = SKIP_RUN
exec(cmd, globals, locals)
except bdb.BdbQuit:
pass
finally:
self.skipBotFrame = SKIP_NONE
self.quitting = 1
sys.settrace(None)
finally:
self.done_run(cmd)
def runeval(self, expr, globals=None, locals=None):
self.prep_run(expr)
try:
debugger_parent.runeval(self, expr, globals, locals)
finally:
self.done_run(expr)
def runexec(self, what, globs=None, locs=None):
self.reset()
sys.settrace(self.trace_dispatch)
try:
try:
exec(what, globs, locs)
except bdb.BdbQuit:
pass
finally:
self.quitting = 1
sys.settrace(None)
def do_set_step(self):
if self.GUIAboutToRun():
self.set_step()
def do_set_next(self):
if self.GUIAboutToRun():
self.set_next(self.curframe)
def do_set_return(self):
if self.GUIAboutToRun():
self.set_return(self.curframe)
def do_set_continue(self):
if self.GUIAboutToRun():
self.set_continue()
def set_quit(self):
ok = 1
if self.pumping:
ok = self.StopDebuggerPump()
if ok:
debugger_parent.set_quit(self)
def _dump_frame_(self, frame,name=None):
if name is None: name = ""
if frame:
if frame.f_code and frame.f_code.co_filename:
fname = os.path.split(frame.f_code.co_filename)[1]
else:
fname = "??"
print(repr(name), fname, frame.f_lineno, frame)
else:
print(repr(name), "None")
def set_trace(self):
# Start debugging from _2_ levels up!
try:
1 + ''
except:
frame = sys.exc_info()[2].tb_frame.f_back.f_back
self.reset()
self.userbotframe = None
while frame:
# scriptutils.py creates a local variable with name
# '_debugger_stop_frame_', and we dont go past it
# (everything above this is Pythonwin framework code)
if "_debugger_stop_frame_" in frame.f_locals:
self.userbotframe = frame
break
frame.f_trace = self.trace_dispatch
self.botframe = frame
frame = frame.f_back
self.set_step()
sys.settrace(self.trace_dispatch)
def set_cur_frame(self, frame):
# Sets the "current" frame - ie, the frame with focus. This is the
# frame on which "step out" etc actions are taken.
# This may or may not be the top of the stack.
assert frame is not None, "You must pass a valid frame"
self.curframe = frame
for f, index in self.stack:
if f is frame:
self.curindex = index
break
else:
assert 0, "Can't find the frame in the stack."
SetInteractiveContext(frame.f_globals, frame.f_locals)
self.GUIRespondDebuggerData()
self.ShowCurrentLine()
def IsBreak(self):
return self.debuggerState == DBGSTATE_BREAK
def IsDebugging(self):
return self.debuggerState != DBGSTATE_NOT_DEBUGGING
def RespondDebuggerState(self, state):
if state == self.debuggerState: return
if state==DBGSTATE_NOT_DEBUGGING: # Debugger exists, but not doing anything
title = ""
elif state==DBGSTATE_RUNNING: # Code is running under the debugger.
title = " - running"
elif state==DBGSTATE_BREAK: # We are at a breakpoint or stepping or whatever.
if self.bAtException:
if self.bAtPostMortem:
title = " - post mortem exception"
else:
title = " - exception"
else:
title = " - break"
else:
raise error("Invalid debugger state passed!")
win32ui.GetMainFrame().SetWindowText(win32ui.LoadString(win32ui.IDR_MAINFRAME) + title)
if self.debuggerState == DBGSTATE_QUITTING and state != DBGSTATE_NOT_DEBUGGING:
print("Ignoring state change cos Im trying to stop!", state)
return
self.debuggerState = state
try:
frame = win32ui.GetMainFrame()
except win32ui.error:
frame = None
if frame is not None:
for id, klass, float in DebuggerDialogInfos:
cb = win32ui.GetMainFrame().GetControlBar(id).dialog
cb.RespondDebuggerState(state)
# Tell each open editor window about the state transition
for doc in editor.editorTemplate.GetDocumentList():
doc.OnDebuggerStateChange(state)
self.ShowCurrentLine()
#
# GUI debugger interface.
#
def GUICheckInit(self):
if self.inited: return
self.inited = 1
frame = win32ui.GetMainFrame()
# Ensure the debugger windows are attached to the debugger.
for id, klass, float in DebuggerDialogInfos:
w = frame.GetControlBar(id)
w.dialog.Init(self)
# Show toolbar if it was visible during last debug session
# This would be better done using a CDockState, but that class is not wrapped yet
if win32ui.GetProfileVal("Debugger Windows\\" + w.dialog.title, "Visible", 0):
frame.ShowControlBar(w, 1, 1)
# ALWAYS show debugging toolbar, regardless of saved state
tb = frame.GetControlBar(win32ui.ID_VIEW_TOOLBAR_DBG)
frame.ShowControlBar(tb, 1, 1)
self.GUIRespondDebuggerData()
# frame.RecalcLayout()
def GetDebuggerBar(self, barName):
frame = win32ui.GetMainFrame()
for id, klass, float in DebuggerDialogInfos:
if klass.title == barName:
return frame.GetControlBar(id)
assert 0, "Can't find a bar of that name!"
def GUIRespondDebuggerData(self):
if not self.inited: # GUI not inited - no toolbars etc.
return
for id, klass, float in DebuggerDialogInfos:
cb = win32ui.GetMainFrame().GetControlBar(id).dialog
cb.RespondDebuggerData()
def GUIAboutToRun(self):
if not self.StopDebuggerPump():
return 0
self._UnshowCurrentLine()
self.RespondDebuggerState(DBGSTATE_RUNNING)
SetInteractiveContext(None, None)
return 1
def GUIAboutToBreak(self):
"Called as the GUI debugger is about to get context, and take control of the running program."
self.GUICheckInit()
self.RespondDebuggerState(DBGSTATE_BREAK)
self.GUIAboutToInteract()
if self.pumping:
print("!!! Already pumping - outa here")
return
self.pumping = 1
win32ui.StartDebuggerPump() # NOTE - This will NOT return until the user is finished interacting
assert not self.pumping, "Should not be pumping once the pump has finished"
if self.frameShutdown: # User shut down app while debugging
win32ui.GetMainFrame().PostMessage(win32con.WM_CLOSE)
def GUIAboutToInteract(self):
"Called as the GUI is about to perform any interaction with the user"
frame = win32ui.GetMainFrame()
# Remember the enabled state of our main frame
# may be disabled primarily if a modal dialog is displayed.
# Only get at enabled via GetWindowLong.
self.bFrameEnabled = frame.IsWindowEnabled()
self.oldForeground = None
fw = win32ui.GetForegroundWindow()
if fw is not frame:
self.oldForeground = fw
# fw.EnableWindow(0) Leave enabled for now?
self.oldFrameEnableState = frame.IsWindowEnabled()
frame.EnableWindow(1)
if self.inForcedGUI and not frame.IsWindowVisible():
frame.ShowWindow(win32con.SW_SHOW)
frame.UpdateWindow()
if self.curframe:
SetInteractiveContext(self.curframe.f_globals, self.curframe.f_locals)
else:
SetInteractiveContext(None, None)
self.GUIRespondDebuggerData()
def GUIAboutToFinishInteract(self):
"""Called as the GUI is about to finish any interaction with the user
Returns non zero if we are allowed to stop interacting"""
if self.oldForeground is not None:
try:
win32ui.GetMainFrame().EnableWindow(self.oldFrameEnableState)
self.oldForeground.EnableWindow(1)
except win32ui.error:
# old window may be dead.
pass
# self.oldForeground.SetForegroundWindow() - fails??
if not self.inForcedGUI:
return 1 # Never a problem, and nothing else to do.
# If we are running a forced GUI, we may never get an opportunity
# to interact again. Therefore we perform a "SaveAll", to makesure that
# any documents are saved before leaving.
for template in win32ui.GetApp().GetDocTemplateList():
for doc in template.GetDocumentList():
if not doc.SaveModified():
return 0
# All documents saved - now hide the app and debugger.
if self.get_option(OPT_HIDE):
frame = win32ui.GetMainFrame()
frame.ShowWindow(win32con.SW_HIDE)
return 1
#
# Pythonwin interface - all stuff to do with showing source files,
# changing line states etc.
#
def ShowLineState(self, fileName, lineNo, lineState):
# Set the state of a line, open if not already
self.ShowLineNo(fileName, lineNo)
self.SetLineState(fileName, lineNo, lineState)
def SetLineState(self, fileName, lineNo, lineState):
# Set the state of a line if the document is open.
doc = editor.editorTemplate.FindOpenDocument(fileName)
if doc is not None:
marker = _LineStateToMarker(lineState)
if not doc.MarkerCheck(lineNo, marker):
doc.MarkerAdd(lineNo, marker)
def ResetLineState(self, fileName, lineNo, lineState):
# Set the state of a line if the document is open.
doc = editor.editorTemplate.FindOpenDocument(fileName)
if doc is not None:
marker = _LineStateToMarker(lineState)
doc.MarkerDelete(lineNo, marker)
def UpdateDocumentLineStates(self, doc):
# Show all lines in their special status color. If the doc is open
# all line states are reset.
doc.MarkerDeleteAll( MARKER_BREAKPOINT )
doc.MarkerDeleteAll( MARKER_CURRENT )
fname = self.canonic(doc.GetPathName())
# Now loop over all break-points
for line in self.breaks.get(fname, []):
doc.MarkerAdd(line, MARKER_BREAKPOINT)
# And the current line if in this document.
if self.shownLineCurrent and fname == self.shownLineCurrent[0]:
lineNo = self.shownLineCurrent[1]
if not doc.MarkerCheck(lineNo, MARKER_CURRENT):
doc.MarkerAdd(lineNo, MARKER_CURRENT)
# if self.shownLineCallstack and fname == self.shownLineCallstack[0]:
# doc.MarkerAdd(self.shownLineCallstack[1], MARKER_CURRENT)
def UpdateAllLineStates(self):
for doc in editor.editorTemplate.GetDocumentList():
self.UpdateDocumentLineStates(doc)
def ShowCurrentLine(self):
# Show the current line. Only ever 1 current line - undoes last current
# The "Current Line" is self.curframe.
# The "Callstack Line" is the top of the stack.
# If current == callstack, only show as current.
self._UnshowCurrentLine() # un-highlight the old one.
if self.curframe:
fileName = self.canonic(self.curframe.f_code.co_filename)
lineNo = self.curframe.f_lineno
self.shownLineCurrent = fileName, lineNo
self.ShowLineState(fileName, lineNo, LINESTATE_CURRENT)
def _UnshowCurrentLine(self):
"Unshow the current line, and forget it"
if self.shownLineCurrent is not None:
fname, lineno = self.shownLineCurrent
self.ResetLineState(fname, lineno, LINESTATE_CURRENT)
self.shownLineCurrent = None
def ShowLineNo( self, filename, lineno ):
wasOpen = editor.editorTemplate.FindOpenDocument(filename) is not None
if os.path.isfile(filename) and scriptutils.JumpToDocument(filename, lineno):
if not wasOpen:
doc = editor.editorTemplate.FindOpenDocument(filename)
if doc is not None:
self.UpdateDocumentLineStates(doc)
return 1
return 0
return 1
else:
# Can't find the source file - linecache may have it?
import linecache
line = linecache.getline(filename, lineno)
print("%s(%d): %s" % (os.path.basename(filename), lineno, line[:-1].expandtabs(4)))
return 0

View file

@ -0,0 +1,48 @@
# NOTE NOTE - This module is designed to fail!
#
# The ONLY purpose for this script is testing/demoing the
# Pythonwin debugger package.
# It does nothing useful, and it even doesnt do that!
import pywin.debugger, sys, time
import traceback
def a():
a=1
try:
b()
except:
# Break into the debugger with the exception information.
pywin.debugger.post_mortem(sys.exc_info()[2])
a=1
a=2
a=3
a=4
pass
def b():
b=1
pywin.debugger.set_trace()
# After importing or running this module, you are likely to be
# sitting at the next line. This is because we explicitely
# broke into the debugger using the "set_trace() function
# "pywin.debugger.brk()" is a shorter alias for this.
c()
pass
def c():
c=1
d()
def d():
d=1
e(d)
raise ValueError("Hi")
def e(arg):
e=1
time.sleep(1)
return e
a()

View file

@ -0,0 +1,215 @@
# The default keyboard etc configuration file for Pythonwin.
#
# The format of this file is very similar to a Windows INI file.
# Sections are identified with [Section] lines, but comments
# use the standatd Python # character. Depending on the section,
# lines may not be in the standard "key=value" format.
# NOTE: You should not need to modify this file.
# Simply create a new .CFG file, and add an entry:
# [General]
# BasedOn = Default
#
# and add your customisations. Then select your new configuration
# from the Pythonwin View/Options/Editor dialog.
# This way you get to add your own customisations,
# but still take advantage of changes to the default
# configuration in new releases.
# See IDLE.cfg for an example extension configuration.
#
##########################################################################
[IDLE Extensions]
# The list of IDLE extensions to load. The extensions
# AutoIndent, AutoFormat and possibly others are
# "built-in", so do not need specifying.
FormatParagraph
CallTips
[Keys]
# The list of _default_ key definitions.
# See [Keys:Interactive] and [Keys:Editor] below for further defs.
#Events of the format <<event-name>>
# are events defined in IDLE extensions.
Alt+Q = <<format-paragraph>>
Ctrl+W = ViewWhitespace
Ctrl+Shift+8 = ViewWhitespace # The MSVC default key def.
Ctrl+Shift+F = ViewFixedFont
# Auto-complete, call-tips, etc.
Alt+/ = <<expand-word>>
Ctrl+Space = <<expand-word>>
( = <<paren-open>>
) = <<paren-close>>
Up = <<check-calltip-cancel>>
Down = <<check-calltip-cancel>>
Left = <<check-calltip-cancel>>
Right = <<check-calltip-cancel>>
. = KeyDot
# Debugger - These are the MSVC default keys, for want of a better choice.
F9 = DbgBreakpointToggle
F5 = DbgGo
Shift+F5 = DbgClose
F11 = DbgStep
F10 = DbgStepOver
Shift+F11 = DbgStepOut
Ctrl+F3 = AutoFindNext
[Keys:Editor]
# Key bindings specific to the editor
F2 = GotoNextBookmark
Ctrl+F2 = ToggleBookmark
Ctrl+G = GotoLine
Alt+I = ShowInteractiveWindow
Alt-B = AddBanner # A sample Event defined in this file.
# Block operations
Alt+3 = <<comment-region>>
Shift+Alt+3 = <<uncomment-region>>
Alt+4 = <<uncomment-region>> # IDLE default.
Alt+5 = <<tabify-region>>
Alt+6 = <<untabify-region>>
# Tabs and other indent features
Back = <<smart-backspace>>
Ctrl+T = <<toggle-tabs>>
Alt+U = <<change-indentwidth>>
Enter = EnterKey
Tab = TabKey
Shift-Tab = <<dedent-region>>
# Folding
Add = FoldExpand
Alt+Add = FoldExpandAll
Shift+Add = FoldExpandSecondLevel
Subtract = FoldCollapse
Alt+Subtract = FoldCollapseAll
Shift+Subtract = FoldCollapseSecondLevel
Multiply = FoldTopLevel
[Keys:Interactive]
# Key bindings specific to the interactive window.
# History for the interactive window
Ctrl+Up = <<history-previous>>
Ctrl+Down = <<history-next>>
Enter = ProcessEnter
Ctrl+Enter = ProcessEnter
Shift+Enter = ProcessEnter
Esc = ProcessEsc
Alt+I = WindowBack # Toggle back to previous window.
Home = InteractiveHome # A sample Event defined in this file.
Shift+Home = InteractiveHomeExtend # A sample Event defined in this file.
# When docked, the Ctrl+Tab and Shift+Ctrl+Tab keys dont work as expected.
Ctrl+Tab = MDINext
Ctrl+Shift+Tab = MDIPrev
[Extensions]
# Python event handlers specific to this config file.
# All functions not starting with an "_" are assumed
# to be events, and take 2 params:
# * editor_window is the same object passed to IDLE
# extensions. editor_window.text is a text widget
# that conforms to the Tk text widget interface.
# * event is the event being fired. Will always be None
# in the current implementation.
# Simply by defining these functions, they are available as
# events.
# Note that we bind keystrokes to these events in the various
# [Keys] sections.
# Add a simple file/class/function simple banner
def AddBanner(editor_window, event):
text = editor_window.text
big_line = "#" * 70
banner = "%s\n## \n## \n## \n%s\n" % (big_line, big_line)
# Insert at the start of the current line.
pos = text.index("insert linestart")
text.undo_block_start() # Allow action to be undone as a single unit.
text.insert(pos, banner)
text.undo_block_stop()
# Now set the insert point to the middle of the banner.
line, col = [int(s) for s in pos.split(".")]
text.mark_set("insert", "%d.1 lineend" % (line+2, ) )
# Here is a sample event bound to the "Home" key in the
# interactive window
def InteractiveHome(editor_window, event):
return _DoInteractiveHome(editor_window.text, 0)
def InteractiveHomeExtend(editor_window, event):
return _DoInteractiveHome(editor_window.text, 1)
def _DoInteractiveHome(text, extend):
import sys
# If Scintilla has an autocomplete window open, then let Scintilla handle it.
if text.edit.SCIAutoCActive():
return 1
of_interest = "insert linestart + %d c" % len(sys.ps1)
if not text.compare("insert", "==", of_interest) and \
text.get("insert linestart", of_interest) in [sys.ps1, sys.ps2]: # Not sys.ps? line
end = of_interest
else:
end = "insert linestart"
if extend: start = "insert"
else: start = end
text.tag_add("sel", start, end)
# From Niki Spahie
def AutoFindNext(editor_window, event):
"find selected text or word under cursor"
from pywin.scintilla import find
from pywin.scintilla import scintillacon
try:
sci = editor_window.edit
word = sci.GetSelText()
if word:
find.lastSearch.findText = word
find.lastSearch.sel = sci.GetSel()
else:
pos = sci.SendScintilla( scintillacon.SCI_GETCURRENTPOS )
start = sci.SendScintilla( scintillacon.SCI_WORDSTARTPOSITION, pos, 1 )
end = sci.SendScintilla( scintillacon.SCI_WORDENDPOSITION, pos, 1 )
word = sci.GetTextRange( start, end )
if word:
find.lastSearch.findText = word
find.lastSearch.sel = (start,end)
except Exception:
import traceback
traceback.print_exc()
find.FindNext()
# A couple of generic events.
def Beep(editor_window, event):
editor_window.text.beep()
def DoNothing(editor_window, event):
pass
def ContinueEvent(editor_window, event):
# Almost an "unbind" - allows Pythonwin/MFC to handle the keystroke
return 1

View file

@ -0,0 +1,116 @@
# The property page to define generic IDE options for Pythonwin
from pywin.mfc import dialog
from pywin.framework import interact
import win32ui
import win32con
buttonControlMap = {
win32ui.IDC_BUTTON1: win32ui.IDC_EDIT1,
win32ui.IDC_BUTTON2: win32ui.IDC_EDIT2,
win32ui.IDC_BUTTON3: win32ui.IDC_EDIT3,
}
class OptionsPropPage(dialog.PropertyPage):
def __init__(self):
dialog.PropertyPage.__init__(self, win32ui.IDD_PP_IDE)
self.AddDDX(win32ui.IDC_CHECK1, "bShowAtStartup")
self.AddDDX(win32ui.IDC_CHECK2, "bDocking")
self.AddDDX(win32ui.IDC_EDIT4, 'MRUSize', "i")
def OnInitDialog(self):
edit = self.GetDlgItem(win32ui.IDC_EDIT1)
format = eval(win32ui.GetProfileVal(interact.sectionProfile, interact.STYLE_INTERACTIVE_PROMPT, str(interact.formatInput)))
edit.SetDefaultCharFormat(format)
edit.SetWindowText("Input Text")
edit = self.GetDlgItem(win32ui.IDC_EDIT2)
format = eval(win32ui.GetProfileVal(interact.sectionProfile, interact.STYLE_INTERACTIVE_OUTPUT, str(interact.formatOutput)))
edit.SetDefaultCharFormat(format)
edit.SetWindowText("Output Text")
edit = self.GetDlgItem(win32ui.IDC_EDIT3)
format = eval(win32ui.GetProfileVal(interact.sectionProfile, interact.STYLE_INTERACTIVE_ERROR, str(interact.formatOutputError)))
edit.SetDefaultCharFormat(format)
edit.SetWindowText("Error Text")
self['bShowAtStartup'] = interact.LoadPreference("Show at startup", 1)
self['bDocking'] = interact.LoadPreference("Docking", 0)
self['MRUSize'] = win32ui.GetProfileVal("Settings","Recent File List Size", 10)
# Hook the button clicks.
self.HookCommand(self.HandleCharFormatChange, win32ui.IDC_BUTTON1)
self.HookCommand(self.HandleCharFormatChange, win32ui.IDC_BUTTON2)
self.HookCommand(self.HandleCharFormatChange, win32ui.IDC_BUTTON3)
# Ensure the spin control remains in range.
spinner = self.GetDlgItem(win32ui.IDC_SPIN1)
spinner.SetRange(1, 16)
return dialog.PropertyPage.OnInitDialog(self)
# Called to save away the new format tuple for the specified item.
def HandleCharFormatChange(self, id, code):
if code == win32con.BN_CLICKED:
editId = buttonControlMap.get(id)
assert editId is not None, "Format button has no associated edit control"
editControl = self.GetDlgItem(editId)
existingFormat = editControl.GetDefaultCharFormat()
flags = win32con.CF_SCREENFONTS
d=win32ui.CreateFontDialog(existingFormat, flags, None, self)
if d.DoModal()==win32con.IDOK:
cf = d.GetCharFormat()
editControl.SetDefaultCharFormat(cf)
self.SetModified(1)
return 0 # We handled this fully!
def OnOK(self):
# Handle the edit controls - get all the fonts, put them back into interact, then
# get interact to save its stuff!
controlAttrs = [
(win32ui.IDC_EDIT1, interact.STYLE_INTERACTIVE_PROMPT),
(win32ui.IDC_EDIT2, interact.STYLE_INTERACTIVE_OUTPUT),
(win32ui.IDC_EDIT3, interact.STYLE_INTERACTIVE_ERROR)]
for id, key in controlAttrs:
control = self.GetDlgItem(id)
fmt = control.GetDefaultCharFormat()
win32ui.WriteProfileVal(interact.sectionProfile, key, str(fmt))
# Save the other interactive window options.
interact.SavePreference("Show at startup", self['bShowAtStartup'])
interact.SavePreference("Docking", self['bDocking'])
# And the other options.
win32ui.WriteProfileVal("Settings","Recent File List Size", self['MRUSize'])
return 1
def ChangeFormat(self, fmtAttribute, fmt):
dlg = win32ui.CreateFontDialog(fmt)
if dlg.DoModal() != win32con.IDOK: return None
return dlg.GetCharFormat()
def OnFormatTitle(self, command, code):
fmt = self.GetFormat(interact.formatTitle)
if fmt:
formatTitle = fmt
SaveFontPreferences()
def OnFormatInput(self, command, code):
global formatInput
fmt = self.GetFormat(formatInput)
if fmt:
formatInput = fmt
SaveFontPreferences()
def OnFormatOutput(self, command, code):
global formatOutput
fmt = self.GetFormat(formatOutput)
if fmt:
formatOutput = fmt
SaveFontPreferences()
def OnFormatError(self, command, code):
global formatOutputError
fmt = self.GetFormat(formatOutputError)
if fmt:
formatOutputError = fmt
SaveFontPreferences()

View file

@ -0,0 +1,122 @@
from pywin.mfc import dialog
import win32ui, win32con, commctrl, win32api
class ListDialog (dialog.Dialog):
def __init__ (self, title, list):
dialog.Dialog.__init__ (self, self._maketemplate(title))
self.HookMessage (self.on_size, win32con.WM_SIZE)
self.HookNotify(self.OnListItemChange, commctrl.LVN_ITEMCHANGED)
self.HookCommand(self.OnListClick, win32ui.IDC_LIST1)
self.items = list
def _maketemplate(self, title):
style = win32con.WS_DLGFRAME | win32con.WS_SYSMENU | win32con.WS_VISIBLE
ls = (
win32con.WS_CHILD |
win32con.WS_VISIBLE |
commctrl.LVS_ALIGNLEFT |
commctrl.LVS_REPORT
)
bs = (
win32con.WS_CHILD |
win32con.WS_VISIBLE
)
return [ [title, (0, 0, 200, 200), style, None, (8, "MS Sans Serif")],
["SysListView32", None, win32ui.IDC_LIST1, (0, 0, 200, 200), ls],
[128, "OK", win32con.IDOK, (10, 0, 50, 14), bs | win32con.BS_DEFPUSHBUTTON],
[128, "Cancel",win32con.IDCANCEL,(0, 0, 50, 14), bs],
]
def FillList(self):
size = self.GetWindowRect()
width = size[2] - size[0] - (10)
itemDetails = (commctrl.LVCFMT_LEFT, width, "Item", 0)
self.itemsControl.InsertColumn(0, itemDetails)
index = 0
for item in self.items:
index = self.itemsControl.InsertItem(index+1, str(item), 0)
def OnListClick(self, id, code):
if code==commctrl.NM_DBLCLK:
self.EndDialog(win32con.IDOK)
return 1
def OnListItemChange(self,std, extra):
(hwndFrom, idFrom, code), (itemNotify, sub, newState, oldState, change, point, lparam) = std, extra
oldSel = (oldState & commctrl.LVIS_SELECTED)!=0
newSel = (newState & commctrl.LVIS_SELECTED)!=0
if oldSel != newSel:
try:
self.selecteditem = itemNotify
self.butOK.EnableWindow(1)
except win32ui.error:
self.selecteditem = None
def OnInitDialog (self):
rc = dialog.Dialog.OnInitDialog (self)
self.itemsControl = self.GetDlgItem(win32ui.IDC_LIST1)
self.butOK = self.GetDlgItem(win32con.IDOK)
self.butCancel = self.GetDlgItem(win32con.IDCANCEL)
self.FillList()
size = self.GetWindowRect()
self.LayoutControls(size[2]-size[0], size[3]-size[1])
self.butOK.EnableWindow(0) # wait for first selection
return rc
def LayoutControls(self, w, h):
self.itemsControl.MoveWindow((0,0,w,h-30))
self.butCancel.MoveWindow((10, h-24, 60, h-4))
self.butOK.MoveWindow((w-60, h-24, w-10, h-4))
def on_size (self, params):
lparam = params[3]
w = win32api.LOWORD(lparam)
h = win32api.HIWORD(lparam)
self.LayoutControls(w, h)
class ListsDialog(ListDialog):
def __init__(self, title, list, colHeadings = ['Item']):
ListDialog.__init__(self, title, list)
self.colHeadings = colHeadings
def FillList(self):
index = 0
size = self.GetWindowRect()
width = size[2] - size[0] - (10) - win32api.GetSystemMetrics(win32con.SM_CXVSCROLL)
numCols = len(self.colHeadings)
for col in self.colHeadings:
itemDetails = (commctrl.LVCFMT_LEFT, width/numCols, col, 0)
self.itemsControl.InsertColumn(index, itemDetails)
index = index + 1
index = 0
for items in self.items:
index = self.itemsControl.InsertItem(index+1, str(items[0]), 0)
for itemno in range(1,numCols):
item = items[itemno]
self.itemsControl.SetItemText(index, itemno, str(item))
def SelectFromList (title, lst):
dlg = ListDialog(title, lst)
if dlg.DoModal()==win32con.IDOK:
return dlg.selecteditem
else:
return None
def SelectFromLists (title, lists, headings):
dlg = ListsDialog(title, lists, headings)
if dlg.DoModal()==win32con.IDOK:
return dlg.selecteditem
else:
return None
def test():
# print SelectFromList('Single list', [1,2,3])
print(SelectFromLists('Multi-List', [ ('1',1, 'a'), ('2',2, 'b'), ('3',3, 'c' )], ['Col 1', 'Col 2']))
if __name__=='__main__':
test()

View file

@ -0,0 +1,121 @@
'''login -- PythonWin user ID and password dialog box
(Adapted from originally distributed with Mark Hammond's PythonWin -
this now replaces it!)
login.GetLogin() displays a modal "OK/Cancel" dialog box with input
fields for a user ID and password. The password field input is masked
with *'s. GetLogin takes two optional parameters, a window title, and a
default user ID. If these parameters are omitted, the title defaults to
"Login", and the user ID is left blank. GetLogin returns a (userid, password)
tuple. GetLogin can be called from scripts running on the console - i.e. you
don't need to write a full-blown GUI app to use it.
login.GetPassword() is similar, except there is no username field.
Example:
import pywin.dialogs.login
title = "FTP Login"
def_user = "fred"
userid, password = pywin.dialogs.login.GetLogin(title, def_user)
Jim Eggleston, 28 August 1996
Merged with dlgpass and moved to pywin.dialogs by Mark Hammond Jan 1998.
'''
import win32ui
import win32api
import win32con
from pywin.mfc import dialog
def MakeLoginDlgTemplate(title):
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
# Window frame and title
dlg = [ [title, (0, 0, 184, 40), style, None, (8, "MS Sans Serif")], ]
# ID label and text box
dlg.append([130, "User ID:", -1, (7, 9, 69, 9), cs | win32con.SS_LEFT])
s = cs | win32con.WS_TABSTOP | win32con.WS_BORDER
dlg.append(['EDIT', None, win32ui.IDC_EDIT1, (50, 7, 60, 12), s])
# Password label and text box
dlg.append([130, "Password:", -1, (7, 22, 69, 9), cs | win32con.SS_LEFT])
s = cs | win32con.WS_TABSTOP | win32con.WS_BORDER
dlg.append(['EDIT', None, win32ui.IDC_EDIT2, (50, 20, 60, 12), s | win32con.ES_PASSWORD])
# OK/Cancel Buttons
s = cs | win32con.WS_TABSTOP
dlg.append([128, "OK", win32con.IDOK, (124, 5, 50, 14), s | win32con.BS_DEFPUSHBUTTON])
s = win32con.BS_PUSHBUTTON | s
dlg.append([128, "Cancel", win32con.IDCANCEL, (124, 20, 50, 14), s])
return dlg
def MakePasswordDlgTemplate(title):
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
# Window frame and title
dlg = [ [title, (0, 0, 177, 45), style, None, (8, "MS Sans Serif")], ]
# Password label and text box
dlg.append([130, "Password:", -1, (7, 7, 69, 9), cs | win32con.SS_LEFT])
s = cs | win32con.WS_TABSTOP | win32con.WS_BORDER
dlg.append(['EDIT', None, win32ui.IDC_EDIT1, (50, 7, 60, 12), s | win32con.ES_PASSWORD])
# OK/Cancel Buttons
s = cs | win32con.WS_TABSTOP | win32con.BS_PUSHBUTTON
dlg.append([128, "OK", win32con.IDOK, (124, 5, 50, 14), s | win32con.BS_DEFPUSHBUTTON])
dlg.append([128, "Cancel", win32con.IDCANCEL, (124, 22, 50, 14), s])
return dlg
class LoginDlg(dialog.Dialog):
Cancel = 0
def __init__(self, title):
dialog.Dialog.__init__(self, MakeLoginDlgTemplate(title) )
self.AddDDX(win32ui.IDC_EDIT1,'userid')
self.AddDDX(win32ui.IDC_EDIT2,'password')
def GetLogin(title='Login', userid='', password=''):
d = LoginDlg(title)
d['userid'] = userid
d['password'] = password
if d.DoModal() != win32con.IDOK:
return (None, None)
else:
return (d['userid'], d['password'])
class PasswordDlg(dialog.Dialog):
def __init__(self, title):
dialog.Dialog.__init__(self, MakePasswordDlgTemplate(title) )
self.AddDDX(win32ui.IDC_EDIT1,'password')
def GetPassword(title='Password', password=''):
d = PasswordDlg(title)
d['password'] = password
if d.DoModal()!=win32con.IDOK:
return None
return d['password']
if __name__ == "__main__":
import sys
title = 'Login'
def_user = ''
if len(sys.argv) > 1:
title = sys.argv[1]
if len(sys.argv) > 2:
def_userid = sys.argv[2]
userid, password = GetLogin(title, def_user)
if userid == password == None:
print("User pressed Cancel")
else:
print("User ID: ", userid)
print("Password:", password)
newpassword = GetPassword("Reenter just for fun", password)
if newpassword is None:
print("User cancelled")
else:
what = ""
if newpassword != password:
what = "not "
print("The passwords did %smatch" % (what))

View file

@ -0,0 +1,227 @@
# 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()

View file

@ -0,0 +1,541 @@
# DockingBar.py
# Ported directly (comments and all) from the samples at www.codeguru.com
# WARNING: Use at your own risk, as this interface is highly likely to change.
# Currently we support only one child per DockingBar. Later we need to add
# support for multiple children.
import win32api, win32con, win32ui
from pywin.mfc import afxres, window
import struct
clrBtnHilight = win32api.GetSysColor(win32con.COLOR_BTNHILIGHT)
clrBtnShadow = win32api.GetSysColor(win32con.COLOR_BTNSHADOW)
def CenterPoint(rect):
width = rect[2]-rect[0]
height = rect[3]-rect[1]
return rect[0] + width//2, rect[1] + height//2
def OffsetRect(rect, point):
(x, y) = point
return rect[0]+x, rect[1]+y, rect[2]+x, rect[3]+y
def DeflateRect(rect, point):
(x, y) = point
return rect[0]+x, rect[1]+y, rect[2]-x, rect[3]-y
def PtInRect(rect, pt):
return rect[0] <= pt[0] < rect[2] and rect[1] <= pt[1] < rect[3]
class DockingBar(window.Wnd):
def __init__(self, obj=None):
if obj is None:
obj = win32ui.CreateControlBar()
window.Wnd.__init__(self, obj)
self.dialog = None
self.nDockBarID = 0
self.sizeMin = 32, 32
self.sizeHorz = 200, 200
self.sizeVert = 200, 200
self.sizeFloat = 200, 200
self.bTracking = 0
self.bInRecalcNC = 0
self.cxEdge = 6
self.cxBorder = 3
self.cxGripper = 20
self.brushBkgd = win32ui.CreateBrush()
self.brushBkgd.CreateSolidBrush(win32api.GetSysColor(win32con.COLOR_BTNFACE))
# Support for diagonal resizing
self.cyBorder = 3
self.cCaptionSize = win32api.GetSystemMetrics(win32con.SM_CYSMCAPTION)
self.cMinWidth = win32api.GetSystemMetrics(win32con.SM_CXMIN)
self.cMinHeight = win32api.GetSystemMetrics(win32con.SM_CYMIN)
self.rectUndock = (0,0,0,0)
def OnUpdateCmdUI(self, target, bDisableIfNoHndler):
return self.UpdateDialogControls(target, bDisableIfNoHndler)
def CreateWindow(self, parent, childCreator, title, id, style=win32con.WS_CHILD | win32con.WS_VISIBLE | afxres.CBRS_LEFT, childCreatorArgs=()):
assert not ((style & afxres.CBRS_SIZE_FIXED) and (style & afxres.CBRS_SIZE_DYNAMIC)), "Invalid style"
self.rectClose = self.rectBorder = self.rectGripper = self.rectTracker = 0,0,0,0
# save the style
self._obj_.dwStyle = style & afxres.CBRS_ALL
cursor = win32api.LoadCursor(0, win32con.IDC_ARROW)
wndClass = win32ui.RegisterWndClass(win32con.CS_DBLCLKS, cursor, self.brushBkgd.GetSafeHandle(), 0)
self._obj_.CreateWindow(wndClass, title, style, (0,0,0,0), parent, id)
# Create the child dialog
self.dialog = childCreator(*(self,) + childCreatorArgs)
# use the dialog dimensions as default base dimensions
assert self.dialog.IsWindow(), "The childCreator function %s did not create a window!" % childCreator
rect = self.dialog.GetWindowRect()
self.sizeHorz = self.sizeVert = self.sizeFloat = rect[2]-rect[0], rect[3]-rect[1]
self.sizeHorz = self.sizeHorz[0], self.sizeHorz[1] + self.cxEdge + self.cxBorder
self.sizeVert = self.sizeVert[0] + self.cxEdge + self.cxBorder, self.sizeVert[1]
self.HookMessages()
def CalcFixedLayout(self, bStretch, bHorz):
rectTop = self.dockSite.GetControlBar(afxres.AFX_IDW_DOCKBAR_TOP).GetWindowRect()
rectLeft = self.dockSite.GetControlBar(afxres.AFX_IDW_DOCKBAR_LEFT).GetWindowRect()
if bStretch:
nHorzDockBarWidth = 32767
nVertDockBarHeight = 32767
else:
nHorzDockBarWidth = rectTop[2]-rectTop[0] + 4
nVertDockBarHeight = rectLeft[3]-rectLeft[1] + 4
if self.IsFloating():
return self.sizeFloat
if bHorz:
return nHorzDockBarWidth, self.sizeHorz[1]
return self.sizeVert[0], nVertDockBarHeight
def CalcDynamicLayout(self, length, mode):
# Support for diagonal sizing.
if self.IsFloating():
self.GetParent().GetParent().ModifyStyle(win32ui.MFS_4THICKFRAME, 0)
if mode & (win32ui.LM_HORZDOCK | win32ui.LM_VERTDOCK):
flags = win32con.SWP_NOSIZE | win32con.SWP_NOMOVE | win32con.SWP_NOZORDER |\
win32con.SWP_NOACTIVATE | win32con.SWP_FRAMECHANGED
self.SetWindowPos(0, (0, 0, 0, 0,), flags)
self.dockSite.RecalcLayout()
return self._obj_.CalcDynamicLayout(length, mode)
if mode & win32ui.LM_MRUWIDTH:
return self.sizeFloat
if mode & win32ui.LM_COMMIT:
self.sizeFloat = length, self.sizeFloat[1]
return self.sizeFloat
# More diagonal sizing.
if self.IsFloating():
dc = self.dockContext
pt = win32api.GetCursorPos()
windowRect = self.GetParent().GetParent().GetWindowRect()
hittest = dc.nHitTest
if hittest==win32con.HTTOPLEFT:
cx = max(windowRect[2] - pt[0], self.cMinWidth) - self.cxBorder
cy = max(windowRect[3] - self.cCaptionSize - pt[1],self.cMinHeight) - 1
self.sizeFloat = cx, cy
top = min(pt[1], windowRect[3] - self.cCaptionSize - self.cMinHeight) - self.cyBorder
left = min(pt[0], windowRect[2] - self.cMinWidth) - 1
dc.rectFrameDragHorz = left, top, dc.rectFrameDragHorz[2], dc.rectFrameDragHorz[3]
return self.sizeFloat
if hittest==win32con.HTTOPRIGHT:
cx = max(pt[0] - windowRect[0], self.cMinWidth)
cy = max(windowRect[3] - self.cCaptionSize - pt[1], self.cMinHeight) - 1
self.sizeFloat = cx, cy
top = min(pt[1], windowRect[3] - self.cCaptionSize - self.cMinHeight) - self.cyBorder
dc.rectFrameDragHorz = dc.rectFrameDragHorz[0], top, dc.rectFrameDragHorz[2], dc.rectFrameDragHorz[3]
return self.sizeFloat
if hittest==win32con.HTBOTTOMLEFT:
cx = max(windowRect[2] - pt[0], self.cMinWidth) - self.cxBorder
cy = max(pt[1] - windowRect[1] - self.cCaptionSize, self.cMinHeight)
self.sizeFloat = cx, cy
left = min(pt[0], windowRect[2] -self.cMinWidth) - 1
dc.rectFrameDragHorz = left, dc.rectFrameDragHorz[1], dc.rectFrameDragHorz[2], dc.rectFrameDragHorz[3]
return self.sizeFloat
if hittest==win32con.HTBOTTOMRIGHT:
cx = max(pt[0] - windowRect[0], self.cMinWidth)
cy = max(pt[1] - windowRect[1] - self.cCaptionSize, self.cMinHeight)
self.sizeFloat = cx, cy
return self.sizeFloat
if mode & win32ui.LM_LENGTHY:
self.sizeFloat = self.sizeFloat[0], max(self.sizeMin[1], length)
return self.sizeFloat
else:
return max(self.sizeMin[0], length), self.sizeFloat[1]
def OnWindowPosChanged(self, msg):
if self.GetSafeHwnd()==0 or self.dialog is None:
return 0
lparam = msg[3]
""" LPARAM used with WM_WINDOWPOSCHANGED:
typedef struct {
HWND hwnd;
HWND hwndInsertAfter;
int x;
int y;
int cx;
int cy;
UINT flags;} WINDOWPOS;
"""
format = "PPiiiii"
bytes = win32ui.GetBytes( lparam, struct.calcsize(format) )
hwnd, hwndAfter, x, y, cx, cy, flags = struct.unpack(format, bytes)
if self.bInRecalcNC:
rc = self.GetClientRect()
self.dialog.MoveWindow(rc)
return 0
# Find on which side are we docked
nDockBarID = self.GetParent().GetDlgCtrlID()
# Return if dropped at same location
# no docking side change and no size change
if (nDockBarID == self.nDockBarID) and \
(flags & win32con.SWP_NOSIZE) and \
((self._obj_.dwStyle & afxres.CBRS_BORDER_ANY) != afxres.CBRS_BORDER_ANY):
return
self.nDockBarID = nDockBarID
# Force recalc the non-client area
self.bInRecalcNC = 1
try:
swpflags = win32con.SWP_NOSIZE | win32con.SWP_NOMOVE | win32con.SWP_NOZORDER | win32con.SWP_FRAMECHANGED
self.SetWindowPos(0, (0,0,0,0), swpflags)
finally:
self.bInRecalcNC = 0
return 0
# This is a virtual and not a message hook.
def OnSetCursor(self, window, nHitTest, wMouseMsg):
if nHitTest != win32con.HTSIZE or self.bTracking:
return self._obj_.OnSetCursor(window, nHitTest, wMouseMsg)
if self.IsHorz():
win32api.SetCursor(win32api.LoadCursor(0, win32con.IDC_SIZENS))
else:
win32api.SetCursor(win32api.LoadCursor(0, win32con.IDC_SIZEWE))
return 1
# Mouse Handling
def OnLButtonUp(self, msg):
if not self.bTracking:
return 1 # pass it on.
self.StopTracking(1)
return 0 # Dont pass on
def OnLButtonDown(self, msg):
# UINT nFlags, CPoint point)
# only start dragging if clicked in "void" space
if self.dockBar is not None:
# start the drag
pt = msg[5]
pt = self.ClientToScreen(pt)
self.dockContext.StartDrag(pt)
return 0
return 1
def OnNcLButtonDown(self, msg):
if self.bTracking: return 0
nHitTest = wparam = msg[2]
pt = msg[5]
if nHitTest==win32con.HTSYSMENU and not self.IsFloating():
self.GetDockingFrame().ShowControlBar(self, 0, 0)
elif nHitTest == win32con.HTMINBUTTON and not self.IsFloating():
self.dockContext.ToggleDocking()
elif nHitTest == win32con.HTCAPTION and not self.IsFloating() and self.dockBar is not None:
self.dockContext.StartDrag(pt)
elif nHitTest == win32con.HTSIZE and not self.IsFloating():
self.StartTracking()
else:
return 1
return 0
def OnLButtonDblClk(self, msg):
# only toggle docking if clicked in "void" space
if self.dockBar is not None:
# toggle docking
self.dockContext.ToggleDocking()
return 0
return 1
def OnNcLButtonDblClk(self, msg):
nHitTest = wparam = msg[2]
# UINT nHitTest, CPoint point)
if self.dockBar is not None and nHitTest == win32con.HTCAPTION:
# toggle docking
self.dockContext.ToggleDocking()
return 0
return 1
def OnMouseMove(self, msg):
flags = wparam = msg[2]
lparam = msg[3]
if self.IsFloating() or not self.bTracking:
return 1
# Convert unsigned 16 bit to signed 32 bit.
x=win32api.LOWORD(lparam)
if x & 32768: x = x | -65536
y = win32api.HIWORD(lparam)
if y & 32768: y = y | -65536
pt = x, y
cpt = CenterPoint(self.rectTracker)
pt = self.ClientToWnd(pt)
if self.IsHorz():
if cpt[1] != pt[1]:
self.OnInvertTracker(self.rectTracker)
self.rectTracker = OffsetRect(self.rectTracker, (0, pt[1] - cpt[1]))
self.OnInvertTracker(self.rectTracker)
else:
if cpt[0] != pt[0]:
self.OnInvertTracker(self.rectTracker)
self.rectTracker = OffsetRect(self.rectTracker, (pt[0]-cpt[0], 0))
self.OnInvertTracker(self.rectTracker)
return 0 # Dont pass it on.
# def OnBarStyleChange(self, old, new):
def OnNcCalcSize(self, bCalcValid, size_info):
(rc0, rc1, rc2, pos) = size_info
self.rectBorder = self.GetWindowRect()
self.rectBorder = OffsetRect( self.rectBorder, (-self.rectBorder[0], -self.rectBorder[1]) )
dwBorderStyle = self._obj_.dwStyle | afxres.CBRS_BORDER_ANY
if self.nDockBarID==afxres.AFX_IDW_DOCKBAR_TOP:
dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_BOTTOM;
rc0.left = rc0.left + self.cxGripper
rc0.bottom = rc0.bottom-self.cxEdge
rc0.top = rc0.top + self.cxBorder
rc0.right = rc0.right - self.cxBorder
self.rectBorder = self.rectBorder[0], self.rectBorder[3]-self.cxEdge, self.rectBorder[2], self.rectBorder[3]
elif self.nDockBarID==afxres.AFX_IDW_DOCKBAR_BOTTOM:
dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_TOP
rc0.left = rc0.left + self.cxGripper
rc0.top = rc0.top + self.cxEdge
rc0.bottom = rc0.bottom - self.cxBorder
rc0.right = rc0.right - self.cxBorder
self.rectBorder = self.rectBorder[0], self.rectBorder[1], self.rectBorder[2], self.rectBorder[1]+self.cxEdge
elif self.nDockBarID==afxres.AFX_IDW_DOCKBAR_LEFT:
dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_RIGHT
rc0.right = rc0.right - self.cxEdge
rc0.left = rc0.left + self.cxBorder
rc0.bottom = rc0.bottom - self.cxBorder
rc0.top = rc0.top + self.cxGripper
self.rectBorder = self.rectBorder[2] - self.cxEdge, self.rectBorder[1], self.rectBorder[2], self.rectBorder[3]
elif self.nDockBarID==afxres.AFX_IDW_DOCKBAR_RIGHT:
dwBorderStyle = dwBorderStyle & ~afxres.CBRS_BORDER_LEFT
rc0.left = rc0.left + self.cxEdge
rc0.right = rc0.right - self.cxBorder
rc0.bottom = rc0.bottom - self.cxBorder
rc0.top = rc0.top + self.cxGripper
self.rectBorder = self.rectBorder[0], self.rectBorder[1], self.rectBorder[0]+self.cxEdge, self.rectBorder[3]
else:
self.rectBorder = 0,0,0,0
self.SetBarStyle(dwBorderStyle)
return 0
def OnNcPaint(self, msg):
self.EraseNonClient()
dc = self.GetWindowDC()
ctl = win32api.GetSysColor(win32con.COLOR_BTNHIGHLIGHT)
cbr = win32api.GetSysColor(win32con.COLOR_BTNSHADOW)
dc.Draw3dRect(self.rectBorder, ctl, cbr)
self.DrawGripper(dc)
rect = self.GetClientRect()
self.InvalidateRect( rect, 1)
return 0
def OnNcHitTest(self, pt): # A virtual, not a hooked message.
if self.IsFloating():
return 1
ptOrig = pt
rect = self.GetWindowRect()
pt = pt[0] - rect[0], pt[1] - rect[1]
if PtInRect(self.rectClose, pt):
return win32con.HTSYSMENU
elif PtInRect(self.rectUndock, pt):
return win32con.HTMINBUTTON
elif PtInRect(self.rectGripper, pt):
return win32con.HTCAPTION
elif PtInRect(self.rectBorder, pt):
return win32con.HTSIZE
else:
return self._obj_.OnNcHitTest(ptOrig)
def StartTracking(self):
self.SetCapture()
# make sure no updates are pending
self.RedrawWindow(None, None, win32con.RDW_ALLCHILDREN | win32con.RDW_UPDATENOW)
self.dockSite.LockWindowUpdate()
self.ptOld = CenterPoint(self.rectBorder)
self.bTracking = 1
self.rectTracker = self.rectBorder;
if not self.IsHorz():
l, t, r, b = self.rectTracker
b = b - 4
self.rectTracker = l, t, r, b
self.OnInvertTracker(self.rectTracker);
def OnCaptureChanged(self, msg):
hwnd = lparam = msg[3]
if self.bTracking and hwnd != self.GetSafeHwnd():
self.StopTracking(0) # cancel tracking
return 1
def StopTracking(self, bAccept):
self.OnInvertTracker(self.rectTracker)
self.dockSite.UnlockWindowUpdate()
self.bTracking = 0
self.ReleaseCapture()
if not bAccept: return
rcc = self.dockSite.GetWindowRect()
if self.IsHorz():
newsize = self.sizeHorz[1]
maxsize = newsize + (rcc[3]-rcc[1])
minsize = self.sizeMin[1]
else:
newsize = self.sizeVert[0]
maxsize = newsize + (rcc[2]-rcc[0])
minsize = self.sizeMin[0]
pt = CenterPoint(self.rectTracker)
if self.nDockBarID== afxres.AFX_IDW_DOCKBAR_TOP:
newsize = newsize + (pt[1] - self.ptOld[1])
elif self.nDockBarID== afxres.AFX_IDW_DOCKBAR_BOTTOM:
newsize = newsize + (- pt[1] + self.ptOld[1])
elif self.nDockBarID== afxres.AFX_IDW_DOCKBAR_LEFT:
newsize = newsize + (pt[0] - self.ptOld[0])
elif self.nDockBarID== afxres.AFX_IDW_DOCKBAR_RIGHT:
newsize = newsize + (- pt[0] + self.ptOld[0])
newsize = max(minsize, min(maxsize, newsize))
if self.IsHorz():
self.sizeHorz = self.sizeHorz[0], newsize
else:
self.sizeVert = newsize, self.sizeVert[1]
self.dockSite.RecalcLayout()
return 0
def OnInvertTracker(self, rect):
assert rect[2]-rect[0]>0 and rect[3]-rect[1]>0, "rect is empty"
assert self.bTracking
rcc = self.GetWindowRect()
rcf = self.dockSite.GetWindowRect()
rect = OffsetRect(rect, (rcc[0] - rcf[0], rcc[1] - rcf[1]))
rect = DeflateRect(rect, (1, 1));
flags = win32con.DCX_WINDOW|win32con.DCX_CACHE|win32con.DCX_LOCKWINDOWUPDATE
dc = self.dockSite.GetDCEx(None, flags)
try:
brush = win32ui.GetHalftoneBrush()
oldBrush = dc.SelectObject(brush)
dc.PatBlt((rect[0], rect[1]), (rect[2]-rect[0], rect[3]-rect[1]), win32con.PATINVERT)
dc.SelectObject(oldBrush)
finally:
self.dockSite.ReleaseDC(dc)
def IsHorz(self):
return self.nDockBarID == afxres.AFX_IDW_DOCKBAR_TOP or \
self.nDockBarID == afxres.AFX_IDW_DOCKBAR_BOTTOM
def ClientToWnd(self, pt):
x, y=pt
if self.nDockBarID == afxres.AFX_IDW_DOCKBAR_BOTTOM:
y = y + self.cxEdge
elif self.nDockBarID == afxres.AFX_IDW_DOCKBAR_RIGHT:
x = x + self.cxEdge
return x,y
def DrawGripper(self, dc):
# no gripper if floating
if self._obj_.dwStyle & afxres.CBRS_FLOATING:
return
# -==HACK==-
# in order to calculate the client area properly after docking,
# the client area must be recalculated twice (I have no idea why)
self.dockSite.RecalcLayout()
# -==END HACK==-
gripper = self.GetWindowRect()
gripper = self.ScreenToClient( gripper )
gripper = OffsetRect( gripper, (-gripper[0], -gripper[1]) )
gl, gt, gr, gb = gripper
if self._obj_.dwStyle & afxres.CBRS_ORIENT_HORZ:
# gripper at left
self.rectGripper = gl, gt + 40, gl+20, gb
# draw close box
self.rectClose = gl+7, gt + 10, gl+19, gt+22
dc.DrawFrameControl(self.rectClose, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONCLOSE)
# draw docking toggle box
self.rectUndock = OffsetRect(self.rectClose, (0,13))
dc.DrawFrameControl(self.rectUndock, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONMAX);
gt = gt + 38
gb = gb - 10
gl = gl + 10
gr = gl + 3
gripper = gl, gt, gr, gb
dc.Draw3dRect( gripper, clrBtnHilight, clrBtnShadow )
dc.Draw3dRect( OffsetRect(gripper, (4,0)), clrBtnHilight, clrBtnShadow )
else:
# gripper at top
self.rectGripper = gl, gt, gr-40, gt+20
# draw close box
self.rectClose = gr-21, gt+7, gr-10, gt+18
dc.DrawFrameControl(self.rectClose, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONCLOSE)
# draw docking toggle box
self.rectUndock = OffsetRect( self.rectClose, (-13,0) )
dc.DrawFrameControl(self.rectUndock, win32con.DFC_CAPTION, win32con.DFCS_CAPTIONMAX)
gr = gr - 38;
gl = gl + 10
gt = gt + 10
gb = gt + 3
gripper = gl, gt, gr, gb
dc.Draw3dRect( gripper, clrBtnHilight, clrBtnShadow )
dc.Draw3dRect( OffsetRect(gripper, (0,4) ), clrBtnHilight, clrBtnShadow )
def HookMessages(self):
self.HookMessage(self.OnLButtonUp, win32con.WM_LBUTTONUP)
self.HookMessage(self.OnLButtonDown, win32con.WM_LBUTTONDOWN)
self.HookMessage(self.OnLButtonDblClk, win32con.WM_LBUTTONDBLCLK)
self.HookMessage(self.OnNcLButtonDown, win32con.WM_NCLBUTTONDOWN)
self.HookMessage(self.OnNcLButtonDblClk, win32con.WM_NCLBUTTONDBLCLK)
self.HookMessage(self.OnMouseMove, win32con.WM_MOUSEMOVE)
self.HookMessage(self.OnNcPaint, win32con.WM_NCPAINT)
self.HookMessage(self.OnCaptureChanged, win32con.WM_CAPTURECHANGED)
self.HookMessage(self.OnWindowPosChanged, win32con.WM_WINDOWPOSCHANGED)
# self.HookMessage(self.OnSize, win32con.WM_SIZE)
def EditCreator(parent):
d = win32ui.CreateEdit()
es = win32con.WS_CHILD | win32con.WS_VISIBLE | win32con.WS_BORDER | win32con.ES_MULTILINE | win32con.ES_WANTRETURN
d.CreateWindow( es, (0,0,150,150), parent, 1000)
return d
def test():
import pywin.mfc.dialog
global bar
bar = DockingBar()
creator = EditCreator
bar.CreateWindow(win32ui.GetMainFrame(), creator, "Coolbar Demo",0xfffff)
# win32ui.GetMainFrame().ShowControlBar(bar, 1, 0)
bar.SetBarStyle( bar.GetBarStyle()|afxres.CBRS_TOOLTIPS|afxres.CBRS_FLYBY|afxres.CBRS_SIZE_DYNAMIC)
bar.EnableDocking(afxres.CBRS_ALIGN_ANY)
win32ui.GetMainFrame().DockControlBar(bar, afxres.AFX_IDW_DOCKBAR_BOTTOM)
if __name__=='__main__':
test()

Some files were not shown because too many files have changed in this diff Show more