| | |
| | | |
| | | import cv2 |
| | | import numpy |
| | | import win32api |
| | | import win32con |
| | | import win32gui |
| | | import win32ui |
| | | import ctypes |
| | | from ctypes import wintypes |
| | | |
| | | from utils import invalid_hwnds_manager |
| | | |
| | | |
| | | def is_visible(hwnd): |
| | | return win32gui.IsWindowVisible(hwnd) |
| | | |
| | | |
| | | # 定义常量 |
| | | SMTO_NORMAL = 0x0000 |
| | | SMTO_BLOCK = 0x0001 |
| | | SMTO_ABORTIFHUNG = 0x0002 |
| | | SMTO_NOTIMEOUTIFNOTHUNG = 0x0008 |
| | | |
| | | text_hwnds_doing = set() |
| | | |
| | | |
| | | def get_title(hwnd): |
| | | length = ctypes.c_int(256) |
| | | buffer = ctypes.create_unicode_buffer(length.value) |
| | | ctypes.windll.user32.SendMessageTimeoutW( |
| | | hwnd, |
| | | ctypes.c_int(0x000D), # WM_GETTEXT |
| | | ctypes.c_int(255), |
| | | ctypes.c_void_p(buffer), |
| | | ctypes.c_int(0x0002), # SMTO_ABORTIFHUNG |
| | | ctypes.c_int(1000), |
| | | ctypes.pointer(ctypes.c_int(0)) |
| | | ) |
| | | return buffer.value |
| | | |
| | | |
| | | def getText(hwnd): |
| | | text_hwnds_doing.add(hwnd) |
| | | try: |
| | | bufSize = win32gui.SendMessage(hwnd, win32con.WM_GETTEXTLENGTH, 0, 0) + 1 |
| | | buffer = array.array('b', b'\x00\x00' * bufSize) |
| | | win32gui.SendMessage(hwnd, win32con.WM_GETTEXT, bufSize, buffer) |
| | | text = win32gui.PyGetString(buffer.buffer_info()[0], bufSize - 1) |
| | | return text.replace("\x00", "").strip() |
| | | finally: |
| | | text_hwnds_doing.discard(hwnd) |
| | | |
| | | |
| | | # 根据标题模糊匹配 |
| | | def search_window(title): |
| | | def search_window(title, max_count=3): |
| | | invalid_hwnds = invalid_hwnds_manager.get_hwnds() |
| | | hwnds = [] |
| | | try: |
| | | hwnd = win32gui.GetDesktopWindow() |
| | | temp = None |
| | | while True: |
| | | if temp not in invalid_hwnds: |
| | | if temp and win32gui.IsWindowVisible(temp): |
| | | str_ = getText(temp) |
| | | if str_.find(title) > -1: |
| | | hwnds.append(temp) |
| | | if len(hwnds) >= max_count: |
| | | break |
| | | temp = win32gui.FindWindowEx(hwnd, temp, None, None) |
| | | if not temp: |
| | | break |
| | |
| | | return im_opencv |
| | | |
| | | |
| | | def move_window(hwnd, x, y): |
| | | """ |
| | | 移动窗口 |
| | | :param hwnd: |
| | | :param x: |
| | | :param y: |
| | | :return: |
| | | """ |
| | | try: |
| | | # 获取窗口的当前矩形区域 |
| | | rect = win32gui.GetWindowRect(hwnd) |
| | | width = rect[2] - rect[0] |
| | | height = rect[3] - rect[1] |
| | | # 移动窗口到指定位置 (x, y),并保持窗口的宽度和高度不变 |
| | | win32gui.MoveWindow(hwnd, x, y, width, height, True) |
| | | print(f"窗口已移动到位置 ({x}, {y})") |
| | | except Exception as e: |
| | | print(f"移动窗口失败: {e}") |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | # print(search_window("副屏1")) |
| | | # visual_click(0x00152876, (110, 90)) |