
git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2069 fd906abe-77d9-0310-91a1-e0d9ade77398
152 lines
5.4 KiB
Python
152 lines
5.4 KiB
Python
""" 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)<THREAD_TIMEOUT_SECS):
|
|
sleep(0.2) # means that the thread hasn't launched; give it a chance
|
|
results=findNewTopWindows(unwantedHwnds,verbose)
|
|
|
|
if not results:
|
|
# stop the program
|
|
terminateApp()
|
|
raise Exception, 'Failed to find any new windows!'
|
|
|
|
if verbose:
|
|
print '..%d additional (new) non-trivial window(s)' % len(results)
|
|
|
|
if verbose:
|
|
for hwnd in results:
|
|
print '..%s: %s' % tupleHwnd(hwnd)[:2]
|
|
|
|
return results,unwantedHwnds,appThread
|
|
|
|
if __name__=='__main__':
|
|
pass
|