pyWinAuto: c:\.projects\py_pywinauto\pywinauto\findwindows.py
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021"""Provides functions for iterating and finding windows
0022
0023"""
0024
0025__revision__ = "$Revision: 607 $"
0026
0027import re
0028
0029import ctypes
0030
0031import win32functions
0032import win32structures
0033import handleprops
0034
0035import findbestmatch
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045class WindowNotFoundError(Exception):
0046 "No window could be found"
0047 pass
0048
0049
0050class WindowAmbiguousError(Exception):
0051 "There was more then one window that matched"
0052 pass
0053
0054
0055
0056
0057def find_window(**kwargs):
0058 """Call findwindows and ensure that only one window is returned
0059
0060 Calls find_windows with exactly the same arguments as it is called with
0061 so please see find_windows for a description of them."""
0062 windows = find_windows(**kwargs)
0063
0064 if not windows:
0065 raise WindowNotFoundError()
0066
0067 if len(windows) > 1:
0068
0069
0070
0071 exception = WindowAmbiguousError(
0072 "There are %d windows that match the criteria %s"% (
0073 len(windows),
0074 unicode(kwargs),
0075 )
0076 )
0077
0078 exception.windows = windows
0079 raise exception
0080
0081 return windows[0]
0082
0083
0084def find_windows(class_name = None,
0085 class_name_re = None,
0086 parent = None,
0087 process = None,
0088 title = None,
0089 title_re = None,
0090 top_level_only = True,
0091 visible_only = True,
0092 enabled_only = True,
0093 best_match = None,
0094 handle = None,
0095 ctrl_index = None,
0096 predicate_func = None,
0097 active_only = False,
0098 ):
0099 """Find windows based on criteria passed in
0100
0101 Possible values are:
0102
0103 * **class_name** Windows with this window class
0104 * **class_name_re** Windows whose class match this regular expression
0105 * **parent** Windows that are children of this
0106 * **process** Windows running in this process
0107 * **title** Windows with this Text
0108 * **title_re** Windows whose Text match this regular expression
0109 * **top_level_only** Top level windows only (default=True)
0110 * **visible_only** Visible windows only (default=True)
0111 * **enabled_only** Enabled windows only (default=True)
0112 * **best_match** Windows with a title similar to this
0113 * **handle** The handle of the window to return
0114 * **ctrl_index** The index of the child window to return
0115 * **active_only** Active windows only (default=False)
0116 """
0117
0118
0119
0120 if handle is not None:
0121 return [handle, ]
0122
0123
0124 if top_level_only:
0125
0126 windows = enum_windows()
0127
0128
0129 if parent:
0130 windows = [win for win in windows
0131 if handleprops.parent(win) == parent]
0132
0133
0134 else:
0135
0136 if not parent:
0137 parent = win32functions.GetDesktopWindow()
0138
0139
0140 windows = enum_child_windows(parent)
0141
0142
0143
0144 if ctrl_index is not None:
0145 return [windows[ctrl_index]]
0146
0147 if active_only:
0148 if not process:
0149 raise RuntimeError("Can only get active window of a process - " "please specify 'process' too")
0151
0152 gui_info = win32structures.GUITHREADINFO()
0153 gui_info.cbSize = ctypes.sizeof(gui_info)
0154
0155
0156 ret = win32functions.GetGUIThreadInfo(0, ctypes.byref(gui_info))
0157
0158 if not ret:
0159 raise ctypes.WinError()
0160
0161
0162 if gui_info.hwndActive in windows:
0163 windows = [gui_info.hwndActive]
0164 else:
0165 windows = []
0166
0167
0168 if class_name is not None and windows:
0169 windows = [win for win in windows
0170 if class_name == handleprops.classname(win)]
0171
0172 if class_name_re is not None and windows:
0173 class_name_regex = re.compile(class_name_re)
0174 windows = [win for win in windows
0175 if class_name_regex.match(handleprops.classname(win))]
0176
0177 if process is not None and windows:
0178 windows = [win for win in windows
0179 if handleprops.processid(win) == process]
0180
0181 if title is not None and windows:
0182 windows = [win for win in windows
0183 if title == handleprops.text(win)]
0184
0185 elif title_re is not None and windows:
0186 title_regex = re.compile(title_re)
0187 windows = [win for win in windows
0188 if title_regex.match(handleprops.text(win))]
0189
0190 if visible_only and windows:
0191 windows = [win for win in windows if handleprops.isvisible(win)]
0192
0193 if enabled_only and windows:
0194 windows = [win for win in windows if handleprops.isenabled(win)]
0195
0196 if best_match is not None and windows:
0197 from controls import WrapHandle
0198 windows = [WrapHandle(win) for win in windows]
0199 windows = findbestmatch.find_best_control_matches(
0200 best_match, windows)
0201
0202 windows = [win.handle for win in windows]
0203
0204 if predicate_func is not None and windows:
0205 windows = [win for win in windows if predicate_func(win)]
0206
0207 return windows
0208
0209
0210def enum_windows():
0211 "Return a list of handles of all the top level windows"
0212 windows = []
0213
0214
0215
0216 def EnumWindowProc(hwnd, lparam):
0217 "Called for each window - adds handles to a list"
0218 windows.append(hwnd)
0219 return True
0220
0221
0222 enum_win_proc = ctypes.WINFUNCTYPE(
0223 ctypes.c_int, ctypes.c_long, ctypes.c_long)
0224
0225
0226 proc = enum_win_proc(EnumWindowProc)
0227
0228
0229 win32functions.EnumWindows(proc, 0)
0230
0231
0232 return windows
0233
0234
0235
0236def enum_child_windows(handle):
0237 "Return a list of handles of the child windows of this handle"
0238
0239
0240 child_windows = []
0241
0242
0243 def EnumChildProc(hwnd, lparam):
0244 "Called for each child - adds child hwnd to list"
0245
0246
0247 child_windows.append(hwnd)
0248
0249
0250 return True
0251
0252
0253 enum_child_proc = ctypes.WINFUNCTYPE(
0254 ctypes.c_int,
0255 win32structures.HWND,
0256 win32structures.LPARAM)
0257
0258
0259 proc = enum_child_proc(EnumChildProc)
0260
0261
0262 win32functions.EnumChildWindows(handle, proc, 0)
0263
0264 return child_windows