""" Class and functions to find the windowText and className for a given executable """ # Author : Tim Couper - tim@2wave.net # Date : 22 July 2004 # Version : 1.1 # Copyright : Copyright TAC Software Ltd, under Python-style licence. # Provided as-is, with no warranty. # Notes : Requires Python 2.3, win32all, ctypes & watsup package import os.path from watsup.winGuiAuto import findTopWindows,findControls,dumpWindow,\ dumpTopWindows from watsup.utils import dumpHwnd,tupleHwnd from watsup.launcher import AppThread,terminateApp from watsup.OrderedDict import OrderedDict from time import time,sleep from types import ListType THREAD_TIMEOUT_SECS=2.0 INDENT=2 #wstruct is of the form [hwnd,wclass,wtext] or # [hwnd,wclass,wtext,[winstruct] ##def printwstruct(wstruct): ## print 'printFormat had trouble with:\n%s' % str(wstruct[3]) ## import pprint ## print '------' ## pprint.pprint(wstruct) ## print '------' def printFormat(wstruct,indent=0): def printwstruct(wstruct): print 'printFormat had trouble with:\n%s' % str(wstruct[3]) import pprint print '------' pprint.pprint(wstruct) print '------' """wstruct is either a wintuple, or a recursive list of wintuples """ # type 1 if type(wstruct[1]) is not ListType: print '%s%s: %s' % (' '*indent,wstruct[2],wstruct[1]) if len(wstruct)>3 and wstruct[3]<>None: try: for item in wstruct[3]: printFormat(item,indent+INDENT) except: print_wstruct(wstruct) # type 2: else: for item in wstruct[1]: printFormat(item,indent+INDENT) class AppControls(object): def __init__(self,program,wantedText=None,wantedClass=None,selectionFunction=None,verbose=False): self.wantedText=wantedText self.wantedClass=wantedClass self.selectionFunction=selectionFunction self.verbose=verbose topHwnds,unwantedHwnds,self.appThread=findAppTopWindows(program,verbose=verbose) #should only be one, but you never know self.topHwnds=[] self.unwantedHwnds=unwantedHwnds def run(self): while self.appThread.isAlive(): results=findNewTopWindows(self.unwantedHwnds,self.verbose) if results: self.process(results) # update the list of topWindows and unwanted TopWindows def process(self,results): for hwnd in results: ctHwnds=findControls(hwnd) if ctHwnds: # we only add hwnd if there are controlHwnds # as there may be a form which exists # as an hwnd, but has not controls materialised yet self.unwantedHwnds.append(hwnd) self.write(hwnd) for ctHwnd in ctHwnds: self.unwantedHwnds.append(ctHwnd) def write(self,hwnd): h=tupleHwnd(hwnd) t=[h[0],h[1],h[2],dumpWindow(hwnd)] printFormat(t) def findNewTopWindows(unwantedHwnds=[],verbose=False): # returns a list of all top windows' hwnds we haven't # found yet htuples=dumpTopWindows() if verbose: print '..%d windows found (%d windows in unwanted)' % (len(htuples),len(unwantedHwnds)) results=[] for htuple in htuples: hwnd=htuple[0] if hwnd not in unwantedHwnds: if verbose: print '..adding %s' % dumpHwnd(hwnd) results.append(hwnd) return results def findAppTopWindows(program,verbose=False): """returns the hwnds for the program, along with the hwnds for the stuff that are to be ignored """ # first we run findTopWindows before launching the program; store the hwnds found # (note that it doesn't matter if an instance of the program IS running # as we'll start another one whose hwnds will be new) # run findTopWindows, and remove from the list any which are stored unwantedHwnds=findNewTopWindows() # list of topWindow hwnds that exist if verbose: print '..%d original window(s)' % len(unwantedHwnds) # run the program appThread=AppThread(program,verbose) appThread.start() # give the thread a chance to get going: results=[] t=time() while not results and ((time()-t)