diff --git a/LunaTranslator/LunaTranslator/LunaTranslator.py b/LunaTranslator/LunaTranslator/LunaTranslator.py index 5d1ea8f3..5b0134cd 100644 --- a/LunaTranslator/LunaTranslator/LunaTranslator.py +++ b/LunaTranslator/LunaTranslator/LunaTranslator.py @@ -46,7 +46,7 @@ import gobject import winsharedutils from winsharedutils import collect_running_pids from myutils.post import POSTSOLVE -from myutils.utils import nowisdark +from myutils.utils import nowisdark, getfilemd5 from myutils.traceplaytime import playtimemanager from myutils.audioplayer import series_audioplayer from gui.dynalang import LAction, LMenu @@ -89,6 +89,7 @@ class MAINUI: self.audioplayer = series_audioplayer() self._internal_reader = None self.reader_uid = None + self.__hwnd = None @property def reader(self): @@ -110,6 +111,41 @@ class MAINUI: def textsource(self): return self.textsource_p + @property + def hwnd(self): + return self.__hwnd + + @hwnd.setter + def hwnd(self, __hwnd): + self.__hwnd = __hwnd + if not __hwnd: + self.translation_ui.processismuteed = False + self.translation_ui.isbindedwindow = False + self.translation_ui.refreshtooliconsignal.emit() + self.translation_ui.thistimenotsetop = False + else: + _mute = winsharedutils.GetProcessMute( + windows.GetWindowThreadProcessId(__hwnd) + ) + self.translation_ui.processismuteed = _mute + self.translation_ui.isbindedwindow = True + self.translation_ui.refreshtooliconsignal.emit() + try: + if not self.textsource: + return + if not self.textsource.autofindpids: + return + self.textsource.pids = [windows.GetWindowThreadProcessId(__hwnd)] + gameuid = findgameuidofpath(getpidexe(self.textsource.pids[0])) + if gameuid: + self.textsource.gameuid = gameuid[0] + self.textsource.md5 = getfilemd5(uid2gamepath[gameuid[0]]) + except: + print_exc() + + if globalconfig["keepontop"]: + self.translation_ui.settop() + @textsource.setter def textsource(self, _): if _ is None and self.textsource_p: @@ -117,6 +153,7 @@ class MAINUI: self.textsource_p.end() except: print_exc() + self.hwnd = None self.textsource_p = _ @property @@ -513,10 +550,10 @@ class MAINUI: try: for _ in (0,): - if not gobject.baseobject.textsource: + if not self.textsource: break - gameuid = gobject.baseobject.textsource.gameuid + gameuid = self.textsource.gameuid if not gameuid: break if savehook_new_data[gameuid]["tts_follow_default"]: @@ -669,7 +706,8 @@ class MAINUI: gameuid = find_or_create_uid(savehook_new_list, pexe, title) savehook_new_list.insert(0, gameuid) - self.textsource = texthook(pids, hwnd, pexe, gameuid, autostart=False) + self.textsource = texthook(pids, pexe, gameuid, autostart=False) + self.hwnd = hwnd self.textsource.start() def starttextsource(self, use=None, checked=True): @@ -899,7 +937,8 @@ class MAINUI: 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 = texthook(pids, name_, uid, autostart=True) + self.hwnd = hwnd self.textsource.start() while self.isrunning: @@ -1070,6 +1109,7 @@ class MAINUI: self.mainuiloadafter() def mainuiloadafter(self): + self.__checkmutethread() self.safeloadprocessmodels() self.prepare() self.startxiaoxueguan() @@ -1093,6 +1133,20 @@ class MAINUI: self.playtimemanager = playtimemanager() self.__count = 0 + @threader + def __checkmutethread(self): + while True: + time.sleep(0.5) + if not self.hwnd: + continue + pid = windows.GetWindowThreadProcessId(self.hwnd) + if not pid: + continue + _mute = winsharedutils.GetProcessMute(pid) + if self.translation_ui.processismuteed != _mute: + self.translation_ui.processismuteed = _mute + self.translation_ui.refreshtooliconsignal.emit() + def openlink(self, file): if file.startswith("http") and checkisusingwine(): self.translation_ui.displaylink.emit(file) diff --git a/LunaTranslator/LunaTranslator/gui/edittext.py b/LunaTranslator/LunaTranslator/gui/edittext.py index 5d8c6858..4a181654 100644 --- a/LunaTranslator/LunaTranslator/gui/edittext.py +++ b/LunaTranslator/LunaTranslator/gui/edittext.py @@ -127,7 +127,7 @@ class edittrans(LMainWindow): self.trykeeppos() def trykeeppos(self): - self.followhwnd = gobject.baseobject.textsource.hwnd + self.followhwnd = gobject.baseobject.hwnd rect = windows.GetWindowRect(self.followhwnd) if rect is None: raise diff --git a/LunaTranslator/LunaTranslator/gui/showword.py b/LunaTranslator/LunaTranslator/gui/showword.py index 36b90e8c..d61c6e17 100644 --- a/LunaTranslator/LunaTranslator/gui/showword.py +++ b/LunaTranslator/LunaTranslator/gui/showword.py @@ -354,7 +354,7 @@ class AnkiWindow(QWidget): if not keystring: return try: - windows.SetForegroundWindow(gobject.baseobject.textsource.hwnd) + windows.SetForegroundWindow(gobject.baseobject.hwnd) time.sleep(0.1) except: pass diff --git a/LunaTranslator/LunaTranslator/gui/translatorUI.py b/LunaTranslator/LunaTranslator/gui/translatorUI.py index 51624ee3..adf71af9 100644 --- a/LunaTranslator/LunaTranslator/gui/translatorUI.py +++ b/LunaTranslator/LunaTranslator/gui/translatorUI.py @@ -272,15 +272,15 @@ class TranslatorWindow(resizableframeless): if self.isdoingsomething(): lastpos = None continue - try: - hwnd = gobject.baseobject.textsource.hwnd - if hwnd != tracehwnd: - lastpos = None - except: + + hwnd = gobject.baseobject.hwnd + if not hwnd: + continue + if hwnd != tracehwnd: + tracehwnd = hwnd lastpos = None continue rect = windows.GetWindowRect(hwnd) - tracehwnd = hwnd if not rect: lastpos = None continue @@ -468,9 +468,9 @@ class TranslatorWindow(resizableframeless): @threader def simulate_key_enter(self): - windows.SetForegroundWindow(gobject.baseobject.textsource.hwnd) + windows.SetForegroundWindow(gobject.baseobject.hwnd) time.sleep(0.1) - while windows.GetForegroundWindow() == gobject.baseobject.textsource.hwnd: + while windows.GetForegroundWindow() == gobject.baseobject.hwnd: time.sleep(0.001) windows.keybd_event(13, 0, 0, 0) windows.keybd_event(13, 0, windows.KEYEVENTF_KEYUP, 0) @@ -487,10 +487,10 @@ class TranslatorWindow(resizableframeless): def addbuttons(self): def simulate_key_ctrl(): - windows.SetForegroundWindow(gobject.baseobject.textsource.hwnd) + windows.SetForegroundWindow(gobject.baseobject.hwnd) time.sleep(0.1) windows.keybd_event(17, 0, 0, 0) - while windows.GetForegroundWindow() == gobject.baseobject.textsource.hwnd: + while windows.GetForegroundWindow() == gobject.baseobject.hwnd: time.sleep(0.001) windows.keybd_event(17, 0, windows.KEYEVENTF_KEYUP, 0) @@ -1080,8 +1080,8 @@ class TranslatorWindow(resizableframeless): return self.fullscreenmanager_busy = True try: - if gobject.baseobject.textsource and gobject.baseobject.textsource.hwnd: - _hwnd = gobject.baseobject.textsource.hwnd + if gobject.baseobject.hwnd: + _hwnd = gobject.baseobject.hwnd else: _hwnd = windows.GetForegroundWindow() _pid = windows.GetWindowThreadProcessId(_hwnd) @@ -1180,7 +1180,7 @@ class TranslatorWindow(resizableframeless): def bindcropwindowcallback(self, pid, hwnd): _pid = os.getpid() - gobject.baseobject.textsource.hwnd = hwnd if pid != _pid else None + gobject.baseobject.hwnd = hwnd if pid != _pid else None def changeshowhideraw(self): try: diff --git a/LunaTranslator/LunaTranslator/myutils/hwnd.py b/LunaTranslator/LunaTranslator/myutils/hwnd.py index b4629f3b..0c7a503b 100644 --- a/LunaTranslator/LunaTranslator/myutils/hwnd.py +++ b/LunaTranslator/LunaTranslator/myutils/hwnd.py @@ -14,10 +14,14 @@ def grabwindow(app="PNG", callback_origin=None): fname = gobject.gettempdir(time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())) uid = None else: - try: - dirname = gobject.baseobject.textsource.basename - except: - dirname = "0" + + hwndx = gobject.baseobject.hwnd + if not hwndx: + hwndx = windows.GetForegroundWindow() + gamepath = getpidexe(windows.GetWindowThreadProcessId(hwndx)) + dirname = os.path.basename(gamepath).replace( + "." + os.path.basename(gamepath).split(".")[-1], "" + ) try: uid = gobject.baseobject.textsource.gameuid except: @@ -48,11 +52,9 @@ def grabwindow(app="PNG", callback_origin=None): callback(fname + "_winrt_magpie." + app) _() - try: - hwnd = gobject.baseobject.textsource.hwnd - if not hwnd: - raise - except: + + hwnd = gobject.baseobject.hwnd + if not hwnd: hwnd = windows.GetForegroundWindow() _ = windows.GetClientRect(hwnd) diff --git a/LunaTranslator/LunaTranslator/myutils/utils.py b/LunaTranslator/LunaTranslator/myutils/utils.py index 05bedbba..3f17edba 100644 --- a/LunaTranslator/LunaTranslator/myutils/utils.py +++ b/LunaTranslator/LunaTranslator/myutils/utils.py @@ -427,13 +427,15 @@ def minmaxmoveobservefunc(self): ): try: - if gobject.baseobject.textsource is None: - return - if not gobject.baseobject.textsource.hwnd: - return - if not gobject.baseobject.textsource.pids: + if not gobject.baseobject.hwnd: return + if event == windows.EVENT_OBJECT_DESTROY: + if hwnd == gobject.baseobject.hwnd: + gobject.baseobject.hwnd = None + return p_pids = gobject.baseobject.textsource.pids + if not p_pids: + return _focusp = windows.GetWindowThreadProcessId(hwnd) if event != windows.EVENT_SYSTEM_FOREGROUND: return @@ -441,7 +443,6 @@ def minmaxmoveobservefunc(self): return if _focusp == os.getpid(): return - if windows.FindWindow( "Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22", None ): @@ -467,7 +468,10 @@ def minmaxmoveobservefunc(self): win_event_callback_cfunc = WinEventProcType(win_event_callback) - eventpairs = ((windows.EVENT_SYSTEM_FOREGROUND, windows.EVENT_SYSTEM_FOREGROUND),) + eventpairs = ( + (windows.EVENT_SYSTEM_FOREGROUND, windows.EVENT_SYSTEM_FOREGROUND), + (windows.EVENT_OBJECT_DESTROY, windows.EVENT_OBJECT_DESTROY), + ) def _(): for pair in eventpairs: diff --git a/LunaTranslator/LunaTranslator/textsource/ocrtext.py b/LunaTranslator/LunaTranslator/textsource/ocrtext.py index f03e516e..ea7cd3fa 100644 --- a/LunaTranslator/LunaTranslator/textsource/ocrtext.py +++ b/LunaTranslator/LunaTranslator/textsource/ocrtext.py @@ -74,7 +74,7 @@ class ocrtext(basetext): h4 = windows.WindowFromPoint(windows.POINT(p2[0], p1[1])) self.range_ui[-1].setrect(rect) - if len(self.range_ui) > 1: + if gobject.baseobject.hwnd: return usehwnds = [] for _ in (h1, h2, h3, h4): @@ -86,7 +86,7 @@ class ocrtext(basetext): return hwnd, count = Counter(usehwnds).most_common()[0] if count == len(usehwnds): - self.hwnd = hwnd + gobject.baseobject.hwnd = hwnd def setstyle(self): [_.setstyle() for _ in self.range_ui] @@ -114,7 +114,12 @@ class ocrtext(basetext): if rect is None: continue imgr = imageCut( - self.hwnd, rect[0][0], rect[0][1], rect[1][0], rect[1][1], i == 0 + gobject.baseobject.hwnd, + rect[0][0], + rect[0][1], + rect[1][0], + rect[1][1], + i == 0, ) ok = True @@ -186,7 +191,9 @@ class ocrtext(basetext): continue if rect[0][0] > rect[1][0] or rect[0][1] > rect[1][1]: return - img = imageCut(self.hwnd, rect[0][0], rect[0][1], rect[1][0], rect[1][1]) + img = imageCut( + gobject.baseobject.hwnd, rect[0][0], rect[0][1], rect[1][0], rect[1][1] + ) text = ocr_run(img) imgr1 = qimge2np(img) diff --git a/LunaTranslator/LunaTranslator/textsource/texthook.py b/LunaTranslator/LunaTranslator/textsource/texthook.py index ec39ef23..90d53c8c 100644 --- a/LunaTranslator/LunaTranslator/textsource/texthook.py +++ b/LunaTranslator/LunaTranslator/textsource/texthook.py @@ -103,7 +103,7 @@ class texthook(basetext): return __shitdict(savehook_new_data[self.gameuid]["hooksetting_private"]) - def __init__(self, pids, hwnd, gamepath, gameuid, autostart=False): + def __init__(self, pids, gamepath, gameuid, autostart=False): if autostart: autostarthookcode = savehook_new_data[gameuid]["hook"] needinserthookcode = savehook_new_data[gameuid]["needinserthookcode"] @@ -136,7 +136,6 @@ class texthook(basetext): self.gameuid = gameuid self.pids = pids self.is64bit = Is64bit(pids[0]) - self.hwnd = hwnd gobject.baseobject.hookselectdialog.changeprocessclearsignal.emit() self.isremoveuseless = self.config["removeuseless"] and len( self.autostarthookcode diff --git a/LunaTranslator/LunaTranslator/textsource/textsourcebase.py b/LunaTranslator/LunaTranslator/textsource/textsourcebase.py index 31055061..96762abf 100644 --- a/LunaTranslator/LunaTranslator/textsource/textsourcebase.py +++ b/LunaTranslator/LunaTranslator/textsource/textsourcebase.py @@ -1,97 +1,15 @@ import threading, gobject, queue -import time, sqlite3, json, os, windows, winsharedutils +import time, sqlite3, json, os from traceback import print_exc -from myutils.config import ( - globalconfig, - savehook_new_data, - findgameuidofpath, - uid2gamepath, -) -from myutils.utils import autosql, getfilemd5 -from myutils.hwnd import getpidexe -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) +from myutils.config import globalconfig, savehook_new_data +from myutils.utils import autosql class basetext: autofindpids = True - @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 self.autofindpids: - self.pids = [] - self.gameuid = None - self.md5 = "0" - self.basename = self.__basename - if _hwnd: - - self.__hwnd = hwndchecker(_hwnd, self) - - if not self.autofindpids: - return - self.pids = [windows.GetWindowThreadProcessId(_hwnd)] - gameuid = findgameuidofpath(getpidexe(self.pids[0])) - if gameuid: - self.gameuid = gameuid[0] - self.md5 = getfilemd5(uid2gamepath[gameuid[0]]) - gamepath = uid2gamepath[self.gameuid] - self.basename = os.path.basename(gamepath).replace( - "." + os.path.basename(gamepath).split(".")[-1], "" - ) - def __init__(self, md5, basename): self.md5 = md5 - self.__basename = self.basename = basename - self.__hwnd = None self.pids = [] self.gameuid = None # @@ -137,7 +55,6 @@ class basetext: return None def end(self): - self.hwnd = None self.ending = True ################## diff --git a/LunaTranslator/LunaTranslator/windows.py b/LunaTranslator/LunaTranslator/windows.py index d76b481c..13904402 100644 --- a/LunaTranslator/LunaTranslator/windows.py +++ b/LunaTranslator/LunaTranslator/windows.py @@ -60,7 +60,7 @@ EVENT_SYSTEM_MINIMIZEEND = 23 EVENT_SYSTEM_MOVESIZESTART = 10 EVENT_SYSTEM_MOVESIZEEND = 11 EVENT_SYSTEM_FOREGROUND = 3 - +EVENT_OBJECT_DESTROY = 0x8001 PIPE_ACCESS_INBOUND = 0x00000001 PIPE_ACCESS_OUTBOUND = 0x00000002 @@ -261,6 +261,7 @@ _keybd_event.argtypes = c_byte, c_byte, c_uint, c_void_p _RegisterWindowMessage = _user32.RegisterWindowMessageW _GetWindowThreadProcessId = _user32.GetWindowThreadProcessId +_GetWindowThreadProcessId.argtypes = HWND, c_void_p _GetClipboardOwner = _user32.GetClipboardOwner try: