Как работать с окнами в python

Мне нужно получить размеры конкретного окна. На данный момент я пользуются PyWin32.

Там можно получить хендл окна по заголовку, а через хендл уже размеры. Однако что если запущено два окна с одинаковыми заголовками?

Есть ли другой способ получить КОНКРЕТНОЕ окно?


Ответы (1 шт):

Автор решения: S. Nick

Выход всегда есть, но так как вы не представляете свой пример, я покажу свой пример, в котором, как мне кажется реализовано и то, что вам надо. Проверьте:

import sys                
import numpy as np
import cv2
import win32gui
import win32con
import win32ui

import re
from time import sleep


def FindWindow_bySearch(pattern):
    window_list = []
    win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), window_list)
    for each in window_list:
        if re.search(pattern, win32gui.GetWindowText(each)) is not None:
            return each
    print(f'Задача {pattern} не выполняется!!')
    sys.exit(0)

def getWindow_W_H(hwnd):
    # Получить размер целевого окна
    left, top, right, bot = win32gui.GetWindowRect(hwnd)
    width = right - left - 15
    height = bot - top - 11
    return (left, top, width, height)

def getWindow_Img(hwnd):
    # Замените hwnd на WindowLong
    s = win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE)
    win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, s|win32con.WS_EX_LAYERED)
    
    # Определите, свернуто ли окно
    show = win32gui.IsIconic(hwnd)
    
    # Измените атрибут слоя окна на прозрачный  
    # Восстановите окно и увеличьте масштаб вперед
    # Отменить максимальную анимацию минимизации
    # Получить ширину и высоту окна
    if show == 1: 
        win32gui.SystemParametersInfo(win32con.SPI_SETANIMATION, 0)
        win32gui.SetLayeredWindowAttributes(hwnd, 0, 0, win32con.LWA_ALPHA)
        win32gui.ShowWindow(hwnd, win32con.SW_RESTORE)    
        x, y, width, height = getWindow_W_H(hwnd) 
        
    # Создать выходной слой
    try:                                    
        hwindc = win32gui.GetWindowDC(hwnd) 
    except:
        print(f'Задача {hwnd} уже не выполняется !!')
        return [] 
    
    srcdc = win32ui.CreateDCFromHandle(hwindc)
    memdc = srcdc.CreateCompatibleDC()
    bmp = win32ui.CreateBitmap()
    # Получить ширину и высоту окна
    x, y, width, height = getWindow_W_H(hwnd)
    
    # Если окно свернуто, переместитесь к нижней части оси Z
    if show == 1: 
        win32gui.SetWindowPos(
            hwnd, win32con.HWND_BOTTOM, x, y, width, height, win32con.SWP_NOACTIVATE
        )
    # Скопируйте целевой слой и вставьте его в bmp.
    bmp.CreateCompatibleBitmap(srcdc, width, height)
    memdc.SelectObject(bmp)
    memdc.BitBlt((0 , 0), (width, height), srcdc, (8, 3), win32con.SRCCOPY)
    
    # Преобразовать растровое изображение в np   
    signedIntsArray = bmp.GetBitmapBits(True)
    img = np.fromstring(signedIntsArray, dtype='uint8')
    img.shape = (height, width, 4)      
    
    # Освободить содержимое устройства 
    srcdc.DeleteDC()
    memdc.DeleteDC()
    win32gui.ReleaseDC(hwnd, hwindc)
    win32gui.DeleteObject(bmp.GetHandle())
    
    # Восстановить целевые атрибуты
    if show == 1 :
        win32gui.SetLayeredWindowAttributes(hwnd, 0, 255, win32con.LWA_ALPHA)
        win32gui.SystemParametersInfo(win32con.SPI_SETANIMATION, 1)
    # Вернуться изображение
    return img


hwnd = FindWindow_bySearch("Библиотеки")
print(f'\n hwnd: {hwnd} \n')

while True:
    sleep(0.03)
    frame = getWindow_Img(hwnd)

    if len(frame):    
        cv2.imshow("screen box", frame)
        k = cv2.waitKey(30)&0xFF     
    else:
        k = 27
    
    if k == 27:           # ESC    
        cv2.destroyAllWindows()
        break

введите сюда описание изображения

→ Ссылка