1.先用关键词拿到窗口顶层句柄
win_name = "工作台" hwnd, window_text = get_qianniu_hwnd(win_name) if hwnd: print(f"找到的窗口句柄: {hwnd}, 窗口标题: '{window_text}'") else: print("没有找到匹配的窗口。")
2.用拿到的句柄去遍历输出所有的子控件句柄 文本 和类名信息,根据输出信息判断哪些是可以直接用的 哪些是需要继续用类名去定位索引的
运行这步时所有子控件将高亮 有的控件不能直接用的还需要重复用第三步去找子控件
把输出的调试信息记录备用
hwnd = 8981440 # 父窗口句柄,替换为实际值 # print(f"窗口句柄: {hwnd} ,窗口标题: {control_text}, 类名{class_name}") controls = find_controls_by_text_pattern(hwnd)
3.按照控件类名调试看哪些索引的控件是需要用上的 写到dict字典里面并测试点击 这一步如果嵌套在多层级的控件可用父级hwnd
hwnd = 8981440 # 父窗口句柄,替换为实际值 class_name = "StandardButton" # 要查找的控件类名 controls_dict = find_controls_by_class_name(hwnd, class_name) for key, hwnd in controls_dict.items(): #在这里调试看哪些索引的控件是需要用上的 写到dict字典里面 highlight_window(hwnd) dict = {"点击接待中心": controls_dict[13]} for key, hwnd in dict.items(): print(f"控件索引{key} 对应的控件句柄: {hwnd}") click_control(hwnd)
4.按照编辑控件类名去找到需要的编辑框并测试编辑输入
import win32con import win32api import win32gui import re
import time
def get_hwnd(win_name): """ 查找并返回指定名称的顶层窗口的句柄和标题。 此函数通过枚举所有可见的顶层窗口,并使用正则表达式匹配窗口标题, 来查找与给定名称匹配的窗口。一旦找到匹配的窗口,就返回其句柄和标题。 如果没有找到匹配的窗口,则返回None。 调用: win_name = "工作台" hwnd, window_text = get_qianniu_hwnd(win_name) if hwnd: print(f"找到的窗口句柄: {hwnd}, 窗口标题: '{window_text}'") else: print("没有找到匹配的窗口。") 参数: - win_name: 字符串,要查找的窗口标题的一部分。这个名称将被用于正则表达式匹配, 因此可以是部分标题或完整标题的正则表达式模式。 返回值: - hwnd: 找到的窗口的句柄。如果没有找到匹配的窗口,则为None。 - window_text: 找到的窗口的标题文本。如果没有找到匹配的窗口,则为None。 """ # 使用列表作为包装器,以便在内部函数中修改 found_window = [None] def enum_window_proc(hwnd, lParam): """ EnumWindows回调函数,用于检查每个顶层窗口是否为目标窗口。 如果窗口标题与给定的正则表达式匹配,保存该窗口的句柄和标题。 """ if win32gui.IsWindowVisible(hwnd): window_text = win32gui.GetWindowText(hwnd) pattern = re.compile(lParam) if pattern.search(window_text): # 保存找到的窗口句柄和标题到列表的第一个元素 found_window[0] = (hwnd, window_text) # 执行枚举所有顶层窗口的操作 win32gui.EnumWindows(enum_window_proc, f".*{win_name}.*") # 检查是否找到了匹配的窗口,并返回结果 if found_window[0]: return found_window[0] else: return None, None # 如果没有找到,返回None def highlight_window(hwnd): """ 绘制一个红色矩形框以高亮显示指定窗口或控件。 参数: - hwnd: 需要高亮显示的窗口或控件的句柄。 说明: - 该函数获取目标窗口的设备上下文(DC),使用红色画笔在窗口的边缘绘制一个矩形框。 这个矩形框可以用于视觉上标识和高亮显示特定的UI元素,非常适合用于UI自动化测试、调试, 或者用户界面的演示中。 - 注意,绘制的矩形框在窗口重绘时可能会消失,如果需要持续高亮,可能需要在适当时机重新调用此函数。 """ try: # 获取窗口的设备上下文(DC),用于绘图 dc = win32gui.GetWindowDC(hwnd) # 设置画笔的样式、宽度和颜色 red_pen = win32gui.CreatePen(win32con.PS_SOLID, 2, win32api.RGB(255, 0, 0)) # 红色画笔 old_pen = win32gui.SelectObject(dc, red_pen) # 设置画刷为透明 old_brush = win32gui.SelectObject(dc, win32gui.GetStockObject(win32con.NULL_BRUSH)) # 获取窗口的边界 left, top, right, bottom = win32gui.GetWindowRect(hwnd) # 转换坐标系统 left, top = win32gui.ScreenToClient(hwnd, (left, top)) right, bottom = win32gui.ScreenToClient(hwnd, (right, bottom)) # 绘制矩形框 win32gui.Rectangle(dc, left, top, right, bottom) # 恢复旧的画笔和画刷 win32gui.SelectObject(dc, old_pen) win32gui.SelectObject(dc, old_brush) # 删除创建的画笔 win32gui.DeleteObject(red_pen) # 释放设备上下文 win32gui.ReleaseDC(hwnd, dc) except: print(f"{hwnd}这是一个无效句柄") def find_controls_by_text_pattern(hwnd): """ 自动化测试工具: 在指定窗口中查找文本匹配特定模式的所有子控件。 调用示例:
hwnd = 8981440 # 父窗口句柄,替换为实际值 # print(f"窗口句柄: {hwnd} ,窗口标题: {control_text}, 类名{class_name}") controls = find_controls_by_text_pattern(hwnd)
参数: - hwnd: 父窗口或顶层窗口的句柄。 返回值: - 一个字典,其中键是匹配到的文本,值是对应控件的句柄(hwnd)。 """ matched_controls = {} def enum_child_proc(hwnd, _): # 尝试获取控件的文本 control_text = win32gui.GetWindowText(hwnd) class_name = win32gui.GetClassName(hwnd) # 检查文本是否匹配给定的模式 matched_controls[control_text] = hwnd highlight_window(hwnd) print(f"窗口句柄: {hwnd} ,窗口标题: {control_text}, 类名{class_name}") # 这里只是为了演示,所以找到第一个匹配的窗口后就返回 # 枚举所有子控件 win32gui.EnumChildWindows(hwnd, enum_child_proc, None) return matched_controls
def click_control(hwnd): """ 模拟鼠标点击指定句柄(hwnd)的控件。 调用: hwnd = 3284220 # 控件的句柄,替换为实际值 click_control(hwnd) 参数: - hwnd: 控件的句柄。 """ # 获取控件的客户区坐标(相对于控件的左上角) left, top, right, bottom = win32gui.GetClientRect(hwnd) # 计算点击位置(这里简单地取中点) click_x = left + (right - left) // 2 click_y = top + (bottom - top) // 2 # 将客户区坐标转换为屏幕坐标 screen_x, screen_y = win32gui.ClientToScreen(hwnd, (click_x, click_y)) # 发送鼠标点击消息 win32api.SendMessage(hwnd, win32con.WM_LBUTTONDOWN, win32con.MK_LBUTTON, win32api.MAKELONG(click_x, click_y)) win32api.SendMessage(hwnd, win32con.WM_LBUTTONUP, 0, win32api.MAKELONG(click_x, click_y)) def find_controls_by_class_name(hwnd, class_name): """ 枚举指定父窗口下所有匹配给定类名的子控件,并存储在字典中。 调用: hwnd = 402930 # 父窗口句柄,替换为实际值 class_name = "StandardButton" # 要查找的控件类名 controls_dict = find_controls_by_class_name(hwnd, class_name) dict={"点击搜索":controls_dict[15],"联系中":controls_dict[17],"最近联系":controls_dict[18],"我的好友":controls_dict[19]} for key, hwnd in dict.items(): print(f"控件索引{key} 对应的控件句柄: {hwnd}") click_control(hwnd) time.sleep(1) 参数: - parent_hwnd: 父窗口的句柄。 - class_name: 要查找的控件类名。 返回值: - 一个字典,键为控件的索引,值为对应的控件句柄。 """ controls_dict = {} def enum_child_proc(hwnd, lParam): if win32gui.GetClassName(hwnd) == class_name: # 将控件句柄添加到字典中,使用字典的当前长度作为索引 lParam[len(lParam)] = hwnd return True # 使用闭包函数枚举子窗口 win32gui.EnumChildWindows(hwnd, enum_child_proc, controls_dict) return controls_dict