This commit is contained in:
恍兮惚兮 2024-04-26 00:40:07 +08:00
parent 77649c0e7b
commit f762155fdf
21 changed files with 198 additions and 57 deletions

View File

@ -21,6 +21,9 @@ from myutils.utils import (
getfilemd5, getfilemd5,
stringfyerror, stringfyerror,
) )
import os, hashlib
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import Qt, QSize, QObject, QEvent
from myutils.wrapper import threader from myutils.wrapper import threader
from gui.showword import searchwordW from gui.showword import searchwordW
from myutils.hwnd import getpidexe, testprivilege, ListProcess from myutils.hwnd import getpidexe, testprivilege, ListProcess
@ -754,6 +757,30 @@ class MAINUI:
time.sleep(0.5) time.sleep(0.5)
def aa(self): 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 = gui.translatorUI.QUnFrameWindow()
self.translation_ui.show() self.translation_ui.show()

View File

@ -259,20 +259,8 @@ class Settin(closeashidewindow):
dark = isDark() dark = isDark()
darklight = ["light", "dark"][dark] darklight = ["light", "dark"][dark]
class WindowEventFilter(QObject): gobject.baseobject.currentisdark = dark
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
self.__filter = WindowEventFilter() # keep ref
QApplication.instance().installEventFilter(self.__filter)
for widget in QApplication.topLevelWidgets(): for widget in QApplication.topLevelWidgets():
if widget.testAttribute(Qt.WA_TranslucentBackground): if widget.testAttribute(Qt.WA_TranslucentBackground):
continue continue

View File

@ -41,10 +41,11 @@ def setTab_quick_direct(self):
"_21": lambda: grabwindow(), "_21": lambda: grabwindow(),
"_22": gobject.baseobject.translation_ui.muteprocessignal.emit, "_22": gobject.baseobject.translation_ui.muteprocessignal.emit,
"_23": lambda: gobject.baseobject.translation_ui.clickRange_signal.emit(True), "_23": lambda: gobject.baseobject.translation_ui.clickRange_signal.emit(True),
"_25": lambda: windows.SendMessage( # 暂时有问题
windows.FindWindow("Magpie_Core_CLI_Message", None), # "_25": lambda: windows.SendMessage(
windows.RegisterWindowMessage("Magpie_Core_CLI_Message_ToggleOverlay"), # windows.FindWindow("WNDCLS_Magpie_Core_CLI_Message", None),
), # windows.RegisterWindowMessage("Magpie_Core_CLI_Message_ToggleOverlay"),
# ),
"_26": gobject.baseobject.translation_ui.ocr_once_signal.emit, "_26": gobject.baseobject.translation_ui.ocr_once_signal.emit,
"_27": gobject.baseobject.translation_ui.simulate_key_enter, "_27": gobject.baseobject.translation_ui.simulate_key_enter,
} }

View File

@ -657,6 +657,7 @@ class QUnFrameWindow(resizableframeless):
self.casthira2kata = str.maketrans( self.casthira2kata = str.maketrans(
static_data["allhira"], static_data["allkata"] static_data["allhira"], static_data["allkata"]
) )
self.fullscreenmanager_busy = False
self.isletgamefullscreened = False self.isletgamefullscreened = False
self.fullscreenmanager = None self.fullscreenmanager = None
self.fullscreenmethod = None self.fullscreenmethod = None
@ -725,7 +726,11 @@ class QUnFrameWindow(resizableframeless):
self.isletgamefullscreened = current self.isletgamefullscreened = current
self.refreshtooliconsignal.emit() self.refreshtooliconsignal.emit()
@threader
def _fullsgame(self): def _fullsgame(self):
if self.fullscreenmanager_busy:
return
self.fullscreenmanager_busy = True
try: try:
if gobject.baseobject.textsource and gobject.baseobject.textsource.hwnd: if gobject.baseobject.textsource and gobject.baseobject.textsource.hwnd:
_hwnd = gobject.baseobject.textsource.hwnd _hwnd = gobject.baseobject.textsource.hwnd
@ -756,6 +761,7 @@ class QUnFrameWindow(resizableframeless):
) # , self.isletgamefullscreened) ) # , self.isletgamefullscreened)
except: except:
print_exc() print_exc()
self.fullscreenmanager_busy = False
def changemousetransparentstate(self, idx): def changemousetransparentstate(self, idx):
if idx == 0: if idx == 0:

View File

@ -8,3 +8,4 @@ class Method(scalebase):
self.savewindowstatus = letfullscreen(hwnd) self.savewindowstatus = letfullscreen(hwnd)
else: else:
recoverwindow(hwnd, self.savewindowstatus) recoverwindow(hwnd, self.savewindowstatus)
return True

View File

