Entries from November 2004 ↓

Article on Task Branching in CM Crossroads in Agile SCM Column

November’s article in CM Crossroads covers some task branching patterns in keeping with the theme of the issue on incremental integration.

Note the article I wrote on multiple release branching pattern with details for implementing it in Perforce.

As noted by my co-column writer, Steve Berczuk, the pattern Stable Receiving seems to add complexity. I would agree, and try and avoid it where possible. Like all these patterns, sometimes it is appropriate and solves a problem.

Word Automation in Python (for testing etc.)

I have been doing some development of an Office based COM plugin (Word, Excel etc), and have been wanted to do some unit testing of it for a long time. Given that the majority of the code is in VB, it doesn’t lend itself to good test harnesses.

I then realised that I might be able to do something in Python which has excellent COM interfaces. The main pre-requisite was a COM control to look for windows appearing etc for which I used the excellent AutoIt Control.

The thing that took a little investigation was the realisation that you often can’t drive menu options in Word very easily via keystrokes. I then realised that I could drive them by finding the menu controls and directly executing them.

Demo

The following script does a simple demo. Comments at end.

from win32com.client import Dispatch, GetActiveObject
import pythoncom
import threading

class MenuCommand(threading.Thread):
    def __init__(self, menu_name, option):
        threading.Thread.__init__(self)
        self.menu_name = menu_name
        self.option = option

    def run(self):
        pythoncom.CoInitialize()
        self.wd = GetActiveObject("Word.Application")
        self.wdapp = self.wd.Application
        self.menu = self.wdapp.CommandBars(self.menu_name)
        print self.menu.Name
        self.ctl = self.menu.Controls(self.option)
        print self.ctl.Caption
        if not self.ctl.Enabled:
            self.ctl.Enabled = True
        self.ctl.Execute()
        pythoncom.CoUninitialize()

auto = Dispatch('AutoItX3.Control')
# First we stop any running version of Word to avoid messing things up
try:
    wd = GetActiveObject("Word.Application")
    wd.Quit()
except:
    pass
wd = Dispatch('Word.Application')	# Create a Word OLE object
wd.Application.Documents.Open(r'C:\work\fred-new1.doc')

t = MenuCommand("Help", "&About Microsoft Office Word")
t.start()

title = 'About Microsoft Office Word'
print "waiting window active"
if auto.WinWaitActive(title, '', 5)
	print "window active"
	auto.WinActivate(title, '')
	auto.Send("{ENTER}")
	info = auto.ClipGet()
	print info
wd.Application.Quit()

Comments

Note that I execute the menu command in its own thread, since if not, the call to execute it will block synchronously and I then can’t check to see if the Window is there or not and click any buttons etc.

In my working version, I also have a similar utility class to open files and suchlike things.

The above has allowed to me to put quite a lot of testing around my app driven by fairly simple keystroke sending and copying things out via the clipboard to see if commands were successful or not.