1703 lines
43 KiB
Python
1703 lines
43 KiB
Python
# 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
|
||
#
|
||
#
|
||
# |