| | |
| | | |
| | | 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): |
| | | 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() |
| | | 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 = [] |
| | | hwnd = win32gui.GetDesktopWindow() |
| | | temp = None |
| | | while True: |
| | | if temp and win32gui.IsWindowVisible(temp): |
| | | str_ = getText(temp) |
| | | if str_.find(title) > -1: |
| | | hwnds.append(temp) |
| | | print(str_) |
| | | temp = win32gui.FindWindowEx(hwnd, temp, None, None) |
| | | if not temp: |
| | | break |
| | | 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 |
| | | except: |
| | | pass |
| | | return hwnds |
| | | |
| | | |
| | |
| | | win32gui.PostMessage(hwnd, win32con.WM_KEYUP, code, 0) |
| | | |
| | | |
| | | def window_capture(hwnd, rect): |
| | | def visual_keyboard_F5(hwnd): |
| | | win32gui.PostMessage(hwnd, win32con.WM_KEYDOWN, win32con.VK_F5, 0) |
| | | win32gui.PostMessage(hwnd, win32con.WM_KEYUP, win32con.VK_F5, 0) |
| | | |
| | | |
| | | # rect格式为:(左,上,右,下坐标) |
| | | def window_capture(hwnd, rect, scale, is_test=False): |
| | | rect_ = win32gui.GetWindowRect(hwnd) |
| | | ow = rect_[2] - rect_[0] |
| | | oh = rect_[3] - rect_[1] |
| | | ow = int(ow * scale) |
| | | oh = int(oh * scale) |
| | | w = rect[2] - rect[0] |
| | | h = rect[3] - rect[1] |
| | | if w == 0 or h == 0: |
| | |
| | | saveDC = mfcDC.CreateCompatibleDC() |
| | | # 创建位图对象准备保存图片 |
| | | saveBitMap = win32ui.CreateBitmap() |
| | | # 为bitmap开辟存储空间 |
| | | saveBitMap.CreateCompatibleBitmap(mfcDC, w, h) |
| | | # 将截图保存到saveBitMap中 |
| | | saveDC.SelectObject(saveBitMap) |
| | | # 保存bitmap到内存设备描述表 |
| | | saveDC.BitBlt((0, 0), (w, h), mfcDC, (rect[0], rect[1]), win32con.SRCCOPY) |
| | | # 保存数据 |
| | | # saveBitMap.SaveBitmapFile(saveDC, "test.png") |
| | | |
| | | if not is_test: |
| | | # 为bitmap开辟存储空间 |
| | | saveBitMap.CreateCompatibleBitmap(mfcDC, w, h) |
| | | # 将截图保存到saveBitMap中 |
| | | saveDC.SelectObject(saveBitMap) |
| | | # 保存bitmap到内存设备描述表 |
| | | saveDC.BitBlt((0, 0), (ow, h), mfcDC, (rect[0], rect[1]), win32con.SRCCOPY) |
| | | else: |
| | | # 为bitmap开辟存储空间 |
| | | saveBitMap.CreateCompatibleBitmap(mfcDC, ow, oh) |
| | | # 将截图保存到saveBitMap中 |
| | | saveDC.SelectObject(saveBitMap) |
| | | # 保存bitmap到内存设备描述表 |
| | | saveDC.BitBlt((0, 0), (ow, oh), mfcDC, (0, 0), win32con.SRCCOPY) |
| | | # 保存数据 |
| | | saveBitMap.SaveBitmapFile(saveDC, "test_origin.png") |
| | | # 内存释放 |
| | | win32gui.DeleteObject(saveBitMap.GetHandle()) |
| | | saveDC.DeleteDC() |
| | | mfcDC.DeleteDC() |
| | | win32gui.ReleaseDC(hwnd, hWndDC) |
| | | |
| | | #########################保存最新的数据########################## |
| | | hWndDC = win32gui.GetWindowDC(hwnd) |
| | | mfcDC = win32ui.CreateDCFromHandle(hWndDC) |
| | | saveDC = mfcDC.CreateCompatibleDC() |
| | | # 创建位图对象准备保存图片 |
| | | saveBitMap = win32ui.CreateBitmap() |
| | | saveBitMap.CreateCompatibleBitmap(mfcDC, w, h) |
| | | # 将截图保存到saveBitMap中 |
| | | saveDC.SelectObject(saveBitMap) |
| | | saveDC.BitBlt((0, 0), (ow, h), mfcDC, (rect[0], rect[1]), win32con.SRCCOPY) |
| | | saveBitMap.SaveBitmapFile(saveDC, "test_origin_clip.png") |
| | | |
| | | signedIntsArray = saveBitMap.GetBitmapBits(True) |
| | | |
| | | |
| | | |
| | | # 内存释放 |
| | | win32gui.DeleteObject(saveBitMap.GetHandle()) |
| | |
| | | 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)) |
| | | # print(search_window("副屏1")) |
| | | # visual_click(0x00152876, (110, 90)) |
| | | |
| | | window_capture(0x00010986, (0, 0, 1920, 895)) |
| | | # pass |