@ -10,3 +10,4 @@ class Method(scalebase):
windows.keybd_event(13, 0, windows.KEYEVENTF_KEYUP, 0) windows.keybd_event(13, 0, windows.KEYEVENTF_KEYUP, 0)
windows.keybd_event(18, 0, windows.KEYEVENTF_KEYUP, 0) windows.keybd_event(18, 0, windows.KEYEVENTF_KEYUP, 0)
return True

View File

@ -1,3 +1,6 @@
from myutils.wrapper import threader
class scalebase: class scalebase:
def __init__(self, setuistatus) -> None: def __init__(self, setuistatus) -> None:
self._setuistatus = setuistatus self._setuistatus = setuistatus
@ -12,18 +15,25 @@ class scalebase:
self._setuistatus(current) self._setuistatus(current)
self.full = not current self.full = not current
@threader
def callstatuschange(self, hwnd): def callstatuschange(self, hwnd):
self.hwnd = hwnd self.callstatuschange_(hwnd)
self.changestatus(hwnd, self.full)
self.setuistatus(self.full)
def callstatuschange_(self, hwnd):
self.hwnd = hwnd
if self.changestatus(hwnd, self.full):
self.setuistatus(self.full)
@threader
def endX(self): def endX(self):
if not self.full and self.hwnd:
self.callstatuschange(self.hwnd)
self.end()
return True
self.hasend = 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): def changestatus(self, hwnd, full):
raise Exception raise Exception

View File

@ -55,7 +55,7 @@ class Method(scalebase):
os.environ["LOCALAPPDATA"], "Lossless Scaling/Settings.xml" os.environ["LOCALAPPDATA"], "Lossless Scaling/Settings.xml"
) )
if os.path.exists(configpath) == False: if os.path.exists(configpath) == False:
return return False
with open(configpath, "r", encoding="utf8") as ff: with open(configpath, "r", encoding="utf8") as ff:
config = ff.read() config = ff.read()
@ -74,3 +74,4 @@ class Method(scalebase):
windows.keybd_event(vkcode, 0, windows.KEYEVENTF_KEYUP, 0) windows.keybd_event(vkcode, 0, windows.KEYEVENTF_KEYUP, 0)
for k in mods: for k in mods:
windows.keybd_event(mp1[k], 0, windows.KEYEVENTF_KEYUP, 0) windows.keybd_event(mp1[k], 0, windows.KEYEVENTF_KEYUP, 0)
return True

View File

@ -48,7 +48,7 @@ class Method(scalebase):
): ):
time.sleep(0.5) time.sleep(0.5)
self.setuistatus(False) self.setuistatus(False)
def changestatus(self, hwnd, full): def changestatus(self, hwnd, full):
configpath = os.path.join(globalconfig["magpiepath"], "config/config.json") configpath = os.path.join(globalconfig["magpiepath"], "config/config.json")
@ -74,7 +74,7 @@ class Method(scalebase):
break break
if os.path.exists(configpath) == False: if os.path.exists(configpath) == False:
return return False
with open(configpath, "r", encoding="utf8") as ff: with open(configpath, "r", encoding="utf8") as ff:
config = json.load(ff) config = json.load(ff)
@ -101,3 +101,4 @@ class Method(scalebase):
for k in mp: for k in mp:
if shortcuts & k != 0: if shortcuts & k != 0:
windows.keybd_event(mp1[mp[k]], 0, windows.KEYEVENTF_KEYUP, 0) windows.keybd_event(mp1[mp[k]], 0, windows.KEYEVENTF_KEYUP, 0)
return True

View File

@ -4,13 +4,43 @@ import windows
from myutils.config import globalconfig, magpie_config from myutils.config import globalconfig, magpie_config
from myutils.subproc import subproc_w from myutils.subproc import subproc_w
from myutils.wrapper import threader from myutils.wrapper import threader
from winsharedutils import startmaglistener, endmaglistener
class Method(scalebase): 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 @threader
def _waitenginestop_magpie(self): def statuslistener(self):
self.engine.wait() listener = windows.AutoHandle(startmaglistener())
self.setuistatus(False) 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): def changestatus(self, hwnd, full):
if full: if full:
@ -18,22 +48,19 @@ class Method(scalebase):
if profiles_index > len(magpie_config["profiles"]): if profiles_index > len(magpie_config["profiles"]):
profiles_index = 0 profiles_index = 0
jspath = os.path.abspath("./userconfig/magpie_config.json") #显示帧率暂时有问题
with open(jspath, "w", encoding="utf-8") as ff: magpie_config["profiles"][profiles_index]["showFPS"] = False
ff.write(
json.dumps( self.saveconfig()
magpie_config, ensure_ascii=False, sort_keys=False, indent=4 windows.SendMessage(
) windows.FindWindow("WNDCLS_Magpie_Core_CLI_Message", None),
) windows.RegisterWindowMessage("Magpie_Core_CLI_Message_Start"),
self.engine = subproc_w( profiles_index,
'./files/plugins/Magpie/Magpie.Core.exe {} {} "{}"'.format( hwnd,
profiles_index, hwnd, jspath
),
cwd="./files/plugins/Magpie/",
) )
self._waitenginestop_magpie()
else: else:
windows.SendMessage( windows.SendMessage(
windows.FindWindow("Magpie_Core_CLI_Message", None), windows.FindWindow("WNDCLS_Magpie_Core_CLI_Message", None),
windows.RegisterWindowMessage("Magpie_Core_CLI_Message_Stop"), windows.RegisterWindowMessage("Magpie_Core_CLI_Message_Stop"),
) )
return False

