summaryrefslogtreecommitdiffstats
path: root/tools/site_compare/drivers/win32/windowing.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/site_compare/drivers/win32/windowing.py')
-rw-r--r--tools/site_compare/drivers/win32/windowing.py110
1 files changed, 55 insertions, 55 deletions
diff --git a/tools/site_compare/drivers/win32/windowing.py b/tools/site_compare/drivers/win32/windowing.py
index 5bc37f8..fe77c56 100644
--- a/tools/site_compare/drivers/win32/windowing.py
+++ b/tools/site_compare/drivers/win32/windowing.py
@@ -24,7 +24,7 @@ import win32process
def FindChildWindows(hwnd, path):
"""Find a set of windows through a path specification.
-
+
Args:
hwnd: Handle of the parent window
path: Path to the window to find. Has the following form:
@@ -32,12 +32,12 @@ def FindChildWindows(hwnd, path):
The slashes specify the "path" to the child window.
The text is the window class, a pipe (if present) is a title.
* is a wildcard and will find all child windows at that level
-
+
Returns:
A list of the windows that were found
"""
windows_to_check = [hwnd]
-
+
# The strategy will be to take windows_to_check and use it
# to find a list of windows that match the next specification
# in the path, then repeat with the list of found windows as the
@@ -45,7 +45,7 @@ def FindChildWindows(hwnd, path):
for segment in path.split("/"):
windows_found = []
check_values = segment.split("|")
-
+
# check_values is now a list with the first element being
# the window class, the second being the window caption.
# If the class is absent (or wildcarded) set it to None
@@ -53,7 +53,7 @@ def FindChildWindows(hwnd, path):
# If the window caption is also absent, force it to None as well
if len(check_values) == 1: check_values.append(None)
-
+
# Loop through the list of windows to check
for window_check in windows_to_check:
window_found = None
@@ -70,26 +70,26 @@ def FindChildWindows(hwnd, path):
window_found = 0
else:
raise e
-
+
# If FindWindowEx struck gold, add to our list of windows found
if window_found: windows_found.append(window_found)
-
+
# The windows we found become the windows to check for the next segment
windows_to_check = windows_found
-
+
return windows_found
def FindChildWindow(hwnd, path):
"""Find a window through a path specification.
-
+
This method is a simple wrapper for FindChildWindows() for the
case (the majority case) where you expect to find a single window
-
+
Args:
hwnd: Handle of the parent window
path: Path to the window to find. See FindChildWindows()
-
+
Returns:
The window that was found
"""
@@ -98,36 +98,36 @@ def FindChildWindow(hwnd, path):
def ScrapeWindow(hwnd, rect=None):
"""Scrape a visible window and return its contents as a bitmap.
-
+
Args:
hwnd: handle of the window to scrape
rect: rectangle to scrape in client coords, defaults to the whole thing
If specified, it's a 4-tuple of (left, top, right, bottom)
-
+
Returns:
An Image containing the scraped data
"""
# Activate the window
SetForegroundWindow(hwnd)
-
+
# If no rectangle was specified, use the fill client rectangle
if not rect: rect = win32gui.GetClientRect(hwnd)
-
+
upper_left = win32gui.ClientToScreen(hwnd, (rect[0], rect[1]))
lower_right = win32gui.ClientToScreen(hwnd, (rect[2], rect[3]))
rect = upper_left+lower_right
-
+
return PIL.ImageGrab.grab(rect)
-
+
def SetForegroundWindow(hwnd):
"""Bring a window to the foreground."""
win32gui.SetForegroundWindow(hwnd)
-
-
+
+
def InvokeAndWait(path, cmdline="", timeout=10, tick=1.):
"""Invoke an application and wait for it to bring up a window.
-
+
Args:
path: full path to the executable to invoke
cmdline: command line to pass to executable
@@ -138,7 +138,7 @@ def InvokeAndWait(path, cmdline="", timeout=10, tick=1.):
A tuple of handles to the process and the application's window,
or (None, None) if it timed out waiting for the process
"""
-
+
def EnumWindowProc(hwnd, ret):
"""Internal enumeration func, checks for visibility and proper PID."""
if win32gui.IsWindowVisible(hwnd): # don't bother even checking hidden wnds
@@ -147,12 +147,12 @@ def InvokeAndWait(path, cmdline="", timeout=10, tick=1.):
ret[1] = hwnd
return 0 # 0 means stop enumeration
return 1 # 1 means continue enumeration
-
+
# We don't need to change anything about the startupinfo structure
# (the default is quite sufficient) but we need to create it just the
# same.
sinfo = win32process.STARTUPINFO()
-
+
proc = win32process.CreateProcess(
path, # path to new process's executable
cmdline, # application's command line
@@ -168,16 +168,16 @@ def InvokeAndWait(path, cmdline="", timeout=10, tick=1.):
# some point we may care about the other members, but for now, all
# we're after is the pid
pid = proc[2]
-
+
# Enumeration APIs can take an arbitrary integer, usually a pointer,
# to be passed to the enumeration function. We'll pass a pointer to
# a structure containing the PID we're looking for, and an empty out
# parameter to hold the found window ID
ret = [pid, None]
-
+
tries_until_timeout = timeout/tick
num_tries = 0
-
+
# Enumerate top-level windows, look for one with our PID
while num_tries < tries_until_timeout and ret[1] is None:
try:
@@ -186,7 +186,7 @@ def InvokeAndWait(path, cmdline="", timeout=10, tick=1.):
# error 0 isn't an error, it just meant the enumeration was
# terminated early
if e[0]: raise e
-
+
time.sleep(tick)
num_tries += 1
@@ -197,11 +197,11 @@ def InvokeAndWait(path, cmdline="", timeout=10, tick=1.):
def WaitForProcessExit(proc, timeout=None):
"""Waits for a given process to terminate.
-
+
Args:
proc: handle to process
timeout: timeout (in seconds). None = wait indefinitely
-
+
Returns:
True if process ended, False if timed out
"""
@@ -210,26 +210,26 @@ def WaitForProcessExit(proc, timeout=None):
else:
# convert sec to msec
timeout *= 1000
-
+
return (win32event.WaitForSingleObject(proc, timeout) ==
win32event.WAIT_OBJECT_0)
def WaitForThrobber(hwnd, rect=None, timeout=20, tick=0.1, done=10):
"""Wait for a browser's "throbber" (loading animation) to complete.
-
+
Args:
hwnd: window containing the throbber
rect: rectangle of the throbber, in client coords. If None, whole window
timeout: if the throbber is still throbbing after this long, give up
tick: how often to check the throbber
done: how long the throbber must be unmoving to be considered done
-
+
Returns:
Number of seconds waited, -1 if timed out
"""
if not rect: rect = win32gui.GetClientRect(hwnd)
-
+
# last_throbber will hold the results of the preceding scrape;
# we'll compare it against the current scrape to see if we're throbbing
last_throbber = ScrapeWindow(hwnd, rect)
@@ -239,7 +239,7 @@ def WaitForThrobber(hwnd, rect=None, timeout=20, tick=0.1, done=10):
while time.clock() < timeout_clock:
time.sleep(tick)
-
+
current_throbber = ScrapeWindow(hwnd, rect)
if current_throbber.tostring() != last_throbber.tostring():
last_throbber = current_throbber
@@ -247,27 +247,27 @@ def WaitForThrobber(hwnd, rect=None, timeout=20, tick=0.1, done=10):
else:
if time.clock() - last_changed_clock > done:
return last_changed_clock - start_clock
-
+
return -1
def MoveAndSizeWindow(wnd, position=None, size=None, child=None):
"""Moves and/or resizes a window.
-
+
Repositions and resizes a window. If a child window is provided,
the parent window is resized so the child window has the given size
-
+
Args:
wnd: handle of the frame window
position: new location for the frame window
size: new size for the frame window (or the child window)
child: handle of the child window
-
+
Returns:
None
"""
rect = win32gui.GetWindowRect(wnd)
-
+
if position is None: position = (rect[0], rect[1])
if size is None:
size = (rect[2]-rect[0], rect[3]-rect[1])
@@ -276,7 +276,7 @@ def MoveAndSizeWindow(wnd, position=None, size=None, child=None):
slop = (rect[2]-rect[0]-child_rect[2]+child_rect[0],
rect[3]-rect[1]-child_rect[3]+child_rect[1])
size = (size[0]+slop[0], size[1]+slop[1])
-
+
win32gui.MoveWindow(wnd, # window to move
position[0], # new x coord
position[1], # new y coord
@@ -287,46 +287,46 @@ def MoveAndSizeWindow(wnd, position=None, size=None, child=None):
def EndProcess(proc, code=0):
"""Ends a process.
-
+
Wraps the OS TerminateProcess call for platform-independence
-
+
Args:
proc: process ID
code: process exit code
-
+
Returns:
None
"""
win32process.TerminateProcess(proc, code)
-
-
+
+
def URLtoFilename(url, path=None, extension=None):
"""Converts a URL to a filename, given a path.
-
+
This in theory could cause collisions if two URLs differ only
in unprintable characters (eg. http://www.foo.com/?bar and
http://www.foo.com/:bar. In practice this shouldn't be a problem.
-
+
Args:
url: The URL to convert
path: path to the directory to store the file
extension: string to append to filename
-
+
Returns:
filename
"""
trans = string.maketrans(r'\/:*?"<>|', '_________')
-
+
if path is None: path = ""
if extension is None: extension = ""
if len(path) > 0 and path[-1] != '\\': path += '\\'
url = url.translate(trans)
return "%s%s%s" % (path, url, extension)
-
+
def PreparePath(path):
"""Ensures that a given path exists, making subdirectories if necessary.
-
+
Args:
path: fully-qualified path of directory to ensure exists
@@ -341,11 +341,11 @@ def PreparePath(path):
if __name__ == "__main__":
PreparePath(r"c:\sitecompare\scrapes\ie7")
# We're being invoked rather than imported. Let's do some tests
-
+
# Hardcode IE's location for the purpose of this test
(proc, wnd) = InvokeAndWait(
r"c:\program files\internet explorer\iexplore.exe")
-
+
# Find the browser pane in the IE window
browser = FindChildWindow(
wnd, "TabWindowClass/Shell DocObject View/Internet Explorer_Server")
@@ -355,8 +355,8 @@ if __name__ == "__main__":
# Take a screenshot
i = ScrapeWindow(browser)
-
+
i.show()
-
+
EndProcess(proc, 0)