From 07fb07ee343c8ede53bb8c8ecac3f37ad6f8b778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <101191390+HIllya51@users.noreply.github.com> Date: Wed, 14 Aug 2024 18:55:50 +0800 Subject: [PATCH] fix --- .../LunaTranslator/LunaTranslator.py | 94 +++++-------------- .../LunaTranslator/gui/translatorUI.py | 2 - .../LunaTranslator/textsource/copyboard.py | 4 +- .../LunaTranslator/textsource/ocrtext.py | 26 ++++- .../LunaTranslator/textsource/texthook.py | 7 +- .../textsource/textsourcebase.py | 59 +++++++++++- LunaTranslator/LunaTranslator/windows.py | 2 + .../LunaTranslator/winsharedutils.py | 16 +--- 8 files changed, 115 insertions(+), 95 deletions(-) diff --git a/LunaTranslator/LunaTranslator/LunaTranslator.py b/LunaTranslator/LunaTranslator/LunaTranslator.py index a65dd291..e1d11610 100644 --- a/LunaTranslator/LunaTranslator/LunaTranslator.py +++ b/LunaTranslator/LunaTranslator/LunaTranslator.py @@ -877,35 +877,27 @@ class MAINUI: return elif self.AttachProcessDialog and self.AttachProcessDialog.isVisible(): return - if self.textsource is None: - hwnd = windows.GetForegroundWindow() - pid = windows.GetWindowThreadProcessId(hwnd) - name_ = getpidexe(pid) - if not name_: - return - found = findgameuidofpath(name_) - if not found: - return - uid, reflist = found - pids = ListProcess(name_) - if self.textsource is not None: - return - if not globalconfig["sourcestatus2"]["texthook"]["use"]: - return - if globalconfig["startgamenototop"] == False: - idx = reflist.index(uid) - reflist.insert(0, reflist.pop(idx)) - self.textsource = texthook(pids, hwnd, name_, uid, autostart=True) - self.textsource.start() - - else: - pids = self.textsource.pids - if len(collect_running_pids(pids)) != 0: - return - self.textsource = None - self.translation_ui.thistimenotsetop = False - if globalconfig["keepontop"]: - self.translation_ui.settop() + if self.textsource is not None: + return + hwnd = windows.GetForegroundWindow() + pid = windows.GetWindowThreadProcessId(hwnd) + name_ = getpidexe(pid) + if not name_: + return + found = findgameuidofpath(name_) + if not found: + return + uid, reflist = found + pids = ListProcess(name_) + if self.textsource is not None: + return + if not globalconfig["sourcestatus2"]["texthook"]["use"]: + return + if globalconfig["startgamenototop"] == False: + idx = reflist.index(uid) + reflist.insert(0, reflist.pop(idx)) + self.textsource = texthook(pids, hwnd, name_, uid, autostart=True) + self.textsource.start() while self.isrunning: try: @@ -915,49 +907,6 @@ class MAINUI: time.sleep(0.5) # 太短了的话,中间存在一瞬间,后台进程比前台窗口内存占用要大。。。 - def autocheckhwndexists(self): - def setandrefresh(b): - if self.translation_ui.isbindedwindow != b: - self.translation_ui.isbindedwindow = b - self.translation_ui.refreshtooliconsignal.emit() - - @tryprint - def __do(): - if not self.textsource: - setandrefresh(False) - return - hwnd = self.textsource.hwnd - - if hwnd == 0: - if not globalconfig["sourcestatus2"]["texthook"]["use"]: - setandrefresh(False) - else: - fhwnd = windows.GetForegroundWindow() - pids = self.textsource.pids - notdone = "once" not in dir(self.textsource) - isgoodproc = windows.GetWindowThreadProcessId(fhwnd) in pids - if isgoodproc and notdone: - self.textsource.once = True - self.textsource.hwnd = fhwnd - setandrefresh(True) - else: - if windows.GetWindowThreadProcessId(hwnd) == 0: - self.textsource.hwnd = 0 - setandrefresh(False) - elif "once" not in dir(self.textsource): - self.textsource.once = True - setandrefresh(True) - if self.textsource.pids: - _mute = winsharedutils.GetProcessMute(self.textsource.pids[0]) - if self.translation_ui.processismuteed != _mute: - self.translation_ui.processismuteed = _mute - self.translation_ui.refreshtooliconsignal.emit() - - while self.isrunning: - __do() - - time.sleep(0.5) - def setdarkandbackdrop(self, widget, dark): if self.__dontshowintaborsetbackdrop(widget): return @@ -1131,7 +1080,6 @@ class MAINUI: self.searchwordW = searchwordW(self.commonstylebase) self.hookselectdialog = hookselect(self.commonstylebase) self.starttextsource() - threading.Thread(target=self.autocheckhwndexists).start() threading.Thread(target=self.autohookmonitorthread).start() threading.Thread( target=minmaxmoveobservefunc, args=(self.translation_ui,) diff --git a/LunaTranslator/LunaTranslator/gui/translatorUI.py b/LunaTranslator/LunaTranslator/gui/translatorUI.py index dda1d772..d19afb85 100644 --- a/LunaTranslator/LunaTranslator/gui/translatorUI.py +++ b/LunaTranslator/LunaTranslator/gui/translatorUI.py @@ -1189,8 +1189,6 @@ class TranslatorWindow(resizableframeless): gameuid = findgameuidofpath(getpidexe(pid)) if gameuid: gobject.baseobject.textsource.gameuid = gameuid[0] - self.isbindedwindow = pid != _pid - self.refreshtoolicon() def changeshowhideraw(self): try: diff --git a/LunaTranslator/LunaTranslator/textsource/copyboard.py b/LunaTranslator/LunaTranslator/textsource/copyboard.py index 12ff1955..10f1946a 100644 --- a/LunaTranslator/LunaTranslator/textsource/copyboard.py +++ b/LunaTranslator/LunaTranslator/textsource/copyboard.py @@ -1,8 +1,6 @@ -import time from textsource.textsourcebase import basetext from myutils.config import globalconfig -import winsharedutils, os, queue -import windows +import winsharedutils, queue class copyboard(basetext): diff --git a/LunaTranslator/LunaTranslator/textsource/ocrtext.py b/LunaTranslator/LunaTranslator/textsource/ocrtext.py index 75ff1cf3..197d37a4 100644 --- a/LunaTranslator/LunaTranslator/textsource/ocrtext.py +++ b/LunaTranslator/LunaTranslator/textsource/ocrtext.py @@ -1,11 +1,12 @@ -import time +import time, os from myutils.config import globalconfig -import winsharedutils +import winsharedutils, windows from gui.rangeselect import rangeadjust from myutils.ocrutil import imageCut, ocr_run, ocr_end, ocr_init import time, gobject from qtsymbols import * from traceback import print_exc +from collections import Counter from textsource.textsourcebase import basetext @@ -70,7 +71,28 @@ class ocrtext(basetext): _r.traceoffsetsignal.emit(curr) def setrect(self, rect): + p1, p2 = rect + h1 = windows.WindowFromPoint(windows.POINT(*p1)) + h2 = windows.WindowFromPoint(windows.POINT(*p2)) + h3 = windows.WindowFromPoint(windows.POINT(p1[0], p2[1])) + h4 = windows.WindowFromPoint(windows.POINT(p2[0], p1[1])) + self.range_ui[-1].setrect(rect) + usehwnds = [] + for _ in (h1, h2, h3, h4): + if windows.GetWindowThreadProcessId(_) == os.getpid(): + continue + usehwnds.append(_) + + if not usehwnds: + return + hwnd, count = Counter(usehwnds).most_common()[0] + if self.hwnd: + if count == len(usehwnds): + self.hwnd = hwnd + else: + if count >= len(usehwnds) - 1: + self.hwnd = hwnd def setstyle(self): [_.setstyle() for _ in self.range_ui] diff --git a/LunaTranslator/LunaTranslator/textsource/texthook.py b/LunaTranslator/LunaTranslator/textsource/texthook.py index 6127f355..d8c01160 100644 --- a/LunaTranslator/LunaTranslator/textsource/texthook.py +++ b/LunaTranslator/LunaTranslator/textsource/texthook.py @@ -226,10 +226,15 @@ class texthook(basetext): self.Luna_FreePtr(ws) return string + def procdisc(self, pid): + self.connectedpids.remove(pid) + if len(self.connectedpids) == 0: + gobject.baseobject.textsource = None + def prepares(self): procs = [ ProcessEvent(self.onprocconnect), - ProcessEvent(self.connectedpids.remove), + ProcessEvent(self.procdisc), ThreadEvent(self.onnewhook), ThreadEvent(self.onremovehook), OutputCallback(self.handle_output), diff --git a/LunaTranslator/LunaTranslator/textsource/textsourcebase.py b/LunaTranslator/LunaTranslator/textsource/textsourcebase.py index 03845fa2..8b5a8bc5 100644 --- a/LunaTranslator/LunaTranslator/textsource/textsourcebase.py +++ b/LunaTranslator/LunaTranslator/textsource/textsourcebase.py @@ -1,16 +1,71 @@ import threading, gobject, queue -import time, sqlite3, json, os +import time, sqlite3, json, os, windows, winsharedutils from traceback import print_exc from myutils.config import globalconfig, savehook_new_data from myutils.utils import autosql +from myutils.wrapper import threader + + +class hwndchecker: + def __del__(self): + if self.ref.hwnd: + return + gobject.baseobject.translation_ui.processismuteed = False + gobject.baseobject.translation_ui.isbindedwindow = False + gobject.baseobject.translation_ui.refreshtooliconsignal.emit() + gobject.baseobject.translation_ui.thistimenotsetop = False + if globalconfig["keepontop"]: + gobject.baseobject.translation_ui.settop() + + def __init__(self, hwnd, ref) -> None: + self.hwnd = hwnd + self.ref = ref + self.end = False + + _mute = winsharedutils.GetProcessMute( + windows.GetWindowThreadProcessId(self.hwnd) + ) + + gobject.baseobject.translation_ui.processismuteed = _mute + gobject.baseobject.translation_ui.isbindedwindow = True + gobject.baseobject.translation_ui.refreshtooliconsignal.emit() + self.__checkthread() + + @threader + def __checkthread(self): + while not self.end: + pid = windows.GetWindowThreadProcessId(self.hwnd) + if not pid: + self.hwnd = None + self.__del__() + break + _mute = winsharedutils.GetProcessMute(pid) + if gobject.baseobject.translation_ui.processismuteed != _mute: + gobject.baseobject.translation_ui.processismuteed = _mute + gobject.baseobject.translation_ui.refreshtooliconsignal.emit() + time.sleep(0.5) class basetext: + @property + def hwnd(self): + + if self.__hwnd is None: + return None + return self.__hwnd.hwnd + + @hwnd.setter + def hwnd(self, _hwnd): + if self.__hwnd: + self.__hwnd.end = True + self.__hwnd = None + if _hwnd: + self.__hwnd = hwndchecker(_hwnd, self) def __init__(self, md5, basename): self.md5 = md5 self.basename = basename - self.hwnd = None + self.__hwnd = None self.pids = [] self.gameuid = None # diff --git a/LunaTranslator/LunaTranslator/windows.py b/LunaTranslator/LunaTranslator/windows.py index b21f83b6..d76b481c 100644 --- a/LunaTranslator/LunaTranslator/windows.py +++ b/LunaTranslator/LunaTranslator/windows.py @@ -398,6 +398,8 @@ def GetClipboardOwner(): def GetWindowThreadProcessId(hwnd): pid = c_uint() handle = _GetWindowThreadProcessId(hwnd, pointer(pid)) + if handle == 0: + return 0 return pid.value diff --git a/LunaTranslator/LunaTranslator/winsharedutils.py b/LunaTranslator/LunaTranslator/winsharedutils.py index 84ab9ef4..1de8b7f9 100644 --- a/LunaTranslator/LunaTranslator/winsharedutils.py +++ b/LunaTranslator/LunaTranslator/winsharedutils.py @@ -28,11 +28,11 @@ import gobject utilsdll = CDLL(gobject.GetDllpath(("winsharedutils32.dll", "winsharedutils64.dll"))) -_SetProcessMute = utilsdll.SetProcessMute -_SetProcessMute.argtypes = c_uint, c_bool +SetProcessMute = utilsdll.SetProcessMute +SetProcessMute.argtypes = c_uint, c_bool -_GetProcessMute = utilsdll.GetProcessMute -_GetProcessMute.restype = c_bool +GetProcessMute = utilsdll.GetProcessMute +GetProcessMute.restype = c_bool _SAPI_List = utilsdll.SAPI_List _SAPI_List.argtypes = (c_uint, c_void_p) @@ -70,14 +70,6 @@ _clipboard_set.argtypes = ( ) -def SetProcessMute(pid, mute): - _SetProcessMute(pid, mute) - - -def GetProcessMute(pid): - return _GetProcessMute(pid) - - def SAPI_List(v): ret = [] _SAPI_List(v, CFUNCTYPE(None, c_wchar_p)(ret.append))