48 lines
1.2 KiB
Python
48 lines
1.2 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class WindowRegion:
|
|
left: int
|
|
top: int
|
|
width: int
|
|
height: int
|
|
title: str
|
|
|
|
def as_mss_monitor(self) -> dict[str, int]:
|
|
return {
|
|
"left": self.left,
|
|
"top": self.top,
|
|
"width": self.width,
|
|
"height": self.height,
|
|
}
|
|
|
|
|
|
def find_window_region(title_contains: str) -> WindowRegion:
|
|
import win32gui
|
|
|
|
matches: list[WindowRegion] = []
|
|
|
|
def collect(hwnd: int, _extra) -> bool:
|
|
if not win32gui.IsWindowVisible(hwnd):
|
|
return True
|
|
|
|
title = win32gui.GetWindowText(hwnd)
|
|
if title_contains.lower() not in title.lower():
|
|
return True
|
|
|
|
left, top, right, bottom = win32gui.GetWindowRect(hwnd)
|
|
width = right - left
|
|
height = bottom - top
|
|
if width > 0 and height > 0:
|
|
matches.append(WindowRegion(left, top, width, height, title))
|
|
return True
|
|
|
|
win32gui.EnumWindows(collect, None)
|
|
if not matches:
|
|
raise RuntimeError(f"no visible window found containing title: {title_contains}")
|
|
|
|
return max(matches, key=lambda region: region.width * region.height)
|