def find(self, element_path): if not self.click_desktop: self.click_desktop = pywinauto.Desktop(backend='uia', allow_magic_lookup=False) if Region.common_path: element_path2 = Region.common_path + core.path_separator + element_path else: element_path2 = element_path entry_list = core.get_entry_list(element_path2) i = 0 unique_element = None elements = None strategy = None while i < 99: while unique_element is None and not elements: try: unique_element, elements = core.find_element( self.click_desktop, entry_list, window_candidates=[], regex_title=self.regex_title) if unique_element is None and not elements: time.sleep(2.0) except Exception: pass i += 1 _, _, y_x, _ = core.get_entry(entry_list[-1]) if y_x is not None: nb_y, nb_x, candidates = core.get_sorted_region(elements) if core.is_int(y_x[0]): unique_element = candidates[int(y_x[0])][int(y_x[1])] else: ref_entry_list = core.get_entry_list(Region.common_path) + core.get_entry_list(y_x[0]) ref_unique_element, _ = core.find_element( self.click_desktop, ref_entry_list, window_candidates=[], regex_title=self.regex_title) ref_r = ref_unique_element.rectangle() r_y = 0 while r_y < nb_y: y_candidate = candidates[r_y][0].rectangle().mid_point()[1] if ref_r.top < y_candidate < ref_r.bottom: unique_element = candidates[r_y][y_x[1]] break r_y = r_y + 1 else: unique_element = None if unique_element is not None: #Region.wait_element_is_ready(unique_element) wait_is_ready_try1(unique_element) break time.sleep(0.1) if not unique_element: raise Exception("Unique element not found! ", element_path2) return unique_element
def process_menu_select_events(events, i): i0 = i i_processed_events = [] menu_bar_path = None menu_path = [] menu_type = 'QT' while i0 >= 0: if type(events[i0]) is ClickEvent: entry_list = core.get_entry_list(events[i0].path) str_name, str_type, _, _ = core.get_entry(entry_list[-1]) if str_type == 'MenuItem': str_name, str_type, _, _ = core.get_entry(entry_list[0]) if str_name == 'Context' and str_type == 'Menu': break menu_path.append(str_name) str_name, str_type, _, _ = core.get_entry(entry_list[-2]) if str_type == 'MenuBar': if str_name: menu_type = 'NPP' menu_path.append(str_name) menu_bar_path = core.path_separator.join(entry_list[0:-2]) menu_path = core.path_separator.join(reversed(menu_path)) break else: i_processed_events.append(i0) i0 = i0 - 1 if menu_bar_path: events[i0] = MenuEvent(path=menu_bar_path, menu_path=menu_path, menu_type=menu_type) for i_p_e in sorted(i_processed_events, reverse=True): del events[i_p_e] i = i - 1 return i
def __find_unique_element_array_1d(self, wrapper_rectangle, elements): nb_y, nb_x, candidates = core.get_sorted_region(elements) for r_y in range(nb_y): for r_x in range(nb_x): try: r = candidates[r_y][r_x].rectangle() except IndexError: continue if r == wrapper_rectangle: xx, yy = r.left, r.mid_point()[1] previous_wrapper_path2 = None while xx > 0: xx = xx - 9 wrapper2 = self.desktop.from_point(xx, yy) if wrapper2 is None: continue wrapper2_rectangle = wrapper2.rectangle() if wrapper2_rectangle.height( ) > wrapper_rectangle.height() * 2: continue wrapper_path2 = get_wrapper_path(wrapper2) if not wrapper_path2: continue if wrapper_path2 == previous_wrapper_path2: continue previous_wrapper_path2 = wrapper_path2 entry_list2 = core.get_entry_list(wrapper_path2) unique_candidate2, _ = core.find_element( self.desktop, entry_list2, window_candidates=[]) if unique_candidate2 is not None: r = wrapper2_rectangle self.main_overlay.add( geometry=oaam.Shape.rectangle, x=r.left, y=r.top, width=r.width(), height=r.height(), thickness=1, color=(0, 0, 255), brush=oaam.Brush.solid, brush_color=(0, 0, 255)) r = wrapper_rectangle self.main_overlay.add( geometry=oaam.Shape.rectangle, x=r.left, y=r.top, width=r.width(), height=r.height(), thickness=1, color=(255, 0, 0), brush=oaam.Brush.solid, brush_color=(255, 200, 0)) return '#[' + wrapper_path2 + ',' + str(r_x) + ']' else: return None return None
def find_common_path(current_path, next_path): current_entry_list = core.get_entry_list(current_path) _, _, y_x, _ = core.get_entry(current_entry_list[-1]) if (y_x is not None) and not core.is_int(y_x[0]): current_entry_list = core.get_entry_list(y_x[0])[:-1] else: current_entry_list = current_entry_list[:-1] next_entry_list = core.get_entry_list(next_path) next_entry_list = next_entry_list[:-1] n = 0 try: while current_entry_list[n] == next_entry_list[n]: n = n + 1 except IndexError: common_path = core.path_separator.join(current_entry_list[0:n]) return common_path common_path = core.path_separator.join(current_entry_list[0:n]) return common_path
def get_relative_path(common_path, path): if not path: return '' path = path[len(common_path) + len(core.path_separator):] entry_list = core.get_entry_list(path) str_name, str_type, y_x, dx_dy = core.get_entry(entry_list[-1]) if (y_x is not None) and not core.is_int(y_x[0]): y_x[0] = y_x[0][len(common_path) + 2:] path = core.path_separator.join( entry_list[:-1]) + core.path_separator + str_name path = path + core.type_separator + str_type + "#[" + y_x[ 0] + "," + str(y_x[1]) + "]" if dx_dy is not None: path = path + "%(" + str(dx_dy[0]) + "," + str(dx_dy[1]) + ")" return path
def move(self, element_path, duration=0.5, mode=MoveMode.linear): global unique_element_old global element_path_old global w_rOLD x, y = win32api.GetCursorPos() if isinstance(element_path, basestring): element_path2 = element_path if Region.common_path: if Region.common_path != element_path[0:len(Region.common_path)]: element_path2 = Region.common_path + core.path_separator + element_path entry_list = core.get_entry_list(element_path2) if element_path2 == element_path_old: w_r = w_rOLD unique_element = unique_element_old else: unique_element = self.find(element_path) w_r = unique_element.rectangle() control_type = None for entry in entry_list: _, control_type, _, _ = core.get_entry(entry) if control_type == 'Menu': break if control_type == 'Menu': entry_list_old = core.get_entry_list(element_path_old) control_type_old = None for entry in entry_list_old: _, control_type_old, _, _ = core.get_entry(entry) if control_type_old == 'Menu': break if control_type_old == 'Menu': mode = MoveMode.x_first else: mode = MoveMode.y_first xd, yd = w_r.mid_point() else: _, _, _, dx_dy = core.get_entry(entry_list[-1]) if dx_dy: dx, dy = dx_dy[0], dx_dy[1] else: dx, dy = 0, 0 xd, yd = w_r.mid_point() xd, yd = xd + round(dx/100.0*w_r.width(), 0), round(yd + dy/100.0*w_r.height(), 0) else: (xd, yd) = element_path unique_element = None if (x, y) != (xd, yd): dt = 0.01 samples = duration/dt step_x = (xd-x)/samples step_y = (yd-y)/samples if mode == MoveMode.x_first: for i in range(int(samples)): x = x+step_x time.sleep(0.01) nx = int(x) * 65535 / win32api.GetSystemMetrics(0) ny = int(y) * 65535 / win32api.GetSystemMetrics(1) win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, nx, ny) step_x = 0 if mode == MoveMode.y_first: for i in range(int(samples)): y = y+step_y time.sleep(0.01) nx = int(x) * 65535 / win32api.GetSystemMetrics(0) ny = int(y) * 65535 / win32api.GetSystemMetrics(1) win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, nx, ny) step_y = 0 for i in range(int(samples)): x, y = x+step_x, y+step_y time.sleep(0.01) nx = int(x) * 65535 / win32api.GetSystemMetrics(0) ny = int(y) * 65535 / win32api.GetSystemMetrics(1) win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, nx, ny) nx = int(xd) * 65535 / win32api.GetSystemMetrics(0) ny = int(yd) * 65535 / win32api.GetSystemMetrics(1) win32api.mouse_event(win32con.MOUSEEVENTF_MOVE | win32con.MOUSEEVENTF_ABSOLUTE, nx, ny) if unique_element is None: return None unique_element_old = unique_element element_path_old = element_path2 w_rOLD = w_r return unique_element
def run(self): keyboard.hook(self.__key_on) mouse.hook(self.__mouse_on) unique_candidate = None elements = [] i = 0 previous_wrapper_path = None unique_wrapper_path = None strategies = [ core.Strategy.unique_path, core.Strategy.array_2D, core.Strategy.array_1D ] i_strategy = 0 self._is_running = True while self._is_running: try: self.main_overlay.clear_all() x, y = win32api.GetCursorPos() wrapper = self.desktop.from_point(x, y) if wrapper is None: continue wrapper_path = get_wrapper_path(wrapper) if not wrapper_path: continue if wrapper_path == previous_wrapper_path: if (unique_wrapper_path is None) or ( strategies[i_strategy] == core.Strategy.array_2D): i_strategy = i_strategy + 1 if i_strategy >= len(strategies): i_strategy = len(strategies) - 1 else: i_strategy = 0 previous_wrapper_path = wrapper_path entry_list = core.get_entry_list(wrapper_path) unique_candidate, elements = core.find_element( self.desktop, entry_list, window_candidates=[]) strategy = strategies[i_strategy] unique_wrapper_path = None if strategy == core.Strategy.unique_path: if unique_candidate is not None: unique_wrapper_path = get_wrapper_path( unique_candidate) r = wrapper.rectangle() self.main_overlay.add(geometry=oaam.Shape.rectangle, x=r.left, y=r.top, width=r.width(), height=r.height(), thickness=1, color=(0, 128, 0), brush=oaam.Brush.solid, brush_color=(0, 255, 0)) else: for e in elements: r = e.rectangle() self.main_overlay.add( geometry=oaam.Shape.rectangle, x=r.left, y=r.top, width=r.width(), height=r.height(), thickness=1, color=(0, 128, 0), brush=oaam.Brush.solid, brush_color=(255, 0, 0)) if strategy == core.Strategy.array_1D: unique_array_1d = self.__find_unique_element_array_1d( wrapper.rectangle(), elements) if unique_array_1d is not None: unique_wrapper_path = wrapper_path + unique_array_1d else: strategy = core.Strategy.array_2D if strategy == core.Strategy.array_2D: unique_array_2d = self.__find_unique_element_array_2d( wrapper.rectangle(), elements) if unique_array_2d is not None: unique_wrapper_path = wrapper_path + unique_array_2d if unique_wrapper_path is not None: self.last_element_event = ElementEvent( strategy, wrapper.rectangle(), unique_wrapper_path) if self.event_list and unique_wrapper_path is not None: self.event_list.append(self.last_element_event) if self.event_list: overlay_add_record_icon(self.main_overlay, 10, 10) else: overlay_add_pause_icon(self.main_overlay, 10, 10) overlay_add_progress_icon(self.main_overlay, i, 60, 10) overlay_add_search_mode_icon(self.main_overlay, 110, 10) i = i + 1 self.main_overlay.refresh() time.sleep( 0.005 ) # main_overlay.clear_all() doit attendre la fin de main_overlay.refresh() except Exception as e: exc_type, exc_value, exc_traceback = sys.exc_info() print( repr( traceback.format_exception(exc_type, exc_value, exc_traceback))) self.main_overlay.clear_all() self.main_overlay.refresh() if self.event_list: self.stop_recording() mouse.unhook_all() keyboard.unhook_all() print("Run end")
def write_in_file(events): new_path = 'Record files' if not os.path.exists(new_path): os.makedirs(new_path) record_file_name = './Record files/recorded ' + time.asctime() + '.py' record_file_name = record_file_name.replace(':', '_') print('Recording in file: ' + record_file_name) record_file = open(record_file_name, "w") record_file.write("# coding: utf-8\n\n") record_file.write("from pywinauto_recorder import *\n\n") i = 0 common_path = '' common_window = '' while i < len(events): e_i = events[i] if type(e_i) is SendKeysEvent: if common_path: record_file.write('\t\t') record_file.write('send_keys(' + e_i.line + ')\n') elif type(e_i) is MouseWheelEvent: if common_path: record_file.write("\t\t") record_file.write('mouse_wheel(' + str(e_i.delta) + ')\n') elif type(e_i) is CommonPathEvent: if e_i.path != common_path: entry_list = core.get_entry_list(e_i.path) e_i_window = entry_list[0] if e_i_window != common_window: record_file.write('\nwith Window(u"' + escape_special_char(e_i_window) + '") as w:\n') common_window = e_i_window rel_path = core.path_separator.join(entry_list[1:]) if rel_path: record_file.write('\twith Region(u"' + escape_special_char(rel_path) + '") as r:\n') else: record_file.write('\twith Region() as r:\n') common_path = e_i.path elif type(e_i) is DragAndDropEvent: p1, p2 = e_i.path, e_i.path2 dx1, dy1 = "{:.2f}".format(round(e_i.dx1 * 100, 2)), "{:.2f}".format( round(e_i.dy1 * 100, 2)) dx2, dy2 = "{:.2f}".format(round(e_i.dx2 * 100, 2)), "{:.2f}".format( round(e_i.dy2 * 100, 2)) if common_path: p1 = get_relative_path(common_path, p1) p2 = get_relative_path(common_path, p2) record_file.write('\t\tr.drag_and_drop(u"' + escape_special_char(p1) + '%(' + dx1 + ',' + dy1 + ')", ') record_file.write('u"' + escape_special_char(p2) + '%(' + dx2 + ',' + dy2 + ')")\n') elif type(e_i) is ClickEvent: p = e_i.path dx, dy = "{:.2f}".format(round(e_i.dx * 100, 2)), "{:.2f}".format( round(e_i.dy * 100, 2)) if common_path: p = get_relative_path(common_path, p) str_c = ['', '\t\tr.', '\tr.double_', '\tr.triple_'] record_file.write(str_c[e_i.click_count] + e_i.button + '_click(u"' + escape_special_char(p) + '%(' + dx + ',' + dy + ')")\n') elif type(e_i) is FindEvent: p = e_i.path dx, dy = "{:.2f}".format(round(e_i.dx * 100, 2)), "{:.2f}".format( round(e_i.dy * 100, 2)) record_file.write('\t\twrapper = r.find(u"' + escape_special_char(p) + '%(' + dx + ',' + dy + ')")\n') elif type(e_i) is MenuEvent: p, m_p = e_i.path, e_i.menu_path if common_path: p = get_relative_path(common_path, p) record_file.write('\t\tr.menu_click(u"' + escape_special_char(p) + '", r"' + escape_special_char(m_p) + '"') if e_i.menu_type == 'NPP': record_file.write(', menu_type="NPP")\n') else: record_file.write(')\n') i = i + 1 record_file.close() with open(record_file_name, 'r') as my_file: data = my_file.read() pyperclip.copy(data) return record_file_name