pywinauto/sandbox/__DeadCodeRepository__.py
2006-01-06 22:58:01 +00:00

1703 lines
43 KiB
Python
Raw Blame History

# GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
# Free Software Foundation, Inc.,
# 59 Temple Place,
# Suite 330,
# Boston, MA 02111-1307 USA
# #----------------------------------------------------------------
# def GetContextMenu(self):
# rect = self.Rectangle
#
# # set the position of the context menu to be 2 pixels in from
# # the control edge
# pos = c_long ((rect.top+ 2 << 16) | (rect.left + 2))
#
# # get the top window before trying to bring up a context menu
# oldTopWin = FindWindow(0, 0)
#
# # send the message but time-out after 10 mili seconds
# res = DWORD()
# SendMessageTimeout (
# self.handle,
# WM_CONTEXTMENU,
# self.handle,
# pos,
# 0,
# 100, # time out in miliseconds
# byref(res)) # result
#
# # get the top window
# popMenuWin = FindWindow(0, 0)
#
# # if no context menu has opened try right clicking the control
## if oldTopWin == popMenuWin:
## SendMessageTimeout (
## self.handle,
## WM_RBUTTONDOWN,
## 0,
## pos,
## 0,
## 100, # time out in miliseconds
## byref(res)) # result
##
## SendMessageTimeout (
## self.handle,
## WM_RBUTTONUP,
## 2,
## pos,
## 0,
## 100, # time out in miliseconds
## byref(res)) # result
##
## # wait another .1 of a second to allow it to display
## import time
## time.sleep(.1)
##
## # get the top window
## popMenuWin = FindWindow(0, 0)
#
#
# # if we still haven't opened a popup menu
# if oldTopWin == popMenuWin:
# return
#
#
# # get the MenuBar info from the PopupWindow which will
# # give you the Menu Handle for the menu itself
# mbi = MENUBARINFO()
# mbi.cbSize = sizeof(MENUBARINFO)
# ret = GetMenuBarInfo(popMenuWin, OBJID_CLIENT, 0, byref(mbi))
#
# if ret:
# GetMenuItems(mbi.hMenu)
# self.properties["ContextMenu"] = GetMenuItems(mbi.hMenu)
#
#
# # make sure the popup goes away!
# self.handle.SendMessage (WM_CANCELMODE, 0, 0)
# SendMessage (popMenuWin, WM_CANCELMODE, 0, 0)
#
# # if it's still open - then close it.
# if IsWindowVisible(popMenuWin):
# SendMessage (popMenuWin, WM_CLOSE, 0, 0)
# #SendMessage (popMenuWin, WM_DESTROY, 0, 0)
# #SendMessage (popMenuWin, WM_NCDESTROY , 0, 0)
##====================================================================
#def RemoveNonCurrentTabControls(dialog, childWindows):
#
# # find out if there is a tab control and get it if there is one
# tab = None
# for child in childWindows:
# if child.Class == "SysTabControl32":
# tab = child
# break
#
#
# # make a copy of childWindows
# firstTabChildren = list(childWindows)
# if tab:
#
# firstTabHandle = 0
#
# # get the parent of the tab control
# tabParent = GetParent(tab.handle)
#
# # find the control with that hwnd
# tabParent = [c for c in childWindows if \
# c.handle == tabParent][0]
#
# # get the index of the parent
# parentIdx = childWindows.index(tabParent) + 1
#
# passedFirstTab = False
# for child in childWindows[parentIdx:]:
#
# # if the current control is a dialog
# if child.Class == "#32770":
#
# # if this is the first tab
# if not passedFirstTab:
# # then just skip it
# passedFirstTab = True
# firstTabHandle = child.handle
# else:
# # Ok so this is NOT the first tab
# # remove the dialog control itself
# try:
# firstTabChildren.remove(child)
# print "Removing(a): ", child.IsVisible, IsWindowChildOf(firstTabHandle, child.handle)
# except ValueError:
# pass
#
# # then remove all the children of that dialog
# for x in GetChildWindows(child.handle):
# try:
# firstTabChildren.remove(x)
# print "Removing(b): ", child.IsVisible, IsWindowChildOf(firstTabHandle, x)
# except ValueError:
# pass
#
#
# return firstTabChildren
##====================================================================
#class Window(object):
# #----------------------------------------------------------------
# def __init__(self, hwndOrProps):
#
# self.ref = None
#
# # if the argument passed in is a Handle
# if isinstance(hwndOrProps, HwndWrapper):
#
# # wrap the handle
# self.handle = hwndOrProps
#
# # Get the properties from this handle
# self.properties = self.handle.GetProperties()
#
# else:
# self.properties = XMLHelpers.ControlFromXML(hwndOrProps)
#
#
# #----------------------------------------------------------------
# def __getattr__(self, name):
# if name in self.properties:
# return self.properties[name]
# else:
# raise AttributeError("'%s' has no attribute '%s'"% \
# (self.__class__.__name__, name))
#
# #----------------------------------------------------------------
# def GetTitle(self):
# return self.Titles[0]
# Title = property(GetTitle)
#
# #----------------------------------------------------------------
# def GetRectangle(self):
# return self.Rectangles[0]
# Rectangle = property(GetRectangle)
#
# #----------------------------------------------------------------
# def GetFont(self):
# return self.Fonts[0]
#
# #----------------------------------------------------------------
# def SetFont(self, font):
# self.Fonts[0] = font
#
# Font = property(GetFont, SetFont)
#
# #----------------------------------------------------------------
# def Parent(self):
# # do a preliminary construction to a Window
# parent = self.handle.Parent()
#
# # reconstruct it to the correct type
# return WindowClassRegistry().GetClass(parent.Class())(parent.handle)#.hwnd)
#
# #----------------------------------------------------------------
# def Style(self, flag = None):
# style = self.properties['Style']
# if flag:
# return style & flag == flag
# else:
# return style
#
# #----------------------------------------------------------------
# def ExStyle(self, flag = None):
# exstyle = self.properties['ExStyle']
# if flag:
# return exstyle & flag == flag
# else:
# return exstyle
#
# #----------------------------------------------------------------
# def __cmp__(self, other):
# return cmp(self.handle, other.handle)
#
# #----------------------------------------------------------------
# def __hash__(self):
# return hash(self.handle)
#
# #----------------------------------------------------------------
## def __str__(self):
## return "%8d %-15s\t'%s'" % (self.handle,
## "'%s'"% self.FriendlyClassName,
## self.Title)
#
#
##====================================================================
#class DialogWindow(Window):
# #----------------------------------------------------------------
# def __init__(self, hwndOrXML):
#
# self.children = []
#
# # if the argument passed in is a window hanle
# if isinstance(hwndOrXML, (int, long)):
# # read the properties for the dialog itself
# # Get the dialog Rectangle first - to get the control offset
#
# if not IsWindow(hwndOrXML):
# raise "The window handle passed is not valid"
#
# Window.__init__(self, hwndOrXML)
#
#
# else:
# dialogElemReached = False
# for ctrlElem in hwndOrXML.findall("CONTROL"):
#
# # if this is the first time through the dialog
# if not dialogElemReached:
# # initialise the Dialog itself
# Window.__init__(self, ctrlElem)
# dialogElemReached = True
#
# # otherwise contruct each control normally
# else:
# # get the class for the control with that window class
# Klass = WindowClassRegistry().GetClass(ctrlElem.attrib["Class"])
#
# # construct the object and append it
# self.children.append(Klass(ctrlElem))
#
# self.children.insert(0, self)
#
#
# #----------------------------------------------------------------
# def AllControls(self):
# return self.children
#
#
#
# #----------------------------------------------------------------
# def AddReference(self, ref):
#
#
# #print "x"*20, ref.AllControls()
# if len(self.AllControls()) != len(ref.AllControls()):
# print len(self.AllControls()), len(ref.AllControls())
# raise "Numbers of controls on ref. dialog does not match Loc. dialog"
#
#
# allIDsMatched = True
# allClassesMatched = True
# for idx, ctrl in enumerate(self.AllControls()):
# refCtrl = ref.AllControls()[idx]
# ctrl.ref = refCtrl
#
# if ctrl.ControlID != refCtrl.ControlID:
# allIDsMatched = False
#
# if ctrl.Class != refCtrl.Class:
# allClassesMatched = False
#
# toRet = 1
#
# allIDsSameFlag = 2
# allClassesSameFlag = 4
#
# if allIDsMatched:
# toRet += allIDsSameFlag
#
# if allClassesMatched:
# toRet += allClassesSameFlag
#
# return toRet
##====================================================================
#def DefaultWindowHwndReader(hwnd, dialogRect):
#
# ctrl = HwndWrapper(hwnd)
#
# return ctrl.GetProperties()
#
# if dialogRect:
# # offset it's rect depending on it's parents
# rect.left -= dialogRect.left
# rect.top -= dialogRect.top
# rect.right -= dialogRect.left
# rect.bottom -= dialogRect.top
##====================================================================
#def GetClass(hwnd):
# # get the className
# className = (c_wchar * 257)()
# GetClassName (hwnd, byref(className), 256)
# return className.value
#
#
##====================================================================
#def GetTitle(hwnd):
# # get the title
# bufferSize = SendMessage (hwnd, WM_GETTEXTLENGTH, 0, 0)
# title = (c_wchar * bufferSize)()
#
# if bufferSize:
# bufferSize += 1
# SendMessage (hwnd, WM_GETTEXT, bufferSize, title)
#
#
# return title.value
#
#
##====================================================================
#def GetChildWindows(dialog):
#
# # this will be filled in the callback function
# childWindows = []
#
# # callback function for EnumChildWindows
# def enumChildProc(hWnd, LPARAM):
# win = Window(hWnd)
#
# # construct an instance of the appropriate type
# win = WindowClassRegistry().GetClass(win.Class)(hWnd)
#
# # append it to our list
# childWindows.append(win)
#
# # return true to keep going
# return True
#
#
# # define the child proc type
# EnumChildProc = WINFUNCTYPE(c_int, HWND, LPARAM)
# proc = EnumChildProc(enumChildProc)
#
# # loop over all the children (callback called for each)
# EnumChildWindows(dialog.hwnd, proc, 0)
#
# return childWindows
#
##====================================================================
#def IsWindowChildOf(parent, child):
## try:
## parentHwnd = parent.handle
## except:
## parentHwnd = parent
#
# childHwnd = child
#
# while True:
# curParentTest = GetParent(childHwnd)
#
#
# # the current parent matches
# if curParentTest == parentHwnd:
# return True
#
# # we reached the very top of the heirarchy so no more parents
# if curParentTest == 0:
# return False
#
# # the next child is the current parent
# childHwnd = curParentTest
#
# =====================================================
# DEAD XML STUFF CODE
# =====================================================
#
# props['ClientRect'] = ParseRect(ctrl.find("CLIENTRECT"))
#
# props['Rectangle'] = ParseRect(ctrl.find("RECTANGLE"))
#
# props['Font'] = ParseLogFont(ctrl.find("FONT"))
#
# props['Titles'] = ParseTitles(ctrl.find("TITLES"))
#
# for key, item in ctrl.attrib.items():
# props[key] = item
##-----------------------------------------------------------------------------
#def StructToXML(struct, structElem):
# "Convert a ctypes Structure to an ElementTree"
#
# for propName in struct._fields_:
# propName = propName[0]
# itemVal = getattr(struct, propName)
#
# # convert number to string
# if isinstance(itemVal, (int, long)):
# propName += "_LONG"
# itemVal = unicode(itemVal)
#
# structElem.set(propName, EscapeSpecials(itemVal))
#
#
#
#
##====================================================================
#def XMLToMenuItems(element):
# items = []
#
# for item in element:
# itemProp = {}
#
# itemProp["ID"] = int(item.attrib["ID_LONG"])
# itemProp["State"] = int(item.attrib["State_LONG"])
# itemProp["Type"] = int(item.attrib["Type_LONG"])
# itemProp["Text"] = item.attrib["Text"]
#
# #print itemProp
# subMenu = item.find("MENUITEMS")
# if subMenu:
# itemProp["MenuItems"] = XMLToMenuItems(subMenu)
#
# items.append(itemProp)
# return items
#
#
##====================================================================
#def ListToXML(listItems, itemName, element):
#
# for i, string in enumerate(listItems):
#
# element.set("%s%05d"%(itemName, i), EscapeSpecials(string))
#
#
#
##====================================================================
#def XMLToList(element):
# items = []
# for subItem in element:
# items.append(PropFromXML(subItem))
#
##====================================================================
#def PropFromXML(element):
#
# for propName in PropParsers:
# if element.tag == propName.upper():
#
# ToXMLFunc, FromXMLFunc = PropParsers[element.tag.upper()]
#
# return FromXMLFunc(element)
#
# raise "Unknown Element Type : %s"% element.tag
#
##====================================================================
#def PropToXML(parentElement, name, value, ):
# print "=" *20, name, value
#
# ToXMLFunc, FromXMLFunc = PropParsers[element.tag.upper()]
#
# return FromXMLFunc(element)
#
#
#
#
#PropParsers = {
# "Font" : (StructToXML, XMLToFont),
# "Rectangle" : (StructToXML, XMLToRect),
# "ClientRects" : (ListToXML, XMLToRect),
# "Titles" : (TitlesToXML, XMLToTitles),
# "Fonts" : (ListToXML, XMLToList),
# #"Rectangles" : (ListToXML, XMLToList),
# #"" : XMLToMenuItems,
# #"" : XMLToMenuItems,
#
#
#}
#
# USED TO BE NEEDED IN THE XML OUTPUT FUNCTION
# # format the output xml a little
# xml = open(fileName, "rb").read()
#
# import re
# tags = re.compile("""
# (
# <[^/>]+> # An opening tag
# )|
# (
# </[^>]+> # A closing tag
# )|
# (
# <[^>]+/> # an empty element
# )
#
# """, re.VERBOSE)
#
# f = open(fileName, "wb")
# indent = 0
# indentText = " "
# for x in tags.finditer(xml):
#
# # closing tag
# if x.group(2):
# indent -= 1
# f.write(indentText*indent + x.group(2) + "\r\n")
#
# # if the element may have attributes
# else:
# if x.group(1):
# text = x.group(1)
# if x.group(3):
# text = x.group(3)
#
# f.write(indentText*indent + text + "\r\n")
#
##
## Trying to indent the attributes each on a single line
## but it is more complicated then it first looks :-(
##
# items = text.split()
#
#
# f.write(indentText*indent + items[0] + "\r\n")
# indent += 1
# for i in items[1:]:
# f.write(indentText*indent + i + "\r\n")
#
# indent -= 1
#
# # opening tag
# if x.group(1):
# indent += 1
#
# f.close()
##====================================================================
## specializes XMLToStruct for Fonts
#def XMLToFont(element):
# font = LOGFONTW()
# #print element.attrib
# XMLToStruct(element, font)
#
# return font
#
##====================================================================
## specializes XMLToStruct for Rects
#def XMLToRect(element):
# rect = RECT()
#
# XMLToStruct(element, rect)
# return rect
#
##====================================================================
#def TitlesToXML(titles, titleElem):
# for i, string in enumerate(titles):
#
# titleElem.set("s%05d"%i, EscapeSpecials(string))
#
#
##====================================================================
# sys.exit()
#
# # SendText playing around!! - not required
# SetForegroundWindow(handle)
# SendText("here is some test text")
#
#
# # some SendText testing
# text = sys.argv[2]
# import os.path
# if os.path.exists(text):
# text = open(text, "rb").read().decode('utf-16')
#
# print `text`
#
# #SendText("--%s--"%text)
# for c in dialog.AllChildren():
# print "(%6d) %s - '%s'"% (c.handle,c.Class, c.Title)
# if c.Class == "Edit":
# #SetActiveWindow (c.handle)
# SetForegroundWindow(c.handle)
# #SetFocus(c.handle)
# #EnableWindow(c.handle, True)
# SendText("--%s--"%text)
#
#
#
#
# get all the windows involved for this control
#windows.extend(windows[0].Children())
#
#
# styles = {
# "WS_DISABLED" : 134217728, # Variable c_long
# "WS_BORDER" : 8388608, # Variable c_long
# "WS_TABSTOP" : 65536, # Variable c_long << adds min, max, buttons
# "WS_MINIMIZE" : 536870912, # Variable c_long
# "WS_DLGFRAME" : 4194304, # Variable c_long
# "WS_VISIBLE" : 268435456, # Variable c_long
# "WS_OVERLAPPED" : 0, # Variable c_long
# "WS_CHILD" : 1073741824, # Variable c_long
# "WS_CAPTION" : 12582912, # Variable c_long
# "WS_POPUPWINDOW" : 2156396544L, # Variable c_ulong
# "WS_HSCROLL" : 1048576, # Variable c_long
# "WS_THICKFRAME" : 262144, # Variable c_long << takes about 2 pixes off length
# #"WS_SIZEBOX" : WS_THICKFRAME, # alias
# "WS_OVERLAPPEDWINDOW" : 13565952, # Variable c_long << turns off sysmenu!
# #"WS_TILEDWINDOW" : WS_OVERLAPPEDWINDOW, # alias
# "WS_GROUP" : 131072, # Variable c_long << adds both minimize and maximize boxes
# "WS_VSCROLL" : 2097152, # Variable c_long
# "WS_MAXIMIZEBOX" : 65536, # Variable c_long << adds both minimize and maximize boxes
# "WS_MAXIMIZE" : 16777216, # Variable c_long
# "WS_SYSMENU" : 524288, # Variable c_long << adds/removes close box
# "WS_POPUP" : 2147483648L, # Variable c_ulong
# "WS_MINIMIZEBOX" : 131072, # Variable c_long << adds both minimize and maximize boxes
# "WS_CLIPCHILDREN" : 33554432, # Variable c_long
# #"WS_ICONIC" : WS_MINIMIZE, # alias
# "WS_CLIPSIBLINGS" : 67108864, # Variable c_long
# #"WS_TILED" : WS_OVERLAPPED, # alias
# "WS_CHILDWINDOW" : 1073741824, # Variable c_long
#
# }
#
# exstyles = {
# "WS_EX_TOOLWINDOW" : 128, # Variable c_long << small font
# "WS_EX_MDICHILD" : 64, # Variable c_long
# "WS_EX_WINDOWEDGE" : 256, # Variable c_long
# "WS_EX_RIGHT" : 4096, # Variable c_long
# "WS_EX_NOPARENTNOTIFY" : 4, # Variable c_long
# "WS_EX_ACCEPTFILES" : 16, # Variable c_long
# "WS_EX_LEFTSCROLLBAR" : 16384, # Variable c_long
# "WS_EX_OVERLAPPEDWINDOW" : 768, # Variable c_long
# "WS_EX_DLGMODALFRAME" : 1, # Variable c_long << adds Icon
# "WS_EX_TRANSPARENT" : 32, # Variable c_long
# "WS_EX_STATICEDGE" : 131072, # Variable c_long
# "WS_EX_TOPMOST" : 8, # Variable c_long
# "WS_EX_LTRREADING" : 0, # Variable c_long
# "WS_EX_RIGHTSCROLLBAR" : 0, # Variable c_long
# "WS_EX_APPWINDOW" : 262144, # Variable c_long
# "WS_EX_CONTROLPARENT" : 65536, # Variable c_long
# "WS_EX_LEFT" : 0, # Variable c_long
# "WS_EX_PALETTEWINDOW" : 392, # Variable c_long << small font
# "WS_EX_CONTEXTHELP" : 1024, # Variable c_long << adds a CH button
# "WS_EX_CLIENTEDGE" : 512, # Variable c_long
# "WS_EX_RTLREADING" : 8192, # Variable c_long
# }
#
#
#
# for s in styles:
# if dialog.Style(styles[s]):
# print "%30s\t0x%-8x"% (s, styles[s])
#
# print "-"*20
# for s in exstyles:
# if dialog.ExStyle(exstyles[s]):
# print "%30s\t0x%-8x"% (s, exstyles[s])
# print dialog.Font().lfHeight, dialog.Font().lfWidth, dialog.Font().lfFaceName
# print "STyle 0x%08x EXStyle 0x%08x" % (dialog.Style(), dialog.ExStyle())
# print "please type the style to set/unset"
# typed = ""
# while typed.lower() != "x":
# typed = raw_input()
#
# if typed in exstyles:
# old = dlg.ExStyle()
# new = dlg.ExStyle() ^ exstyles[typed]
# SetWindowLong(dlg.handle, GWL_EXSTYLE, c_long(new))
# print "%0x %0x %0x"% (old, new, exstyles[typed])
# SetWindowLong(dlg.handle, GWL_STYLE, dlg.Style() ^268435456)
# SetWindowLong(dlg.handle, GWL_STYLE, dlg.Style() ^268435456)
# SendMessage(dlg.handle, WM_PAINT, 0, 0)
# SetForegroundWindow(dlg.handle)
#
#
# if typed in styles:
# old = dlg.Style()
# new = dlg.Style() ^ styles[typed]
# SetWindowLong(dlg.handle, GWL_STYLE, c_long(new))
# print "%0x %0x %0x"% (old, new, styles[typed])
# SetWindowLong(dlg.handle, GWL_STYLE, dlg.Style() ^268435456)
# SetWindowLong(dlg.handle, GWL_STYLE, dlg.Style() ^268435456)
# SendMessage(dlg.handle, WM_PAINT, 0, 0)
# SetForegroundWindow(dlg.handle)
#dialog = ParentWindow(dlg.handle)
#
#
##====================================================================
#from SendInput import TypeKeys, PressKey, LiftKey, TypeKey, VK_MENU, \
# VK_SHIFT, VK_BACK, VK_DOWN, VK_LEFT
#
#
#def SendText(text):
#
# # write the text passed in
# TypeKeys(text)
#
# # press shift
# PressKey(VK_SHIFT)
# # lowercase 'a'
# #import pm
# #pm.set_trace()
# toType = (VK_LEFT,) * 13
# TypeKeys(toType)
#
# # unpress shift
# LiftKey(VK_SHIFT)
#
#
# PressKey(VK_MENU)
# TypeKey('F')
# LiftKey(VK_MENU)
#
#
# TypeKeys((VK_DOWN,)*4)
#
#
#====================================================================
#class Menuitem(object):
# def __init__(self, item):
# for attr in item.keys():
# self.__dict__["_%s_"%attr] = item[attr]
#
# self.__dict__.setdefault("_MenuItems_", [])
#
# def __getattr__(self, key):
# return getattr(MenuWrapper(self._MenuItems_), key)
#
#
#
##====================================================================
#class MenuWrapper(object):
# def __init__(self, items):
# # clean up the existing menuItem attributes
# # and set them
# self.__items = items
#
# self.__texts = [item['Text'] for item in self.__items]
#
#
# def __getattr__(self, key):
#
# item = find_best_match(key, self._texts_, self.__items)
#
# return item
#
#
##====================================================================
#def MenuSelect(ctrl, menupath, menu_items):
#
# id = FindMenu(menupath, menu_items)
#
# #print ctrl['MenuItems']
# APIFuncs.PostMessage(ctrl.handle, win32defines.WM_COMMAND, id, 0)
#
#
#
#
##====================================================================
#class Dialog2(controls.HwndWrapper.HwndWrapper):
# #----------------------------------------------------------------
# def __init__(self, title = None, class_ = None, timeout = 1, handle = None):
#
# if not handle:
#
# handle = FindDialog(title, testClass = class_)
# waited = 0
# while not handle and waited <= timeout:
# time.sleep(.1)
# handle = FindDialog(title, testClass = class_)
# waited += .1
#
# if not handle:
# raise WindowNotFound("Window not found")
#
# super(Dialog2, self).__init__(handle)
#
# self.controls = [self, ]
# self.controls.extend(self.Children)
#
# controlactions.add_actions(self)
#
# #self._build_control_id_map()
#
# self.ctrl_texts = [ctrl.Text or ctrl.FriendlyClassName for ctrl in self.controls]
#
# # we need to handle controls where the default text is not that interesting e.g.
# # edit boxes
#
#
# #----------------------------------------------------------------
# def __getattr__(self, to_find):
#
# waited = 0
# while waited <= 1:
# try:
# #if "Dialog" in self.ctrl_texts:
# # print "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"
# # print self.ctrl_texts, self.Class, self.Children
# ctrl = find_best_match(to_find, self.ctrl_texts, self.controls)
# return controlactions.add_actions(ctrl)
# except WindowNotFound:
# waited += .1
#
# print self
# print "failed to find %s in %s" % (to_find, self.ctrl_texts)
#
# raise
#
#
# #----------------------------------------------------------------
# def MenuSelect(self, path):
#
#
# item_id = FindMenu(self.MenuItems, path)
# #menu_items = MenuWrapper(self.MenuItems)
#
# #item_id = FindMenu(menu_items, path)
#
# #print ctrl['MenuItems']
# self.PostMessage(win32defines.WM_COMMAND, item_id)
#
#
#
#
##====================================================================
#def TestNotepad():
#
# try:
# notepad = Dialog2(title = "^.*Notepad.*", class_ = "Notepad")
# except WindowNotFound:
# os.system("start notepad")
# time.sleep(.1)
# notepad = Dialog2(title = "^.*Notepad.*", class_ = "Notepad")
#
#
# #print notepad.handle
#
## notepad.SendKeys("testing")
## notepad.edit.SendKeys("Here is so\\nme t<><74>ext%H")
## notepad.SendKeys("{DOWN}{ENTER}")
## #notepad.SendKeys("a")
##
## # need to get active window!!
## notepad.SendKeys("{ESC}")
## notepad.SendKeys("%E")
# if "1" in sys.argv:
# # Select that menu item
# notepad.MenuSelect("File->Page Setup")
#
# # find the dialog
# page_setup = Dialog2(title = "Page Setup")
#
# edit = page_setup.Edit1
# edit.TypeKeys("{HOME}+{END}{BKSP}23")
#
#
# page_setup.Combo1.Select(5)
# time.sleep(1)
#
# page_setup.Combo1.Select("Tabloid")
# time.sleep(1)
#
# # click the printer button
# page_setup.Printer.Click()
#
# dlg = Dialog2("^Page Setup").Properties.Click()
#
# Dialog2(".*Document Properties").Advanced.Click()
#
# Dialog2(".*Advanced Options").Cancel.Click()
#
# Dialog2(".*Document Properties").cancel.Click()
#
# Dialog2("^Page Setup").cancel.Click()
#
# # dialog doesn't go away because 23 that we typed is 'wrong'
# Dialog2(title = "^Page Setup").ok.Click()
#
# # this is teh message box
# Dialog2(title = "^Page Setup").ok.Click()
#
# # dialog doesn't go away because 23 that we typed is 'wrong'
# Dialog2(title = "^Page Setup").cancel.Click()
#
# if "2" in sys.argv:
# # Select that menu item
# notepad.MenuSelect("Format->Font")
#
# font_dlg = Dialog2(title = "^Font$")
#
# font_dlg.combobox2.Select(3)
# time.sleep(2)
#
# Dialog2(title = "^Font$").OK.Click()
#
# if "3" in sys.argv:
# notepad.Edit1.Select(1,4)
# time.sleep(2)
#
# print notepad.edit1.SelectionIndices
#
# if "4" in sys.argv:
#
# raise "NotWorkingYet"
# edit = notepad.Edit1
# print edit.Rectangle
#
# edit.PressMouse(coords = (0,0))
# edit.MoveMouse(coords = (400, 400))
# edit.ReleaseMouse(coords = (400,400))
#
# if "5" in sys.argv:
#
# edit = notepad.Edit1
#
# edit.DoubleClick(coords = (1290,1290))
#
#
#
##====================================================================
#def test():
#
# # some some normal dailogs
# if 1:
# testStrings = ["Combo", "Combo2", "ComboBox", "blah blah", "test" ,"hex" ,"matchwhole" ,"regularExp" ,"wrapsearch" ,"wrap" ,"inalldocs" ,"extend_sel" ,"Find next" ,"markall" ,"up" ,"down" ,"direct" ,"conds"]
# else:
# testStrings = ["blah blah", "first", "from", "from0", "from001", "from2", "from0000003", "from3", "insensitive", "delduplicate", "charCodeOrder"]
#
#
# item_texts = [ctrl.Text or ctrl.FriendlyClassName for ctrl in ctrls]
#
# missedMatches = []
# for test in testStrings:
#
# try:
# ctrl = find_best_match(test, item_texts, ctrls)
# print "%15s %15s %-20s %s"% (test, ctrl.FriendlyClassName, `ctrl.Text[:20]`, str(ctrl.Rectangle))
# except IndexError, e:
# missedMatches.append(test)
#
# if missedMatches:
# print "\nNo Matches for: " + ", ".join(missedMatches)
#
#
#
#if __name__ == "__main__":
# TestNotepad()
#print "\n\nMenuTesting"
#missedMatches = []
#try:
# print MenuWrapper(ctrls[0].MenuItems).File.PageSetup._Text_
#except IndexError, e:
# missedMatches.append(test)
#
#if missedMatches:
# print "\nNo Matches for: " + ", ".join(missedMatches)
#
#
#for ctrl in ctrls:
# print CtrlAccessName(ctrl)
#
# if ctrl.Class in ('ComboBox'):
#
#
# candidates = []
# # find controls that are to it's left
# for ctrl2 in ctrls:
# # if this ctrl has a top or bottom between
# # other ctrl top and bottom
#
# if \
# (((ctrl2.Rectangle.top >= ctrl.Rectangle.top and \
# ctrl2.Rectangle.top < ctrl.Rectangle.bottom) or \
# (ctrl2.Rectangle.bottom > ctrl.Rectangle.top and \
# ctrl2.Rectangle.bottom <= ctrl.Rectangle.bottom)) and\
# ctrl2.Rectangle.left < ctrl.Rectangle.left) \
# or \
# (((ctrl2.Rectangle.right >= ctrl.Rectangle.left and \
# ctrl2.Rectangle.right < ctrl.Rectangle.bottom) or \
# (ctrl2.Rectangle.bottom > ctrl.Rectangle.top and \
# ctrl2.Rectangle.bottom <= ctrl.Rectangle.bottom)) and\
# ctrl2.Rectangle.left < ctrl.Rectangle.left) \
# :
#
#
#
#
#
# candidates.append(ctrl2)
#
#
#
# #for candidate in cadidates:
# # print "%18s - 20%s" % (candidate.Class, "'%s'"%candidate.Title), CtrlAccessName(candidate)
#
#
#
# #if ctrl2.Rectangle.top >= ctrl.Rectangle.top <= ctrl2.Rectangle.bottom or \
# # ctrl2.Rectangle.bottom >= ctrl.Rectangle.top
#
#
# #if ctrl2.Rectangle.top
#
#
#
##import pprint
##pprint.pprint(ctrls)
#
# how should we read in the XML file
# NOT USING MS Components (requirement on machine)
# maybe using built in XML
# maybe using elementtree
# others?
from elementtree.ElementTree import Element, SubElement, ElementTree
import ctypes
from APIStructures import RECT, LOGFONTW
charEncodings = {
"\\n" : "\n",
"\\x12" : "\x12",
#"\\\\" : "\\",
}
#todo - make the dialog reading function not actually know about the
# types of each element (so that we can read the control properties
# without having to know each and every element type)
# probably need to store info on what type things are.
#-----------------------------------------------------------------------------
def AddElement(element, name, value):
# if it is a ctypes structure
if isinstance(value, ctypes.Structure):
# create an element for the structure
structElem = SubElement(element, name)
# iterate over the fields in the structure
for propName in value._fields_:
propName = propName[0]
itemVal = getattr(value, propName)
if isinstance(itemVal, (int, long)):
propName += "_LONG"
itemVal = unicode(itemVal)
structElem.set(propName, EscapeSpecials(itemVal))#.encode('utf8'))
elif isinstance(value, (list, tuple)):
# add the element to hold the values
#listElem = SubElement(element, name)
# remove the s at the end (if there)
name = name.rstrip('s')
for i, attrVal in enumerate(value):
AddElement(element, "%s_%05d"%(name, i), attrVal)
elif isinstance(value, dict):
dictElem = SubElement(element, name)
for n, val in value.items():
AddElement(dictElem, n, val)
else:
if isinstance(value, (int, long)):
name += "_LONG"
element.set(name, EscapeSpecials(value))#.encode('utf8', 'backslashreplace'))
#-----------------------------------------------------------------------------
def ConvertDialogToElement(dialog):
# build a tree structure
root = Element("DIALOG")
for ctrl in dialog.AllControls():
ctrlElem = SubElement(root, "CONTROL")
for name, value in ctrl.properties.items():
AddElement(ctrlElem, name, value)
return root
#-----------------------------------------------------------------------------
def WriteElementToFile(element, fileName):
# wrap it in an ElementTree instance, and save as XML
tree = ElementTree(element)
tree.write(fileName, encoding="utf-8")
# # format the output xml a little
# xml = open(fileName, "rb").read()
#
# import re
# tags = re.compile("""
# (
# <[^/>]+> # An opening tag
# )|
# (
# </[^>]+> # A closing tag
# )|
# (
# <[^>]+/> # an empty element
# )
#
# """, re.VERBOSE)
#
# f = open(fileName, "wb")
# indent = 0
# indentText = " "
# for x in tags.finditer(xml):
#
# # closing tag
# if x.group(2):
# indent -= 1
# f.write(indentText*indent + x.group(2) + "\r\n")
#
# # if the element may have attributes
# else:
# if x.group(1):
# text = x.group(1)
# if x.group(3):
# text = x.group(3)
#
# f.write(indentText*indent + text + "\r\n")
#
##
## Trying to indent the attributes each on a single line
## but it is more complicated then it first looks :-(
##
# items = text.split()
#
#
# f.write(indentText*indent + items[0] + "\r\n")
# indent += 1
# for i in items[1:]:
# f.write(indentText*indent + i + "\r\n")
#
# indent -= 1
#
# # opening tag
# if x.group(1):
# indent += 1
#
# f.close()
#-----------------------------------------------------------------------------
def EscapeSpecials(inStr):
"Ensure that some characters are escaped before writing to XML"
# make sure input is a unicode string or convert
inStr = unicode(inStr)
for (replacement, char) in charEncodings.items():
inStr = inStr.replace(char, replacement)
return inStr
#-----------------------------------------------------------------------------
def UnEscapeSpecials(inStr):
"Replace escaped characters with real character"
for (replacement, char) in charEncodings.items():
inStr = inStr.replace(replacement, char)
return unicode(inStr)
#-----------------------------------------------------------------------------
def StructToXML(struct, structElem):
for propName in struct._fields_:
propName = propName[0]
itemVal = getattr(struct, propName)
# convert number to string
if isinstance(itemVal, (int, long)):
propName += "_LONG"
itemVal = unicode(itemVal)
structElem.set(propName, EscapeSpecials(itemVal))#.encode('utf8'))
#-----------------------------------------------------------------------------
def XMLToStruct(element, struct):
# get the attribute and set them upper case
structAttribs = dict([(at.upper(), at) for at in dir(struct)])
for propName in element.attrib:
val = element.attrib[propName]
if propName.endswith("_LONG"):
val = long(val)
propName = propName[:-5]
else:
val = unicode(val)
# now we can have all upper case attribute name
# but structure name will not be upper case
if propName.upper() in structAttribs:
propName = structAttribs[propName.upper()]
setattr(struct, propName, val)
#====================================================================
# specializes XMLToStruct for Fonts
def XMLToFont(element):
font = LOGFONTW()
#print element.attrib
XMLToStruct(element, font)
return font
#====================================================================
# specializes XMLToStruct for Rects
def XMLToRect(element):
rect = RECT()
XMLToStruct(element, rect)
return rect
#====================================================================
def TitlesToXML(titles, titleElem):
for i, string in enumerate(titles):
titleElem.set("s%05d"%i, EscapeSpecials(string))
#====================================================================
def XMLToTitles(element):
# get all the attribute names
titleNames = element.attrib.keys()
# sort them to make sure we get them in the right order
titleNames.sort()
# build up the array
titles = []
for name in titleNames:
val = element.attrib[name]
val = val.replace('\\n', '\n')
val = val.replace('\\x12', '\x12')
val = val.replace('\\\\', '\\')
titles.append(unicode(val))
return titles
#====================================================================
def XMLToMenuItems(element):
items = []
for item in element:
itemProp = {}
itemProp["ID"] = int(item.attrib["ID_LONG"])
itemProp["State"] = int(item.attrib["State_LONG"])
itemProp["Type"] = int(item.attrib["Type_LONG"])
itemProp["Text"] = item.attrib["Text"]
#print itemProp
subMenu = item.find("MENUITEMS")
if subMenu:
itemProp["MenuItems"] = XMLToMenuItems(subMenu)
items.append(itemProp)
return items
#====================================================================
def ListToXML(listItems, itemName, element):
for i, string in enumerate(listItems):
element.set("%s%05d"%(itemName, i), EscapeSpecials(string))
#====================================================================
def XMLToList(element):
items = []
for subItem in element:
items.append(PropFromXML(subItem))
#====================================================================
def PropFromXML(element):
for propName in PropParsers:
if element.tag == propName.upper():
ToXMLFunc, FromXMLFunc = PropParsers[element.tag.upper()]
return FromXMLFunc(element)
raise "Unknown Element Type : %s"% element.tag
#====================================================================
def PropToXML(parentElement, name, value, ):
#print "=" *20, name, value
ToXMLFunc, FromXMLFunc = PropParsers[element.tag.upper()]
return FromXMLFunc(element)
import re
def GetAttributes(element):
# get all the attributes
for attribName, val in element.attrib.items():
# if it is 'Long' element convert it to an long
if attribName.endswith("_LONG"):
val = long(val)
attribName = attribName[:-5]
else:
# otherwise it is a string - make sure we get it as a unicode string
val = unicode(val)
# if the attributes are a list of itmes
if re.match(r".*_\d{5}", attribName)
# set the property
properties[attribName] = val
else:
properties[attribName] = val
#====================================================================
def ControlFromXML(controlElement):
properties = {}
# get all the attributes
for attribName in controlElement.attrib:
# get attribute value
val = controlElement.attrib[attribName]
#print "-" *20, attribName, val
# if it is 'Long' element convert it to an long
if attribName.endswith("_LONG"):
val = long(val)
attribName = attribName[:-5]
else:
# otherwise it is a string - make sure we get it as a unicode string
val = unicode(val)
# if the attributes are a list of itmes
if re.match(r".*_\d{5}", attribName)
# set the property
properties[attribName] = val
else:
properties[attribName] = val
for elem in controlElement:
propValue = PropFromXML(elem)
# if there was another element with this name
if propName in properties:
# Make sure it is a list
properties[propName] = list(properties[propName])
# add our element
properties[propName].append(propValue)
#print propName, properties[propName]
else:
# so we haven't already seen another prop with this name
# just add it
properties[propName] = propValue
return properties
PropParsers = {
"Font" : (StructToXML, XMLToFont),
"Rectangle" : (StructToXML, XMLToRect),
"ClientRects" : (ListToXML, XMLToRect),
"Titles" : (TitlesToXML, XMLToTitles),
"Fonts" : (ListToXML, XMLToList),
#"Rectangles" : (ListToXML, XMLToList),
#"" : XMLToMenuItems,
#"" : XMLToMenuItems,
}
if __name__ == "__main__":
import sys
from elementtree import ElementTree
parsed = ElementTree.parse(sys.argv[1])
props = {}
print dir(parsed)
for ctrl in parsed.findall("CONTROL"):
print ControlFromXML(ctrl)
sys.exit()
props['ClientRect'] = ParseRect(ctrl.find("CLIENTRECT"))
props['Rectangle'] = ParseRect(ctrl.find("RECTANGLE"))
props['Font'] = ParseLogFont(ctrl.find("FONT"))
props['Titles'] = ParseTitles(ctrl.find("TITLES"))
for key, item in ctrl.attrib.items():
props[key] = item
##====================================================================
#FROM FINDDIALOG
##====================================================================
#
#def FindWindow(
# start_window = None,
# match_title = None,
# match_class = None,
# toplevel_only = False,
# recurse_children = True,
# this_thread_only = None,
# )
#
# if start_window == None:
# start_window = GetDesktopWindow()
#
# if recurse_children:
# # get the 1st child of the start window
# win_to_test = GetWindow (start_window, GW_CHILD)
#
# wrapped = WrapHandle(win_to_test)
#
# if match_title:
# if re.match(match_title, wrapped.Text)
#
#
#totalWindowCount = 0
##====================================================================
#def FindDialog(titleToFind, caseSensitive = False, testClass = None, startWin = None):
# """Find a dialog based on the title
#
#
#Returns the dialog that has a title that matches the regular
#expression in titleToFind.
#If caseSensitive == True then it performs a case sensitive match
#If startWin == None then it starts searching from the desktop window
#otherwise it searches the child windows of the specified window."""
#
# if caseSensitive:
#
# flags = re.IGNORECASE
# else:
# flags = 0
#
# titleRe = re.compile(titleToFind, flags)
#
# # If the startWin is NULL then we are just starting and we
# # should start with the Desktop window and look from there
# if startWin == None:
# startWin = GetDesktopWindow()
#
# # get the 1st child of the start window
# winToTest = GetWindow (startWin, GW_CHILD)
#
# # Now Iterate through all the children of the startwindow
# # (ie ALL windows, dialogs, controls ) then if the HWND is a dialog
# # get the Title and compare it to what we are looking for
# # it makes a check first to make sure that the window has at
# # least 1 child window
# while winToTest:
# global totalWindowCount
# totalWindowCount += 1
#
# # get the Title of the Window and if the Title the same as
# # what we want if So then return it
# title = controls.WrapHandle(winToTest).Text
#
# # Check the title to see if it is the same as the title we
# # are looking for - if it is then return the handle
# found = titleRe.search(title)
# if found:
#
# if testClass:
# if testClass == controls.WrapHandle(winToTest).Class:
# return winToTest
# else:
# return winToTest
#
#
# # Now Check through the children of the present window
# # this is recursive through all the children of the window
# # It calls FindDialog with the title and the new window
# # this will keep going recursively until the window is found
# # or we reach the end of the children
# tempWin = FindDialog (titleToFind, caseSensitive, testClass, winToTest)
#
# if tempWin != None:
# return tempWin
#
# # So the last one wasnt it just continue with the next
# # which will be the next window at the present level
# winToTest = GetWindow (winToTest, GW_HWNDNEXT)
#
# # we have gotten to here so we didnt find the window
# # in the current depth of the tree return NULL to say
# # that we didnt get it and continue at the previous depth
# return None
#
#
#