Enhancement: Ability to customize window properties to look for when win32 api searching for d2r window (#563)

This commit is contained in:
Vladimir Makaev
2022-02-18 17:27:31 +00:00
committed by GitHub
parent 59c8a898b7
commit 528400503c
4 changed files with 54 additions and 10 deletions

View File

@@ -250,4 +250,8 @@ settings_backup_key=f8
auto_settings_key=f9
graphic_debugger_key=f10
resume_key=f11
exit_key=f12
exit_key=f12
hwnd_window_title=
hwnd_window_process=D2R\.exe
;If you want to control Hyper-V window from host use 0,51 here
window_client_area_offset=0,0

View File

@@ -8,6 +8,8 @@ from logger import Logger
config_lock = threading.Lock()
def _default_iff(value, iff, default = None):
return default if value == iff else value
@dataclass
class ItemProps:
@@ -312,6 +314,9 @@ class Config:
"restore_settings_from_backup_key": Config._select_val("advanced_options", "restore_settings_from_backup_key"),
"settings_backup_key": Config._select_val("advanced_options", "settings_backup_key"),
"graphic_debugger_key": Config._select_val("advanced_options", "graphic_debugger_key"),
"hwnd_window_title": _default_iff(Config._select_val("advanced_options", "hwnd_window_title"), ''),
"hwnd_window_process": _default_iff(Config._select_val("advanced_options", "hwnd_window_process"), ''),
"window_client_area_offset": tuple(map(int, Config._select_val("advanced_options", "window_client_area_offset").split(",")))
}
Config.items = {}

View File

@@ -5,7 +5,7 @@ import time
from logger import Logger
from typing import Tuple
from config import Config
from utils.misc import find_d2r_window
from utils.misc import WindowSpec, find_d2r_window
import os
@@ -22,8 +22,12 @@ class Screen:
# Find d2r screen offsets and monitor idx
self.found_offsets = False
position = None
Logger.debug("Using WinAPI to search for window under D2R.exe process")
position = find_d2r_window()
find_window = WindowSpec(
title_regex=Config.advanced_options["hwnd_window_title"],
process_name_regex=Config.advanced_options["hwnd_window_process"],
)
Logger.debug(f"Using WinAPI to search for window: {find_window}")
position = find_d2r_window(find_window, offset=Config.advanced_options["window_client_area_offset"])
if position is not None:
self._set_window_position(*position)
else:

View File

@@ -1,12 +1,17 @@
from dataclasses import dataclass
from decimal import InvalidOperation
from re import RegexFlag
import time
import random
import ctypes
import numpy as np
from copy import deepcopy
from pyparsing import Regex
from logger import Logger
import cv2
from typing import List, Tuple
from typing import List, Tuple, Union
import os
from math import cos, sin, dist
import subprocess
@@ -20,15 +25,34 @@ import psutil
def close_down_d2():
subprocess.call(["taskkill","/F","/IM","D2R.exe"], stderr=subprocess.DEVNULL)
def find_d2r_window() -> tuple[int, int]:
@dataclass
class WindowSpec:
title_regex: 'Union[str, None]' = None
process_name_regex: 'Union[str, None]' = None
def match(self, hwnd) -> bool:
result = True
if self.title_regex is not None:
result = result and Regex(self.title_regex).matches(GetWindowText(hwnd))
if self.process_name_regex is not None:
_, process_id = GetWindowThreadProcessId(hwnd)
result = result and Regex(self.process_name_regex).matches(psutil.Process(process_id).name())
if self.title_regex is None and self.process_name_regex is None:
result = False
return result
def find_d2r_window(spec: WindowSpec, offset = (0, 0)) -> tuple[int, int]:
offset_x, offset_y = offset
if os.name == 'nt':
window_list = []
EnumWindows(lambda w, l: l.append((w, *GetWindowThreadProcessId(w))), window_list)
for (hwnd, _, process_id) in window_list:
if psutil.Process(process_id).name() == "D2R.exe":
EnumWindows(lambda w, l: l.append(w), window_list)
for hwnd in window_list:
if spec.match(hwnd):
left, top, right, bottom = GetClientRect(hwnd)
(left, top), (right, bottom) = ClientToScreen(hwnd, (left, top)), ClientToScreen(hwnd, (right, bottom))
return (left, top)
return (left + offset_x, top + offset_y)
return None
def set_d2r_always_on_top():
@@ -187,3 +211,10 @@ def rotate_vec(vec: np.ndarray, deg: float) -> np.ndarray:
def unit_vector(vec: np.ndarray) -> np.ndarray:
return vec / dist(vec, (0, 0))
if __name__ == "__main__":
spec1 = WindowSpec(title_regex="D2R1 on .+")
spec2 = WindowSpec(process_name_regex="D2R.exe")
print(find_d2r_window(spec1))
print(find_d2r_window(spec2))