added multi monitor support for window module

This commit is contained in:
Adam Saudagar 2022-01-30 19:58:17 +05:30
parent f77478d52b
commit 6326a83434
2 changed files with 25 additions and 11 deletions

View File

@ -5,11 +5,12 @@ from enum import Enum
from threading import Thread from threading import Thread
import cv2 import cv2
import numpy as np import d3dshot
import pywintypes import pywintypes
import win32api
import win32gui import win32gui
from PIL import ImageGrab from d3dshot import D3DShot
from win32api import GetSystemMetrics from ctypes import windll
from fishy.helper.config import config from fishy.helper.config import config
@ -28,6 +29,8 @@ class WindowServer:
windowOffset = None windowOffset = None
hwnd = None hwnd = None
status = Status.STOPPED status = Status.STOPPED
d3: D3DShot = None
monitor_top_left = None
def init(): def init():
@ -37,10 +40,19 @@ def init():
""" """
try: try:
WindowServer.hwnd = win32gui.FindWindow(None, "Elder Scrolls Online") WindowServer.hwnd = win32gui.FindWindow(None, "Elder Scrolls Online")
monitor_id = windll.user32.MonitorFromWindow(WindowServer.hwnd, 2)
WindowServer.monitor_top_left = win32api.GetMonitorInfo(monitor_id)["Monitor"][:2]
rect = win32gui.GetWindowRect(WindowServer.hwnd) rect = win32gui.GetWindowRect(WindowServer.hwnd)
client_rect = win32gui.GetClientRect(WindowServer.hwnd) client_rect = win32gui.GetClientRect(WindowServer.hwnd)
WindowServer.windowOffset = math.floor(((rect[2] - rect[0]) - client_rect[2]) / 2) WindowServer.windowOffset = math.floor(((rect[2] - rect[0]) - client_rect[2]) / 2)
WindowServer.status = Status.RUNNING WindowServer.status = Status.RUNNING
d3 = d3dshot.create(capture_output="numpy")
d3.display = next((m for m in d3.displays if m.hmonitor == monitor_id), None)
WindowServer.d3 = d3
except pywintypes.error: except pywintypes.error:
logging.error("Game window not found") logging.error("Game window not found")
WindowServer.status = Status.CRASHED WindowServer.status = Status.CRASHED
@ -51,21 +63,22 @@ def loop():
Executed in the start of the main loop Executed in the start of the main loop
finds the game window location and captures it finds the game window location and captures it
""" """
bbox = (0, 0, GetSystemMetrics(0), GetSystemMetrics(1))
temp_screen = np.array(ImageGrab.grab(bbox=bbox)) temp_screen = WindowServer.d3.screenshot()
rect = win32gui.GetWindowRect(WindowServer.hwnd) rect = win32gui.GetWindowRect(WindowServer.hwnd)
client_rect = win32gui.GetClientRect(WindowServer.hwnd) client_rect = win32gui.GetClientRect(WindowServer.hwnd)
fullscreen = GetSystemMetrics(1) == (rect[3] - rect[1]) fullscreen = WindowServer.d3.display.resolution[1] == (rect[3] - rect[1])
titleOffset = ((rect[3] - rect[1]) - client_rect[3]) - WindowServer.windowOffset if not fullscreen else 0 title_offset = ((rect[3] - rect[1]) - client_rect[3]) - WindowServer.windowOffset if not fullscreen else 0
crop = ( crop = (
rect[0] + WindowServer.windowOffset, rect[1] + titleOffset, rect[2] - WindowServer.windowOffset, rect[0] + WindowServer.windowOffset - WindowServer.monitor_top_left[0],
rect[3] - WindowServer.windowOffset) rect[1] + title_offset - WindowServer.monitor_top_left[1],
rect[2] - WindowServer.windowOffset - WindowServer.monitor_top_left[0],
rect[3] - WindowServer.windowOffset - WindowServer.monitor_top_left[1]
)
WindowServer.Screen = temp_screen[crop[1]:crop[3], crop[0]:crop[2]] WindowServer.Screen = temp_screen[crop[1]:crop[3], crop[0]:crop[2]] if not fullscreen else temp_screen
if WindowServer.Screen.size == 0: if WindowServer.Screen.size == 0:
logging.error("Don't minimize or drag game window outside the screen") logging.error("Don't minimize or drag game window outside the screen")

View File

@ -15,3 +15,4 @@ playsound==1.2.2
event-scheduler event-scheduler
pyzbar pyzbar
mouse mouse
d3dshot