diff options
Diffstat (limited to 'tools/site_compare/drivers/win32/windowing.py')
-rw-r--r-- | tools/site_compare/drivers/win32/windowing.py | 110 |
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) |