View File

@ -228,7 +228,7 @@ class texthook(basetext):
@threader @threader
def solveeventthread(self): def solveeventthread(self):
while self.ending == False: while self.ending == False:
message = windows.ReadFile(self.hRead, sizeof(Message), None) message = windows.ReadFile(self.hRead, sizeof(Message))
if len(message) != sizeof(Message): if len(message) != sizeof(Message):
break break
message = Message.from_buffer_copy(message) message = Message.from_buffer_copy(message)
@ -426,7 +426,7 @@ class texthook(basetext):
def ReadThread(hread): def ReadThread(hread):
while True: while True:
message = windows.ReadFile(hread, sizeof(simplehooks), None) message = windows.ReadFile(hread, sizeof(simplehooks))
if len(message) != sizeof(simplehooks): if len(message) != sizeof(simplehooks):
break break
message = simplehooks.from_buffer_copy(message) message = simplehooks.from_buffer_copy(message)

View File

@ -69,7 +69,7 @@ class TS(basetrans):
continue continue
windows.WriteFile(self.hPipe, line.encode(codes[self.srclang])) windows.WriteFile(self.hPipe, line.encode(codes[self.srclang]))
ress.append( 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) return "\n".join(ress)

View File

@ -96,7 +96,7 @@ class TS(basetrans):
continue continue
code1 = line.encode("utf-16-le") code1 = line.encode("utf-16-le")
windows.WriteFile(self.hPipe, self.packuint32(int(self.tgtlang)) + code1) 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") xx = xx.decode("utf-16-le", errors="ignore")
ress.append(xx) ress.append(xx)
return "\n".join(ress) return "\n".join(ress)

View File

@ -71,7 +71,7 @@ class TS(basetrans):
if len(line) == 0: if len(line) == 0:
continue continue
windows.WriteFile(self.hPipe, line.encode("utf-16-le")) 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")) ress.append(x.decode("utf-16-le"))
return "\n".join(ress) return "\n".join(ress)

View File

@ -85,6 +85,6 @@ class TTS(TTSbase):
windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(rate))) windows.WriteFile(self.hPipe, bytes(ctypes.c_uint(rate)))
buf = ctypes.create_unicode_buffer(content, 10000) buf = ctypes.create_unicode_buffer(content, 10000)
windows.WriteFile(self.hPipe, bytes(buf)) 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): if os.path.exists(fname):
return fname return fname

View File

@ -139,6 +139,6 @@ class TTS(TTSbase):
# print(code1) # print(code1)
windows.WriteFile(self.hPipe, 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): if os.path.exists(fname):
return fname return fname

View File

@ -129,6 +129,6 @@ class TTS(TTSbase):
# print(code1) # print(code1)
windows.WriteFile(self.hPipe, 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): if os.path.exists(fname):
return fname return fname

View File

@ -533,8 +533,8 @@ def CloseHandle(handle):
return _CloseHandle(handle) return _CloseHandle(handle)
def SendMessage(hwnd, message): def SendMessage(hwnd, message, wp=None, lp=None):
return _SendMessage(hwnd, message, 0, 0) return _SendMessage(hwnd, message, wp, lp)
def keybd_event(bVk, bScan, dwFlags, _): 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 _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) buf = create_string_buffer(nNumberOfBytesToRead)
dwread = c_int() dwread = c_int()
_ReadFile(handle, buf, nNumberOfBytesToRead, pointer(dwread), lpOverlapped) _ReadFile(handle, buf, nNumberOfBytesToRead, pointer(dwread), lpOverlapped)
@ -940,3 +940,12 @@ _CopyFile.restype = BOOL
def CopyFile(src, dst, bFailIfExists): def CopyFile(src, dst, bFailIfExists):
return _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)

View File

@ -347,3 +347,8 @@ Is64bit.restype = c_bool
isDark = utilsdll.isDark isDark = utilsdll.isDark
isDark.restype = c_bool isDark.restype = c_bool
startmaglistener = utilsdll.startmaglistener
startmaglistener.restype = HANDLE
endmaglistener = utilsdll.endmaglistener
endmaglistener.argtypes = (HANDLE,)

View File

@ -2,7 +2,7 @@
project(winsharedutils) 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) target_link_libraries(winsharedutils dwmapi)
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64") set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64")

View File

@ -0,0 +1,64 @@
#include <windows.h>
#include <thread>
#include <string>
#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;
}
}