diff --git a/cpp/LunaHook/LunaHook/engine32/utawarerumono.cpp b/cpp/LunaHook/LunaHook/engine32/utawarerumono.cpp index d2fa83e0..2dd2647d 100644 --- a/cpp/LunaHook/LunaHook/engine32/utawarerumono.cpp +++ b/cpp/LunaHook/LunaHook/engine32/utawarerumono.cpp @@ -1,55 +1,61 @@ -#include"utawarerumono.h" +#include "utawarerumono.h" -bool utawarerumonoh() { +bool utawarerumonoh() +{ const BYTE bytes[] = { - 0x80,XX,0x5C, + 0x80, XX, 0x5C, 0x75 - //*a2 != 92 || a2[1] != 107 + //*a2 != 92 || a2[1] != 107 }; const BYTE bytes2[] = { - 0x80,XX,XX,XX,0x5C, - 0x75 - }; + 0x80, XX, XX, XX, 0x5C, + 0x75}; auto addr1 = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress); auto addr2 = MemDbg::findBytes(bytes2, sizeof(bytes2), processStartAddress, processStopAddress); - auto succ=false; - for (auto addr : { addr1,addr2 }) { - if (addr == 0)continue; + auto succ = false; + for (auto addr : {addr1, addr2}) + { + if (addr == 0) + continue; const BYTE funcstart[] = { - 0x51,0x53 - }; + 0x51, 0x53}; addr = reverseFindBytes(funcstart, sizeof(funcstart), addr - 0x100, addr); - if (addr == 0)return false; + if (addr == 0) + return false; HookParam hp; hp.address = addr; - hp.offset=get_stack(1); + hp.newlineseperator = L"\\n"; + hp.offset = get_stack(1); hp.type = CODEC_UTF8 | USING_STRING | NO_CONTEXT; ConsoleOutput("utawarerumono"); - succ|=NewHook(hp, "utawarerumono"); - } + succ |= NewHook(hp, "utawarerumono"); + } return succ; } -bool utawarerumonoh2() { +bool utawarerumonoh2() +{ const BYTE bytes2[] = { - 0x8b,0xca, - 0xc1,0xe9,0x02, - 0xf3,0xa5 - }; - auto addr2 = Util::SearchMemory(bytes2, sizeof(bytes2),PAGE_EXECUTE, processStartAddress, processStopAddress); - auto succ=false; - for (auto addr : addr2) { + 0x8b, 0xca, + 0xc1, 0xe9, 0x02, + 0xf3, 0xa5}; + auto addr2 = Util::SearchMemory(bytes2, sizeof(bytes2), PAGE_EXECUTE, processStartAddress, processStopAddress); + auto succ = false; + for (auto addr : addr2) + { HookParam hp; - hp.address = addr+2; - hp.offset=get_reg(regs::esi); - hp.type = CODEC_UTF8 | USING_STRING|NO_CONTEXT; - ConsoleOutput("utawarerumono %p",addr); - succ|=NewHook(hp, "utawarerumono"); + hp.address = addr + 2; + hp.offset = get_reg(regs::esi); + hp.type = CODEC_UTF8 | USING_STRING | NO_CONTEXT; + hp.newlineseperator = L"\\n"; + ConsoleOutput("utawarerumono %p", addr); + succ |= NewHook(hp, "utawarerumono"); } return succ; } -bool utawarerumono::attach_function() { - bool b1=utawarerumonoh(); - bool b2=utawarerumonoh2(); - return b1||b2; -} \ No newline at end of file +bool utawarerumono::attach_function() +{ + bool b1 = utawarerumonoh(); + bool b2 = utawarerumonoh2(); + return b1 || b2; +} \ No newline at end of file diff --git a/cpp/version.cmake b/cpp/version.cmake index fb352884..23e8c1ad 100644 --- a/cpp/version.cmake +++ b/cpp/version.cmake @@ -1,7 +1,7 @@ set(VERSION_MAJOR 5) -set(VERSION_MINOR 57) -set(VERSION_PATCH 4) +set(VERSION_MINOR 58) +set(VERSION_PATCH 0) set(VERSION_REVISION 0) add_definitions(-DVERSION_MAJOR=${VERSION_MAJOR}) add_definitions(-DVERSION_MINOR=${VERSION_MINOR}) diff --git a/cpp/winsharedutils/webview2_extra.cpp b/cpp/winsharedutils/webview2_extra.cpp index dffa2512..d2df2d78 100644 --- a/cpp/winsharedutils/webview2_extra.cpp +++ b/cpp/winsharedutils/webview2_extra.cpp @@ -11,31 +11,35 @@ using namespace Microsoft::WRL; if (FAILED((x))) \ return x; -DECLARE_API void set_transparent_background(void* m_host){ +DECLARE_API void set_transparent_background(void *m_host) +{ COREWEBVIEW2_COLOR color; - ZeroMemory(&color,sizeof(color)); + ZeroMemory(&color, sizeof(color)); wil::com_ptr m_controller(reinterpret_cast(m_host)); wil::com_ptr coreWebView2 = - m_controller.try_query(); - if(coreWebView2){ + m_controller.try_query(); + if (coreWebView2) + { coreWebView2->put_DefaultBackgroundColor(color); } } -DECLARE_API HRESULT put_PreferredColorScheme(void *m_host, COREWEBVIEW2_PREFERRED_COLOR_SCHEME scheme) +DECLARE_API void put_PreferredColorScheme(void *m_host, COREWEBVIEW2_PREFERRED_COLOR_SCHEME scheme) { - wil::com_ptr m_controller(reinterpret_cast(m_host)); wil::com_ptr coreWebView2; - CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2)); - auto webView2_13 = coreWebView2.try_query(); - if (webView2_13) + [&]() { - wil::com_ptr profile; - CHECK_FAILURE(webView2_13->get_Profile(&profile)); - CHECK_FAILURE(profile->put_PreferredColorScheme(scheme)); - } - return S_FALSE; + CHECK_FAILURE(m_controller->get_CoreWebView2(&coreWebView2)); + auto webView2_13 = coreWebView2.try_query(); + if (webView2_13) + { + wil::com_ptr profile; + CHECK_FAILURE(webView2_13->get_Profile(&profile)); + CHECK_FAILURE(profile->put_PreferredColorScheme(scheme)); + } + return S_OK; + }(); } DECLARE_API void *add_ZoomFactorChanged(void *m_host, void (*signal)(double)) { @@ -60,9 +64,9 @@ DECLARE_API void *add_ZoomFactorChanged(void *m_host, void (*signal)(double)) } DECLARE_API void remove_ZoomFactorChanged(void *m_host, void *m_zoomFactorChangedToken) { - - reinterpret_cast(m_host)->remove_ZoomFactorChanged(*reinterpret_cast(m_zoomFactorChangedToken)); - delete m_zoomFactorChangedToken; + auto token = reinterpret_cast(m_zoomFactorChangedToken); + reinterpret_cast(m_host)->remove_ZoomFactorChanged(*token); + delete token; } DECLARE_API double get_ZoomFactor(void *m_host) { @@ -73,4 +77,86 @@ DECLARE_API double get_ZoomFactor(void *m_host) DECLARE_API void put_ZoomFactor(void *m_host, double zoomFactor) { reinterpret_cast(m_host)->put_ZoomFactor(zoomFactor); +} +// https://github.com/MicrosoftEdge/WebView2Feedback/blob/main/specs/WebMessageObjects.md +DECLARE_API void remove_WebMessageReceived(void *m_host, void *m_webMessageReceivedToken) +{ + auto token = reinterpret_cast(m_webMessageReceivedToken); + wil::com_ptr m_controller(reinterpret_cast(m_host)); + wil::com_ptr m_webView; + [&]() + { + CHECK_FAILURE(m_controller->get_CoreWebView2(&m_webView)); + CHECK_FAILURE(m_webView->remove_WebMessageReceived(*token)); + return S_OK; + }(); + delete token; +} + +DECLARE_API void *add_WebMessageReceived(void *m_host, void (*callback)(const wchar_t *)) +{ + wil::com_ptr m_controller(reinterpret_cast(m_host)); + wil::com_ptr coreWebView4 = + m_controller.try_query(); + if (coreWebView4) + { + coreWebView4->put_AllowExternalDrop(true); + } + wil::com_ptr m_webView; + EventRegistrationToken *m_webMessageReceivedToken = new EventRegistrationToken; + [&]() + { + CHECK_FAILURE(m_controller->get_CoreWebView2(&m_webView)); + CHECK_FAILURE(m_webView->add_WebMessageReceived( + Callback( + [=](ICoreWebView2 *sender, ICoreWebView2WebMessageReceivedEventArgs *args) noexcept + { + wil::unique_cotaskmem_string message; + CHECK_FAILURE(args->TryGetWebMessageAsString(&message)); + if (std::wstring(L"FilesDropped") == message.get()) + { + wil::com_ptr args2 = + wil::com_ptr(args) + .query(); + if (args2) + { + wil::com_ptr + objectsCollection; + CHECK_FAILURE(args2->get_AdditionalObjects(&objectsCollection)); + unsigned int length; + CHECK_FAILURE(objectsCollection->get_Count(&length)); + std::vector paths; + + for (unsigned int i = 0; i < length; i++) + { + wil::com_ptr object; + CHECK_FAILURE(objectsCollection->GetValueAtIndex(i, &object)); + // Note that objects can be null. + if (object) + { + wil::com_ptr file = + object.query(); + if (file) + { + // Add the file to message to be sent back to webview + wil::unique_cotaskmem_string path; + CHECK_FAILURE(file->get_Path(&path)); + paths.push_back(path.get()); + } + } + } + // ProcessPaths(paths); + if (paths.size()) + { + callback(paths[0].c_str()); + } + } + } + return S_OK; + }) + .Get(), + m_webMessageReceivedToken)); + return S_OK; + }(); + return m_webMessageReceivedToken; } \ No newline at end of file diff --git a/py/LunaTranslator/LunaTranslator.py b/py/LunaTranslator/LunaTranslator.py index 8f2b7c90..1c447a0e 100644 --- a/py/LunaTranslator/LunaTranslator.py +++ b/py/LunaTranslator/LunaTranslator.py @@ -12,7 +12,6 @@ from myutils.config import ( set_font_default, _TR, ) -from ctypes import c_int, CFUNCTYPE, c_void_p from myutils.utils import ( minmaxmoveobservefunc, parsemayberegexreplace, @@ -260,7 +259,6 @@ class MAINUI: return else: msgs = [ - ("", False, False), ("", False, True), ("", True, False), ("", True, True), @@ -1099,7 +1097,9 @@ class MAINUI: threading.Thread( target=minmaxmoveobservefunc, args=(self.translation_ui,) ).start() - self.messagecallback__ = CFUNCTYPE(None, c_int, c_void_p)(self.messagecallback) + self.messagecallback__ = winsharedutils.globalmessagelistener_cb( + self.messagecallback + ) winsharedutils.globalmessagelistener(self.messagecallback__) self.inittray() self.playtimemanager = playtimemanager() diff --git a/py/LunaTranslator/LunaTranslator_main.py b/py/LunaTranslator/LunaTranslator_main.py index 4ca7bc8f..4affada6 100644 --- a/py/LunaTranslator/LunaTranslator_main.py +++ b/py/LunaTranslator/LunaTranslator_main.py @@ -1,5 +1,4 @@ import sys, os -from ctypes import windll, wintypes def dopathexists(file: str): @@ -12,10 +11,7 @@ def dopathexists(file: str): file = windows.check_maybe_unc_file(file) if not file: return False - PathFileExists = windll.Shlwapi.PathFileExistsW - PathFileExists.argtypes = (wintypes.LPCWSTR,) - PathFileExists.restype = wintypes.BOOL - return bool(PathFileExists(os.path.abspath(file))) + return bool(windows.PathFileExists(os.path.abspath(file))) def overridepathexists(): @@ -28,7 +24,7 @@ def prepareqtenv(): # win7 no vcredist2015 windows.addenvpath("./files/runtime/") - windows.loadlibrary("./files/runtime/PyQt5/Qt5/bin/Qt5Core.dll") + windows.LoadLibraryW("./files/runtime/PyQt5/Qt5/bin/Qt5Core.dll") from qtsymbols import QApplication, isqt5, Qt, QFont, QLocale diff --git a/py/LunaTranslator/gui/rangeselect.py b/py/LunaTranslator/gui/rangeselect.py index 57f76a8b..698b805c 100644 --- a/py/LunaTranslator/gui/rangeselect.py +++ b/py/LunaTranslator/gui/rangeselect.py @@ -176,6 +176,7 @@ class rangeselect(QMainWindow): self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground) self.backlabel = QLabel(self) self.rectlabel = QLabel(self) + self.backlabel.move(0, 0) # self.setWindowOpacity(0.5) self.setMouseTracking(True) self.setCursor(Qt.CursorShape.CrossCursor) @@ -183,7 +184,6 @@ class rangeselect(QMainWindow): def reset(self): winsharedutils.maximum_window(int(self.winId())) - winsharedutils.maximum_window(int(self.backlabel.winId())) self.once = True self.is_drawing = False self.start_point = QPoint() @@ -200,6 +200,9 @@ class rangeselect(QMainWindow): "background-color: rgba(255,255,255, %s)" % globalconfig["ocrselectalpha"] ) + def resizeEvent(self, e: QResizeEvent): + self.backlabel.resize(e.size()) + def paintEvent(self, event): if self.is_drawing: @@ -224,7 +227,7 @@ class rangeselect(QMainWindow): def mousePressEvent(self, event): if event.button() == Qt.MouseButton.RightButton: - self.once = False + self.once = False self.close() elif event.button() == Qt.MouseButton.LeftButton: if self.startauto: diff --git a/py/LunaTranslator/gui/textbrowser.py b/py/LunaTranslator/gui/textbrowser.py index 49a56a2e..aadf6aa0 100644 --- a/py/LunaTranslator/gui/textbrowser.py +++ b/py/LunaTranslator/gui/textbrowser.py @@ -1,6 +1,6 @@ from qtsymbols import * from myutils.config import globalconfig -import importlib, copy +import importlib, copy, os from webviewpy import webview_exception from gui.usefulwidget import getQMessageBox from traceback import print_exc @@ -8,6 +8,7 @@ from traceback import print_exc class Textbrowser(QFrame): contentsChanged = pyqtSignal(QSize) + dropfilecallback = pyqtSignal(str) def resizeEvent(self, event: QResizeEvent): self.textbrowser.resize(event.size()) @@ -24,6 +25,7 @@ class Textbrowser(QFrame): if self.textbrowser: self.textbrowser.hide() self.textbrowser.contentsChanged.disconnect() + self.textbrowser.dropfilecallback.disconnect() self.textbrowser.deleteLater() if __ == "QWebEngine": __ = "webview" @@ -51,6 +53,7 @@ class Textbrowser(QFrame): self.textbrowser.move(0, 0) self.textbrowser.setMouseTracking(True) self.textbrowser.contentsChanged.connect(self._contentsChanged) + self.textbrowser.dropfilecallback.connect(self.normdropfilepath) self.textbrowser.resize(size) self.textbrowser.show() self.textbrowser.setselectable(globalconfig["selectable"]) @@ -59,6 +62,9 @@ class Textbrowser(QFrame): self.textbrowser.showhidetranslate(globalconfig["showfanyi"]) self.refreshcontent() + def normdropfilepath(self, file): + self.dropfilecallback.emit(os.path.normpath(file)) + def refreshcontent(self): traces = self.trace.copy() self.clear() diff --git a/py/LunaTranslator/gui/translatorUI.py b/py/LunaTranslator/gui/translatorUI.py index c3773f1f..c865337b 100644 --- a/py/LunaTranslator/gui/translatorUI.py +++ b/py/LunaTranslator/gui/translatorUI.py @@ -3,7 +3,13 @@ import time, functools, threading, os, importlib, shutil, uuid from traceback import print_exc import windows, qtawesome, gobject, winsharedutils from myutils.wrapper import threader, tryprint -from myutils.config import globalconfig, saveallconfig, static_data, savehook_new_data +from myutils.config import ( + globalconfig, + saveallconfig, + static_data, + savehook_new_data, + savehook_new_list, +) from gui.dialog_savedgame import dialog_setting_game from myutils.subproc import endsubprocs from myutils.ocrutil import ocr_run, imageCut @@ -12,13 +18,13 @@ from myutils.utils import ( str2rgba, makehtml, loadpostsettingwindowmethod_maybe, + find_or_create_uid, ) from myutils.hwnd import ( mouseselectwindow, grabwindow, getExeIcon, getcurrexe, - hwndratex, ) from gui.setting_about import doupdate from gui.dialog_memory import dialog_memory @@ -33,6 +39,7 @@ from gui.usefulwidget import ( from gui.edittext import edittrans from gui.dialog_savedgame import dialog_savedgame_integrated from gui.dialog_savedgame_setting import favorites, calculate_centered_rect +from gui.dialog_savedgame_common import startgame from gui.dynalang import LDialog @@ -947,6 +954,7 @@ class TranslatorWindow(resizableframeless): self.left_bottom_corner = self.geometry().bottomLeft() self.translate_text = Textbrowser(self) self.translate_text.move(0, 0) + self.translate_text.dropfilecallback.connect(self.dropfilecallback) self.translate_text.contentsChanged.connect(self.textAreaChanged) self.translate_text.textbrowser.setselectable(globalconfig["selectable"]) self.titlebar.raise_() @@ -957,6 +965,14 @@ class TranslatorWindow(resizableframeless): t.start() self.adjustbuttons = self.titlebar.adjustbuttons + def dropfilecallback(self, file: str): + if not (file.lower().endswith(".exe") or file.lower().endswith(".lnk")): + return + uid = find_or_create_uid(savehook_new_list, file) + if uid not in savehook_new_list: + savehook_new_list.insert(0, uid) + startgame(uid) + def showEvent(self, e): if not self.firstshow: self.enterfunction() diff --git a/py/LunaTranslator/gui/usefulwidget.py b/py/LunaTranslator/gui/usefulwidget.py index 636f7b4a..e37dc91d 100644 --- a/py/LunaTranslator/gui/usefulwidget.py +++ b/py/LunaTranslator/gui/usefulwidget.py @@ -1230,11 +1230,15 @@ class abstractwebview(QWidget): class WebivewWidget(abstractwebview): html_limit = 1572834 # https://github.com/MicrosoftEdge/WebView2Feedback/issues/1355#issuecomment-1384161283 + dropfilecallback = pyqtSignal(str) def __del__(self): if not self.webview: return winsharedutils.remove_ZoomFactorChanged(self.get_controller(), self.__token) + winsharedutils.remove_WebMessageReceived( + self.get_controller(), self.m_webMessageReceivedToken + ) def bind(self, fname, func): self.webview.bind(fname, func) @@ -1256,13 +1260,19 @@ class WebivewWidget(abstractwebview): super().__init__(parent) self.webview = None self.webview = Webview(debug=debug, window=int(self.winId())) - zoomfunc = winsharedutils.add_ZoomFactorChanged_CALLBACK( + self.m_webMessageReceivedToken = None + self.zoomfunc = winsharedutils.add_ZoomFactorChanged_CALLBACK( self.on_ZoomFactorChanged.emit ) self.__token = winsharedutils.add_ZoomFactorChanged( - self.get_controller(), zoomfunc + self.get_controller(), self.zoomfunc + ) + self.dropfilecallback__ref = winsharedutils.add_WebMessageReceived_cb( + self.dropfilecallback.emit + ) + self.m_webMessageReceivedToken = winsharedutils.add_WebMessageReceived( + self.get_controller(), self.dropfilecallback__ref ) - self.keepref = [zoomfunc] self.webview.bind("__on_load", self._on_load) self.webview.init("""window.__on_load(window.location.href)""") if usedarklight: diff --git a/py/LunaTranslator/hiraparse/mecab.py b/py/LunaTranslator/hiraparse/mecab.py index e4323dcd..73589e44 100644 --- a/py/LunaTranslator/hiraparse/mecab.py +++ b/py/LunaTranslator/hiraparse/mecab.py @@ -1,7 +1,5 @@ import winsharedutils -import os, functools, csv, gobject -from ctypes import CFUNCTYPE, c_char_p - +import os, csv, gobject from hiraparse.basehira import basehira # # 2.1.2 src schema @@ -61,7 +59,7 @@ class mecabwrap: fields = list(csv.reader([feature.decode(codec)]))[0] res.append((surface.decode(codec), fields)) - fp = CFUNCTYPE(None, c_char_p, c_char_p)(cb) + fp = winsharedutils.mecab_parse_cb(cb) succ = winsharedutils.mecab_parse(self.kks, text.encode(codec), fp) if not succ: raise Exception("mecab parse failed") diff --git a/py/LunaTranslator/myutils/hwnd.py b/py/LunaTranslator/myutils/hwnd.py index aea6acfa..71638f23 100644 --- a/py/LunaTranslator/myutils/hwnd.py +++ b/py/LunaTranslator/myutils/hwnd.py @@ -173,8 +173,8 @@ def ListProcess(exe=None): return ret.get(exe, []) -def getExeIcon(name, icon=True, cache=False): - if name.lower()[-4:] == ".lnk": +def getExeIcon(name: str, icon=True, cache=False): + if name.lower().endswith(".lnk"): exepath, args, iconpath, dirp = winsharedutils.GetLnkTargetPath(name) if os.path.exists(iconpath): name = iconpath diff --git a/py/LunaTranslator/myutils/localetools.py b/py/LunaTranslator/myutils/localetools.py index fbfb9ef8..d3f0ebda 100644 --- a/py/LunaTranslator/myutils/localetools.py +++ b/py/LunaTranslator/myutils/localetools.py @@ -27,16 +27,16 @@ class Launcher: class LEbase(Launcher): def runX(self, exe, usearg, dirpath, config): ... - def run(self, game, config): + def run(self, game: str, config): dirpath = os.path.dirname(game) - if game.lower()[-4:] not in [".lnk", ".exe"]: + if not (game.lower().endswith(".exe") or game.lower().endswith(".lnk")): # 对于其他文件,需要AssocQueryStringW获取命令行才能正确le,太麻烦,放弃。 windows.ShellExecute(None, "open", game, "", dirpath, windows.SW_SHOW) return execheck3264 = game usearg = '"{}"'.format(game) - if game.lower()[-4:] == ".lnk": + if game.lower().endswith(".lnk"): exepath, args, iconpath, dirp = winsharedutils.GetLnkTargetPath(game) if args != "": diff --git a/py/LunaTranslator/myutils/utils.py b/py/LunaTranslator/myutils/utils.py index 403a54fb..d901479d 100644 --- a/py/LunaTranslator/myutils/utils.py +++ b/py/LunaTranslator/myutils/utils.py @@ -2,12 +2,10 @@ import windows import os, time import codecs, hashlib, shutil import socket, gobject, uuid, subprocess, functools -import ctypes, importlib, json -import ctypes.wintypes +import importlib, json from qtsymbols import * from string import Formatter -from ctypes import CDLL, c_void_p, CFUNCTYPE, c_size_t, cast, c_char, POINTER -from ctypes.wintypes import HANDLE +from ctypes import cast, c_char, POINTER from traceback import print_exc from myutils.config import ( globalconfig, @@ -305,7 +303,7 @@ def duplicateconfig(uidold): return uid -def find_or_create_uid(targetlist, gamepath, title=None): +def find_or_create_uid(targetlist, gamepath: str, title=None): uids = findgameuidofpath(gamepath, findall=True) if len(uids) == 0: uid = initanewitem(title) @@ -315,7 +313,12 @@ def find_or_create_uid(targetlist, gamepath, title=None): + "/" + os.path.basename(gamepath) ) - uid2gamepath[uid] = gamepath + if gamepath.lower().endswith(".lnk"): + exepath, _, _, _ = winsharedutils.GetLnkTargetPath(gamepath) + uid2gamepath[uid] = exepath + savehook_new_data[uid]["launchpath"] = gamepath + else: + uid2gamepath[uid] = gamepath trysearchforid(uid, [title] + guessmaybetitle(gamepath, title)) return uid else: @@ -429,18 +432,6 @@ def getfilemd5(file, default="0"): def minmaxmoveobservefunc(self): - user32 = ctypes.windll.user32 - - WinEventProcType = ctypes.CFUNCTYPE( - None, - ctypes.wintypes.HANDLE, - ctypes.wintypes.DWORD, - ctypes.wintypes.HWND, - ctypes.wintypes.LONG, - ctypes.wintypes.LONG, - ctypes.wintypes.DWORD, - ctypes.wintypes.DWORD, - ) self.lastpos = None def win_event_callback( @@ -492,7 +483,7 @@ def minmaxmoveobservefunc(self): except: print_exc() - win_event_callback_cfunc = WinEventProcType(win_event_callback) + win_event_callback_cfunc = windows.WINEVENTPROC(win_event_callback) eventpairs = ( (windows.EVENT_SYSTEM_FOREGROUND, windows.EVENT_SYSTEM_FOREGROUND), @@ -501,16 +492,16 @@ def minmaxmoveobservefunc(self): def _(): for pair in eventpairs: - hook_id = user32.SetWinEventHook( + hook_id = windows.SetWinEventHook( pair[0], pair[1], 0, win_event_callback_cfunc, 0, 0, 0 ) - msg = ctypes.wintypes.MSG() - while ctypes.windll.user32.GetMessageW(ctypes.byref(msg), None, 0, 0) != 0: - ctypes.windll.user32.TranslateMessage(ctypes.byref(msg)) - ctypes.windll.user32.DispatchMessageW(ctypes.byref(msg)) + msg = windows.MSG() + while windows.GetMessageW(windows.byref(msg), None, 0, 0) != 0: + windows.TranslateMessage(windows.byref(msg)) + windows.DispatchMessageW(windows.byref(msg)) - ctypes.windll.user32.UnhookWindowsHookEx(hook_id) + windows.UnhookWindowsHookEx(hook_id) _() @@ -831,7 +822,7 @@ class audiocapture: self.stoped = threading.Lock() self.stoped.acquire() self.data = None - self.cb1 = CFUNCTYPE(None, c_void_p, c_size_t)(self.__datacollect) + self.cb1 = winsharedutils.StartCaptureAsync_cb(self.__datacollect) self.mutex = winsharedutils.StartCaptureAsync(self.cb1) diff --git a/py/LunaTranslator/myutils/winsyshotkey.py b/py/LunaTranslator/myutils/winsyshotkey.py index c50e02bf..ae006580 100644 --- a/py/LunaTranslator/myutils/winsyshotkey.py +++ b/py/LunaTranslator/myutils/winsyshotkey.py @@ -3,12 +3,7 @@ import time import _thread as thread import windows -import ctypes -from ctypes import wintypes -byref = ctypes.byref -user32 = ctypes.windll.user32 -PM_REMOVE = 0x0001 unique_int = 0 @@ -37,7 +32,7 @@ class SystemHotkey: self.changedlock.acquire() self.hk_ref[unique_int] = hotkey self.changedlock.release() - if not user32.RegisterHotKey(None, unique_int, masks, keycode): + if not windows.RegisterHotKey(None, unique_int, masks, keycode): self._error = True self.waitforregist.release() @@ -58,7 +53,7 @@ class SystemHotkey: break if _use: del self.hk_ref[_use] - user32.UnregisterHotKey(None, _use) + windows.UnregisterHotKey(None, _use) self.changedlock.release() self.hk_action_queue.put(lambda: nt_unregister(hotkey)) @@ -78,7 +73,7 @@ class SystemHotkey: ) def _nt_wait(self): - msg = wintypes.MSG() + msg = windows.MSG() while 1: try: remove_or_add = self.hk_action_queue.get(block=False) @@ -87,7 +82,7 @@ class SystemHotkey: pass else: remove_or_add() - if user32.PeekMessageA(byref(msg), 0, 0, 0, PM_REMOVE): + if windows.PeekMessageA(windows.pointer(msg), 0, 0, 0, windows.PM_REMOVE): if msg.message == windows.WM_HOTKEY: self.changedlock.acquire() hotkey = self.hk_ref[msg.wParam][0], self.hk_ref[msg.wParam][1] diff --git a/py/LunaTranslator/network/libcurl/libcurl.py b/py/LunaTranslator/network/libcurl/libcurl.py index 34566379..2a323dc9 100644 --- a/py/LunaTranslator/network/libcurl/libcurl.py +++ b/py/LunaTranslator/network/libcurl/libcurl.py @@ -1,4 +1,4 @@ -import gobject, os +import gobject from requests import RequestException, Timeout from ctypes import ( CDLL, diff --git a/py/LunaTranslator/ocrengines/weixinocr.py b/py/LunaTranslator/ocrengines/weixinocr.py index dafcc80c..f23906f2 100644 --- a/py/LunaTranslator/ocrengines/weixinocr.py +++ b/py/LunaTranslator/ocrengines/weixinocr.py @@ -1,4 +1,4 @@ -import gobject, os, uuid, windows +import gobject, os, uuid from ocrengines.baseocrclass import baseocr from ctypes import CDLL, c_void_p, c_wchar_p, c_char_p, CFUNCTYPE, c_bool, c_int import winsharedutils diff --git a/py/LunaTranslator/rendertext/textbrowser.py b/py/LunaTranslator/rendertext/textbrowser.py index de134789..d27e93ec 100644 --- a/py/LunaTranslator/rendertext/textbrowser.py +++ b/py/LunaTranslator/rendertext/textbrowser.py @@ -53,8 +53,22 @@ class Qlabel_c(QLabel): class TextBrowser(QWidget, dataget): contentsChanged = pyqtSignal(QSize) + dropfilecallback = pyqtSignal(str) _padding = 5 + def dragEnterEvent(self, event: QDragEnterEvent): + if event.mimeData().hasUrls(): + event.accept() + else: + event.ignore() + + def dropEvent(self, event: QDropEvent): + files = [u.toLocalFile() for u in event.mimeData().urls()] + if not files: + return + file = files[0] + self.dropfilecallback.emit(file) + def __makeborder(self, size: QSize): # border是用来当可选取时,用来拖动的 # webview2的绘制和qt的绘制不兼容,qt的半透明对他无效,必须缩放,否则遮挡,所以还是各写一份吧。 @@ -85,6 +99,7 @@ class TextBrowser(QWidget, dataget): def __init__(self, parent) -> None: super().__init__(parent) + self.setAcceptDrops(True) self.atback_color = QLabel(self) self.atback_color.setMouseTracking(True) self.atback2 = QLabel(self) diff --git a/py/LunaTranslator/rendertext/webview.html b/py/LunaTranslator/rendertext/webview.html index 7edbccfa..ce9c2875 100644 --- a/py/LunaTranslator/rendertext/webview.html +++ b/py/LunaTranslator/rendertext/webview.html @@ -19,6 +19,21 @@ display: none; } + +