diff --git a/LunaTranslator/LunaTranslator/LunaTranslator.py b/LunaTranslator/LunaTranslator/LunaTranslator.py index a5fc141f..283f417f 100644 --- a/LunaTranslator/LunaTranslator/LunaTranslator.py +++ b/LunaTranslator/LunaTranslator/LunaTranslator.py @@ -21,6 +21,9 @@ from myutils.utils import ( getfilemd5, stringfyerror, ) +import os, hashlib +from PyQt5.QtWidgets import QApplication +from PyQt5.QtCore import Qt, QSize, QObject, QEvent from myutils.wrapper import threader from gui.showword import searchwordW from myutils.hwnd import getpidexe, testprivilege, ListProcess @@ -754,6 +757,30 @@ class MAINUI: time.sleep(0.5) def aa(self): + class WindowEventFilter(QObject): + def eventFilter(_, obj, event): + if event.type() == QEvent.Type.WinIdChange: + + hwnd = obj.winId() + if hwnd: # window create/destroy,when destroy winId is None + if ( + self.currentisdark is not None + and obj.testAttribute(Qt.WA_TranslucentBackground) == False + ): + winsharedutils.SetTheme( + int(obj.winId()), + self.currentisdark, + globalconfig["WindowBackdrop"], + ) + windows.SetProp( + int(obj.winId()), "Magpie.ToolWindow", windows.HANDLE(1) + ) + return False + + self.currentisdark = None + self.__filter = WindowEventFilter() # keep ref + QApplication.instance().installEventFilter(self.__filter) + self.translation_ui = gui.translatorUI.QUnFrameWindow() self.translation_ui.show() diff --git a/LunaTranslator/LunaTranslator/gui/settin.py b/LunaTranslator/LunaTranslator/gui/settin.py index e0ff5131..f31c1124 100644 --- a/LunaTranslator/LunaTranslator/gui/settin.py +++ b/LunaTranslator/LunaTranslator/gui/settin.py @@ -259,20 +259,8 @@ class Settin(closeashidewindow): dark = isDark() darklight = ["light", "dark"][dark] - class WindowEventFilter(QObject): - def eventFilter(_, obj, event): - if event.type() == QEvent.Type.WinIdChange: - if obj.testAttribute(Qt.WA_TranslucentBackground): - return False - hwnd = obj.winId() - if hwnd: # window create/destroy,when destroy winId is None - winsharedutils.SetTheme( - int(obj.winId()), dark, globalconfig["WindowBackdrop"] - ) - return False + gobject.baseobject.currentisdark = dark - self.__filter = WindowEventFilter() # keep ref - QApplication.instance().installEventFilter(self.__filter) for widget in QApplication.topLevelWidgets(): if widget.testAttribute(Qt.WA_TranslucentBackground): continue diff --git a/LunaTranslator/LunaTranslator/gui/settingpage_quick.py b/LunaTranslator/LunaTranslator/gui/settingpage_quick.py index c6854ad2..cfa93024 100644 --- a/LunaTranslator/LunaTranslator/gui/settingpage_quick.py +++ b/LunaTranslator/LunaTranslator/gui/settingpage_quick.py @@ -41,10 +41,11 @@ def setTab_quick_direct(self): "_21": lambda: grabwindow(), "_22": gobject.baseobject.translation_ui.muteprocessignal.emit, "_23": lambda: gobject.baseobject.translation_ui.clickRange_signal.emit(True), - "_25": lambda: windows.SendMessage( - windows.FindWindow("Magpie_Core_CLI_Message", None), - windows.RegisterWindowMessage("Magpie_Core_CLI_Message_ToggleOverlay"), - ), + # 暂时有问题 + # "_25": lambda: windows.SendMessage( + # windows.FindWindow("WNDCLS_Magpie_Core_CLI_Message", None), + # windows.RegisterWindowMessage("Magpie_Core_CLI_Message_ToggleOverlay"), + # ), "_26": gobject.baseobject.translation_ui.ocr_once_signal.emit, "_27": gobject.baseobject.translation_ui.simulate_key_enter, } diff --git a/LunaTranslator/LunaTranslator/gui/translatorUI.py b/LunaTranslator/LunaTranslator/gui/translatorUI.py index 347a402e..c8453d96 100644 --- a/LunaTranslator/LunaTranslator/gui/translatorUI.py +++ b/LunaTranslator/LunaTranslator/gui/translatorUI.py @@ -657,6 +657,7 @@ class QUnFrameWindow(resizableframeless): self.casthira2kata = str.maketrans( static_data["allhira"], static_data["allkata"] ) + self.fullscreenmanager_busy = False self.isletgamefullscreened = False self.fullscreenmanager = None self.fullscreenmethod = None @@ -725,7 +726,11 @@ class QUnFrameWindow(resizableframeless): self.isletgamefullscreened = current self.refreshtooliconsignal.emit() + @threader def _fullsgame(self): + if self.fullscreenmanager_busy: + return + self.fullscreenmanager_busy = True try: if gobject.baseobject.textsource and gobject.baseobject.textsource.hwnd: _hwnd = gobject.baseobject.textsource.hwnd @@ -756,6 +761,7 @@ class QUnFrameWindow(resizableframeless): ) # , self.isletgamefullscreened) except: print_exc() + self.fullscreenmanager_busy = False def changemousetransparentstate(self, idx): if idx == 0: diff --git a/LunaTranslator/LunaTranslator/scalemethod/SW_SHOWMAXIMIZED.py b/LunaTranslator/LunaTranslator/scalemethod/SW_SHOWMAXIMIZED.py index 09aabf35..838108b0 100644 --- a/LunaTranslator/LunaTranslator/scalemethod/SW_SHOWMAXIMIZED.py +++ b/LunaTranslator/LunaTranslator/scalemethod/SW_SHOWMAXIMIZED.py @@ -8,3 +8,4 @@ class Method(scalebase): self.savewindowstatus = letfullscreen(hwnd) else: recoverwindow(hwnd, self.savewindowstatus) + return True \ No newline at end of file diff --git a/LunaTranslator/LunaTranslator/scalemethod/alt_enter.py b/LunaTranslator/LunaTranslator/scalemethod/alt_enter.py index 8fc3620b..7875e4f9 100644 --- a/LunaTranslator/LunaTranslator/scalemethod/alt_enter.py +++ b/LunaTranslator/LunaTranslator/scalemethod/alt_enter.py @@ -10,3 +10,4 @@ class Method(scalebase): windows.keybd_event(13, 0, windows.KEYEVENTF_KEYUP, 0) windows.keybd_event(18, 0, windows.KEYEVENTF_KEYUP, 0) + return True \ No newline at end of file diff --git a/LunaTranslator/LunaTranslator/scalemethod/base.py b/LunaTranslator/LunaTranslator/scalemethod/base.py index 8459a2b0..b6d30289 100644 --- a/LunaTranslator/LunaTranslator/scalemethod/base.py +++ b/LunaTranslator/LunaTranslator/scalemethod/base.py @@ -1,3 +1,6 @@ +from myutils.wrapper import threader + + class scalebase: def __init__(self, setuistatus) -> None: self._setuistatus = setuistatus @@ -12,18 +15,25 @@ class scalebase: self._setuistatus(current) self.full = not current + @threader def callstatuschange(self, hwnd): - self.hwnd = hwnd - self.changestatus(hwnd, self.full) - self.setuistatus(self.full) + self.callstatuschange_(hwnd) + def callstatuschange_(self, hwnd): + self.hwnd = hwnd + if self.changestatus(hwnd, self.full): + self.setuistatus(self.full) + + @threader def endX(self): - if not self.full and self.hwnd: - self.callstatuschange(self.hwnd) - self.end() - return True self.hasend = True - return False + ret = False + if not self.full and self.hwnd: + self.callstatuschange_(self.hwnd) + ret = True + self.end() + + return ret def changestatus(self, hwnd, full): raise Exception diff --git a/LunaTranslator/LunaTranslator/scalemethod/external_lossless.py b/LunaTranslator/LunaTranslator/scalemethod/external_lossless.py index 689bd14e..50bd0740 100644 --- a/LunaTranslator/LunaTranslator/scalemethod/external_lossless.py +++ b/LunaTranslator/LunaTranslator/scalemethod/external_lossless.py @@ -55,7 +55,7 @@ class Method(scalebase): os.environ["LOCALAPPDATA"], "Lossless Scaling/Settings.xml" ) if os.path.exists(configpath) == False: - return + return False with open(configpath, "r", encoding="utf8") as ff: config = ff.read() @@ -74,3 +74,4 @@ class Method(scalebase): windows.keybd_event(vkcode, 0, windows.KEYEVENTF_KEYUP, 0) for k in mods: windows.keybd_event(mp1[k], 0, windows.KEYEVENTF_KEYUP, 0) + return True \ No newline at end of file diff --git a/LunaTranslator/LunaTranslator/scalemethod/external_magpie.py b/LunaTranslator/LunaTranslator/scalemethod/external_magpie.py index 55d5cbaa..142526d1 100644 --- a/LunaTranslator/LunaTranslator/scalemethod/external_magpie.py +++ b/LunaTranslator/LunaTranslator/scalemethod/external_magpie.py @@ -48,7 +48,7 @@ class Method(scalebase): ): time.sleep(0.5) self.setuistatus(False) - + def changestatus(self, hwnd, full): configpath = os.path.join(globalconfig["magpiepath"], "config/config.json") @@ -74,7 +74,7 @@ class Method(scalebase): break if os.path.exists(configpath) == False: - return + return False with open(configpath, "r", encoding="utf8") as ff: config = json.load(ff) @@ -101,3 +101,4 @@ class Method(scalebase): for k in mp: if shortcuts & k != 0: windows.keybd_event(mp1[mp[k]], 0, windows.KEYEVENTF_KEYUP, 0) + return True \ No newline at end of file diff --git a/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py b/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py index ddcc0ee9..cd72b0e8 100644 --- a/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py +++ b/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py @@ -4,13 +4,43 @@ import windows from myutils.config import globalconfig, magpie_config from myutils.subproc import subproc_w from myutils.wrapper import threader +from winsharedutils import startmaglistener, endmaglistener class Method(scalebase): + def saveconfig(self): + with open(self.jspath, "w", encoding="utf-8") as ff: + ff.write( + json.dumps(magpie_config, ensure_ascii=False, sort_keys=False, indent=4) + ) + @threader - def _waitenginestop_magpie(self): - self.engine.wait() - self.setuistatus(False) + def statuslistener(self): + listener = windows.AutoHandle(startmaglistener()) + while not self.hasend: + status = windows.c_int.from_buffer_copy(windows.ReadFile(listener, 4)).value + self.setuistatus(status) + + endmaglistener(listener) + + def init(self): + self.statuslistener() + self.jspath = os.path.abspath("./cache/magpie.config.json") + self.engine = subproc_w( + './files/plugins/Magpie/Magpie.Core.exe "{}"'.format(self.jspath), + cwd="./files/plugins/Magpie/", + ) + waitsignal = "Magpie_notify_prepared_ok_" + str(self.engine.pid) + windows.WaitForSingleObject( + windows.AutoHandle(windows.CreateEvent(False, False, waitsignal)), + windows.INFINITE, + ) + + def end(self): + windows.SendMessage( + windows.FindWindow("WNDCLS_Magpie_Core_CLI_Message", None), + windows.RegisterWindowMessage("Magpie_Core_CLI_Message_Exit"), + ) def changestatus(self, hwnd, full): if full: @@ -18,22 +48,19 @@ class Method(scalebase): if profiles_index > len(magpie_config["profiles"]): profiles_index = 0 - jspath = os.path.abspath("./userconfig/magpie_config.json") - with open(jspath, "w", encoding="utf-8") as ff: - ff.write( - json.dumps( - magpie_config, ensure_ascii=False, sort_keys=False, indent=4 - ) - ) - self.engine = subproc_w( - './files/plugins/Magpie/Magpie.Core.exe {} {} "{}"'.format( - profiles_index, hwnd, jspath - ), - cwd="./files/plugins/Magpie/", + #显示帧率暂时有问题 + magpie_config["profiles"][profiles_index]["showFPS"] = False + + self.saveconfig() + windows.SendMessage( + windows.FindWindow("WNDCLS_Magpie_Core_CLI_Message", None), + windows.RegisterWindowMessage("Magpie_Core_CLI_Message_Start"), + profiles_index, + hwnd, ) - self._waitenginestop_magpie() else: windows.SendMessage( - windows.FindWindow("Magpie_Core_CLI_Message", None), + windows.FindWindow("WNDCLS_Magpie_Core_CLI_Message", None), windows.RegisterWindowMessage("Magpie_Core_CLI_Message_Stop"), ) + return False diff --git a/LunaTranslator/LunaTranslator/textsource/texthook.py b/LunaTranslator/LunaTranslator/textsource/texthook.py index bc412e08..db67a62d 100644 --- a/LunaTranslator/LunaTranslator/textsource/texthook.py +++ b/LunaTranslator/LunaTranslator/textsource/texthook.py @@ -228,7 +228,7 @@ class texthook(basetext): @threader def solveeventthread(self): while self.ending == False: - message = windows.ReadFile(self.hRead, sizeof(Message), None) + message = windows.ReadFile(self.hRead, sizeof(Message)) if len(message) != sizeof(Message): break message = Message.from_buffer_copy(message) @@ -426,7 +426,7 @@ class texthook(basetext): def ReadThread(hread): while True: - message = windows.ReadFile(hread, sizeof(simplehooks), None) + message = windows.ReadFile(hread, sizeof(simplehooks)) if len(message) != sizeof(simplehooks): break message = simplehooks.from_buffer_copy(message) diff --git a/LunaTranslator/LunaTranslator/translator/dreye.py b/LunaTranslator/LunaTranslator/translator/dreye.py index a70033ab..71bdd113 100644 --- a/LunaTranslator/LunaTranslator/translator/dreye.py +++ b/LunaTranslator/LunaTranslator/translator/dreye.py @@ -69,7 +69,7 @@ class TS(basetrans): continue windows.WriteFile(self.hPipe, line.encode(codes[self.srclang])) ress.append( - windows.ReadFile(self.hPipe, 4096, None).decode(codes[self.tgtlang]) + windows.ReadFile(self.hPipe, 4096).decode(codes[self.tgtlang]) ) return "\n".join(ress) diff --git a/LunaTranslator/LunaTranslator/translator/jb7.py b/LunaTranslator/LunaTranslator/translator/jb7.py index 52abbf20..a8d2f073 100644 --- a/LunaTranslator/LunaTranslator/translator/jb7.py +++ b/LunaTranslator/LunaTranslator/translator/jb7.py @@ -96,7 +96,7 @@ class TS(basetrans): continue code1 = line.encode("utf-16-le") windows.WriteFile(self.hPipe, self.packuint32(int(self.tgtlang)) + code1) - xx = windows.ReadFile(self.hPipe, 65535, None) + xx = windows.ReadFile(self.hPipe, 65535) xx = xx.decode("utf-16-le", errors="ignore") ress.append(xx) return "\n".join(ress) diff --git a/LunaTranslator/LunaTranslator/translator/kingsoft.py b/LunaTranslator/LunaTranslator/translator/kingsoft.py index 8c59562b..4aee54b1 100644 --- a/LunaTranslator/LunaTranslator/translator/kingsoft.py +++ b/LunaTranslator/LunaTranslator/translator/kingsoft.py @@ -71,7 +71,7 @@ class TS(basetrans): if len(line) == 0: continue windows.WriteFile(self.hPipe, line.encode("utf-16-le")) - x = windows.ReadFile(self.hPipe, 4096, None) + x = windows.ReadFile(self.hPipe, 4096) ress.append(x.decode("utf-16-le")) return "\n".join(ress) diff --git a/LunaTranslator/LunaTranslator/tts/NeoSpeech.py b/LunaTranslator/LunaTranslator/tts/NeoSpeech.py index b8fca5de..942aab5e 100644 --- a/LunaTranslator/LunaTranslator/tts/NeoSpeech.py +++ b/LunaTranslator/LunaTranslator/tts/NeoSpeech.py @@ -85,6 +85,6 @@ class TTS(TTSbase): windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(rate))) buf = ctypes.create_unicode_buffer(content, 10000) windows.WriteFile(self.hPipe, bytes(buf)) - fname = windows.ReadFile(self.hPipe, 1024, None).decode("utf-16-le") + fname = windows.ReadFile(self.hPipe, 1024).decode("utf-16-le") if os.path.exists(fname): return fname diff --git a/LunaTranslator/LunaTranslator/tts/voiceroid2.py b/LunaTranslator/LunaTranslator/tts/voiceroid2.py index 74158d6a..d4e845b9 100644 --- a/LunaTranslator/LunaTranslator/tts/voiceroid2.py +++ b/LunaTranslator/LunaTranslator/tts/voiceroid2.py @@ -139,6 +139,6 @@ class TTS(TTSbase): # print(code1) windows.WriteFile(self.hPipe, code1) - fname = windows.ReadFile(self.hPipe, 1024, None).decode("utf8") + fname = windows.ReadFile(self.hPipe, 1024).decode("utf8") if os.path.exists(fname): return fname diff --git a/LunaTranslator/LunaTranslator/tts/voiceroidplus.py b/LunaTranslator/LunaTranslator/tts/voiceroidplus.py index 145e1958..31e5c7a1 100644 --- a/LunaTranslator/LunaTranslator/tts/voiceroidplus.py +++ b/LunaTranslator/LunaTranslator/tts/voiceroidplus.py @@ -129,6 +129,6 @@ class TTS(TTSbase): # print(code1) windows.WriteFile(self.hPipe, code1) - fname = windows.ReadFile(self.hPipe, 1024, None).decode("utf8") + fname = windows.ReadFile(self.hPipe, 1024).decode("utf8") if os.path.exists(fname): return fname diff --git a/LunaTranslator/LunaTranslator/windows.py b/LunaTranslator/LunaTranslator/windows.py index 8b5ff48a..77fee1e7 100644 --- a/LunaTranslator/LunaTranslator/windows.py +++ b/LunaTranslator/LunaTranslator/windows.py @@ -533,8 +533,8 @@ def CloseHandle(handle): return _CloseHandle(handle) -def SendMessage(hwnd, message): - return _SendMessage(hwnd, message, 0, 0) +def SendMessage(hwnd, message, wp=None, lp=None): + return _SendMessage(hwnd, message, wp, lp) def keybd_event(bVk, bScan, dwFlags, _): @@ -671,7 +671,7 @@ _ReadFile = _kernel32.ReadFile _ReadFile.argtypes = HANDLE, c_char_p, c_uint, c_void_p, c_void_p -def ReadFile(handle, nNumberOfBytesToRead, lpOverlapped): +def ReadFile(handle, nNumberOfBytesToRead, lpOverlapped=None): buf = create_string_buffer(nNumberOfBytesToRead) dwread = c_int() _ReadFile(handle, buf, nNumberOfBytesToRead, pointer(dwread), lpOverlapped) @@ -940,3 +940,12 @@ _CopyFile.restype = BOOL def CopyFile(src, dst, bFailIfExists): return _CopyFile(src, dst, bFailIfExists) + + +_SetPropW = _user32.SetPropW +_SetPropW.argtypes = HWND, LPCWSTR, HANDLE +_SetPropW.restype = BOOL + + +def SetProp(hwnd, string, hdata): + return _SetPropW(hwnd, string, hdata) diff --git a/LunaTranslator/LunaTranslator/winsharedutils.py b/LunaTranslator/LunaTranslator/winsharedutils.py index 946f88d1..66b25d27 100644 --- a/LunaTranslator/LunaTranslator/winsharedutils.py +++ b/LunaTranslator/LunaTranslator/winsharedutils.py @@ -347,3 +347,8 @@ Is64bit.restype = c_bool isDark = utilsdll.isDark isDark.restype = c_bool + +startmaglistener = utilsdll.startmaglistener +startmaglistener.restype = HANDLE +endmaglistener = utilsdll.endmaglistener +endmaglistener.argtypes = (HANDLE,) diff --git a/plugins/winsharedutils/CMakeLists.txt b/plugins/winsharedutils/CMakeLists.txt index 89c9be45..f5f4ed4e 100644 --- a/plugins/winsharedutils/CMakeLists.txt +++ b/plugins/winsharedutils/CMakeLists.txt @@ -2,7 +2,7 @@ project(winsharedutils) -add_library(winsharedutils MODULE hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp) +add_library(winsharedutils MODULE hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp cinterface.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp) target_link_libraries(winsharedutils dwmapi) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64") diff --git a/plugins/winsharedutils/maglistener.cpp b/plugins/winsharedutils/maglistener.cpp new file mode 100644 index 00000000..79834e31 --- /dev/null +++ b/plugins/winsharedutils/maglistener.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include "define.h" + +static UINT WM_MAGPIE_SCALINGCHANGED = RegisterWindowMessage(L"MagpieScalingChanged"); +static HWND listener = 0; +static HANDLE hwrite = 0; + +DECLARE HANDLE startmaglistener() +{ + ChangeWindowMessageFilter(WM_MAGPIE_SCALINGCHANGED, MSGFLT_ADD); + auto CLASS_NAME = L"MagpieWatcher"; + WNDCLASS wc = {}; + wc.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) + { + if (message == WM_MAGPIE_SCALINGCHANGED && hwrite) + { + int send = wParam; + DWORD _; + WriteFile(hwrite, &send, 4, &_, 0); + } + switch (message) + { + + case WM_DESTROY: + { + CloseHandle(hwrite); + PostQuitMessage(0); + } + } + return DefWindowProc(hWnd, message, wParam, lParam); + }; + wc.hInstance = GetModuleHandle(0); + wc.lpszClassName = CLASS_NAME; + static auto _ = RegisterClass(&wc); + HANDLE hread; + CreatePipe(&hread, &hwrite, 0, 0); + + std::thread([=]() + { + listener = CreateWindowEx( + WS_EX_CLIENTEDGE, CLASS_NAME, CLASS_NAME, WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, + NULL, NULL, GetModuleHandle(0), hwrite);; + MSG msg = {}; + while (GetMessage(&msg, NULL, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } }) + .detach(); + + return hread; +} +DECLARE void endmaglistener(HANDLE hread) +{ + if (listener) + { + DestroyWindow(listener); + listener = 0; + hwrite = 0; + } +} \ No newline at end of file