From 856c901f63f300d10ae40aa93b26725b216d14fd 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: Sun, 14 Jul 2024 15:09:37 +0800 Subject: [PATCH] . --- .../LunaTranslator/hiraparse/mecab.py | 30 +++- .../LunaTranslator/ocrengines/weixinocr.py | 28 +-- .../LunaTranslator/tts/windowstts.py | 8 +- LunaTranslator/LunaTranslator/winrtutils.py | 52 ++---- .../LunaTranslator/winsharedutils.py | 162 ++++++------------ plugins/implsapi.cpp | 21 +-- plugins/shareddllproxy/neospeech.cpp | 19 +- plugins/wcocr/wcocr.cpp | 22 +-- plugins/winrtutils/CMakeLists.txt | 2 +- plugins/winrtutils/cinterface.cpp | 67 -------- plugins/winrtutils/define.h | 19 +- plugins/winrtutils/winrtocr.cpp | 31 +--- plugins/winsharedutils/CMakeLists.txt | 2 +- plugins/winsharedutils/cinterface.cpp | 64 ------- plugins/winsharedutils/cinterface.h | 3 - plugins/winsharedutils/clipboard.cpp | 30 ++-- plugins/winsharedutils/define.h | 14 +- plugins/winsharedutils/icon.cpp | 10 +- plugins/winsharedutils/sapi_dll.cpp | 83 ++++----- plugins/winsharedutils/screenshot.cpp | 22 +-- plugins/winsharedutils/simplemecab.cpp | 23 +-- 21 files changed, 244 insertions(+), 468 deletions(-) delete mode 100644 plugins/winrtutils/cinterface.cpp delete mode 100644 plugins/winsharedutils/cinterface.cpp delete mode 100644 plugins/winsharedutils/cinterface.h diff --git a/LunaTranslator/LunaTranslator/hiraparse/mecab.py b/LunaTranslator/LunaTranslator/hiraparse/mecab.py index 618a363a..dc3a2252 100644 --- a/LunaTranslator/LunaTranslator/hiraparse/mecab.py +++ b/LunaTranslator/LunaTranslator/hiraparse/mecab.py @@ -1,5 +1,6 @@ import winsharedutils -import os +import os, functools, csv, gobject +from ctypes import CFUNCTYPE, c_char_p from hiraparse.basehira import basehira @@ -23,11 +24,36 @@ from hiraparse.basehira import basehira # 'aModType lid lemma_id'.split(' ')) +class mecabwrap: + def __init__(self, mecabpath) -> None: + self.kks = winsharedutils.mecab_init( + mecabpath.encode("utf8"), gobject.GetDllpath("libmecab.dll") + ) + + def __del__(self): + winsharedutils.mecab_end(self.kks) + + def parse(self, text: str, codec: str): + res = [] + + def cb(surface: bytes, feature: bytes): + fields = list(csv.reader([feature.decode(codec)]))[0] + res.append((surface.decode(codec), fields)) + + succ = winsharedutils.mecab_parse( + self.kks, text.encode(codec), CFUNCTYPE(None, c_char_p, c_char_p)(cb) + ) + if not succ: + raise Exception # failed + + return res + + class mecab(basehira): def init(self) -> None: mecabpath = self.config["path"] if os.path.exists(mecabpath): - self.kks = winsharedutils.mecabwrap( + self.kks = mecabwrap( mecabpath ) # fugashi.Tagger('-r nul -d "{}" -Owakati'.format(mecabpath)) diff --git a/LunaTranslator/LunaTranslator/ocrengines/weixinocr.py b/LunaTranslator/LunaTranslator/ocrengines/weixinocr.py index a8d697ea..84f7d8af 100644 --- a/LunaTranslator/LunaTranslator/ocrengines/weixinocr.py +++ b/LunaTranslator/LunaTranslator/ocrengines/weixinocr.py @@ -1,6 +1,6 @@ -import gobject, os, uuid, json +import gobject, os, uuid from ocrengines.baseocrclass import baseocr -from ctypes import CDLL, c_void_p, c_wchar_p, c_char_p, cast +from ctypes import CDLL, c_void_p, c_wchar_p, c_char_p, CFUNCTYPE, c_bool, c_int class OCR(baseocr): @@ -41,20 +41,24 @@ class OCR(baseocr): ff.write(imagebinary) imgfile = os.path.abspath(fname) wcocr_ocr = self.wcocr.wcocr_ocr - wcocr_ocr.argtypes = c_void_p, c_char_p - wcocr_ocr.restype = c_void_p - wcocr_free_str = self.wcocr.wcocr_free_str - wcocr_free_str.argtypes = (c_void_p,) - pstring = wcocr_ocr(self.pobj, imgfile.encode("utf8")) - if not pstring: - return - string = cast(pstring, c_char_p).value.decode("utf8") - wcocr_free_str(pstring) + wcocr_ocr.argtypes = c_void_p, c_char_p, c_void_p + wcocr_ocr.restype = c_bool + ret = [] + def cb(x1, y1, x2, y2, text: bytes): + ret.append((x1, y1, x2, y2, text.decode("utf8"))) + + succ = wcocr_ocr( + self.pobj, + imgfile.encode("utf8"), + CFUNCTYPE(None, c_int, c_int, c_int, c_int, c_char_p)(cb), + ) + if not succ: + return os.remove(imgfile) boxs = [] texts = [] - for line in json.loads(string): + for line in ret: x1, y1, x2, y2, text = line boxs.append((x1, y1, x2, y2)) texts.append(text) diff --git a/LunaTranslator/LunaTranslator/tts/windowstts.py b/LunaTranslator/LunaTranslator/tts/windowstts.py index cc862f4e..c1a63c16 100644 --- a/LunaTranslator/LunaTranslator/tts/windowstts.py +++ b/LunaTranslator/LunaTranslator/tts/windowstts.py @@ -1,6 +1,4 @@ -import time, os import winsharedutils - from tts.basettsclass import TTSbase @@ -35,8 +33,6 @@ class TTS(TTSbase): else: version = 7 voice_idx = self._7m[voice] - - data=winsharedutils.SAPI_Speak( - content, version, voice_idx, rate, 100 - ) + + data = winsharedutils.SAPI_Speak(content, version, voice_idx, rate, 100) return data diff --git a/LunaTranslator/LunaTranslator/winrtutils.py b/LunaTranslator/LunaTranslator/winrtutils.py index 4a38875b..c05a7e5d 100644 --- a/LunaTranslator/LunaTranslator/winrtutils.py +++ b/LunaTranslator/LunaTranslator/winrtutils.py @@ -1,12 +1,10 @@ from ctypes import ( c_uint, c_bool, - POINTER, c_wchar_p, - pointer, CDLL, c_size_t, - Structure, + CFUNCTYPE, c_void_p, ) import platform, gobject @@ -21,49 +19,35 @@ except: if winrtutilsdll: - class ocrres(Structure): - _fields_ = [ - ("lines", POINTER(c_wchar_p)), - ("xs", POINTER(c_uint)), - ("ys", POINTER(c_uint)), - ("xs2", POINTER(c_uint)), - ("ys2", POINTER(c_uint)), - ] - _OCR_f = winrtutilsdll.OCR - _OCR_f.argtypes = c_void_p, c_size_t, c_wchar_p, c_wchar_p, POINTER(c_uint) - _OCR_f.restype = ocrres - _freeocrres = winrtutilsdll.freeocrres - _freeocrres.argtypes = ocrres, c_uint + _OCR_f.argtypes = c_void_p, c_size_t, c_wchar_p, c_wchar_p, c_void_p - _freewstringlist = winrtutilsdll.freewstringlist - _freewstringlist.argtypes = POINTER(c_wchar_p), c_uint _check_language_valid = winrtutilsdll.check_language_valid _check_language_valid.argtypes = (c_wchar_p,) _check_language_valid.restype = c_bool _getlanguagelist = winrtutilsdll.getlanguagelist - _getlanguagelist.argtypes = (POINTER(c_uint),) - _getlanguagelist.restype = POINTER(c_wchar_p) + _getlanguagelist.argtypes = (c_void_p,) def getlanguagelist(): - num = c_uint() - ret = _getlanguagelist(pointer(num)) - _allsupport = [] - for i in range(num.value): - _allsupport.append(ret[i]) - _freewstringlist(ret, num.value) - return _allsupport + ret = [] + _getlanguagelist(CFUNCTYPE(None, c_wchar_p)(ret.append)) + return ret def OCR_f(data, lang, space): - num = c_uint() - ret = _OCR_f(data, len(data), lang, space, pointer(num)) - res = [] - for i in range(num.value): - res.append((ret.lines[i], ret.xs[i], ret.ys[i], ret.xs2[i], ret.ys2[i])) + ret = [] - _freeocrres(ret, num.value) - return res + def cb(x1, y1, x2, y2, text): + ret.append((text, x1, y1, x2, y2)) + + _OCR_f( + data, + len(data), + lang, + space, + CFUNCTYPE(None, c_uint, c_uint, c_uint, c_uint, c_wchar_p)(cb), + ) + return ret _winrt_capture_window = winrtutilsdll.winrt_capture_window _winrt_capture_window.argtypes = c_wchar_p, c_void_p diff --git a/LunaTranslator/LunaTranslator/winsharedutils.py b/LunaTranslator/LunaTranslator/winsharedutils.py index 58f62a7b..5a2abade 100644 --- a/LunaTranslator/LunaTranslator/winsharedutils.py +++ b/LunaTranslator/LunaTranslator/winsharedutils.py @@ -3,7 +3,6 @@ from ctypes import ( c_bool, POINTER, c_char_p, - c_uint64, c_wchar_p, pointer, CDLL, @@ -22,18 +21,12 @@ from ctypes import ( CFUNCTYPE, c_long, ) -from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD, RECT, BYTE +from ctypes.wintypes import WORD, HANDLE, HWND, LONG, DWORD, RECT from windows import WINDOWPLACEMENT -import gobject, csv +import gobject utilsdll = CDLL(gobject.GetDllpath(("winsharedutils32.dll", "winsharedutils64.dll"))) -_freewstringlist = utilsdll.freewstringlist -_freewstringlist.argtypes = POINTER(c_wchar_p), c_uint -_free_all = utilsdll.free_all -_free_all.argtypes = (c_void_p,) -_freestringlist = utilsdll.freestringlist -_freestringlist.argtypes = POINTER(c_char_p), c_uint _SetProcessMute = utilsdll.SetProcessMute _SetProcessMute.argtypes = c_uint, c_bool @@ -42,23 +35,10 @@ _GetProcessMute = utilsdll.GetProcessMute _GetProcessMute.restype = c_bool _SAPI_List = utilsdll.SAPI_List -_SAPI_List.argtypes = ( - c_uint, - POINTER(c_uint64), -) -_SAPI_List.restype = POINTER(c_wchar_p) - +_SAPI_List.argtypes = (c_uint, c_void_p) _SAPI_Speak = utilsdll.SAPI_Speak -_SAPI_Speak.argtypes = ( - c_wchar_p, - c_uint, - c_uint, - c_uint, - c_uint, - POINTER(c_int), - POINTER(c_void_p), -) +_SAPI_Speak.argtypes = (c_wchar_p, c_uint, c_uint, c_uint, c_uint, c_void_p) _SAPI_Speak.restype = c_bool @@ -69,27 +49,20 @@ levenshtein_ratio = utilsdll.levenshtein_ratio levenshtein_ratio.argtypes = c_uint, c_wchar_p, c_uint, c_wchar_p levenshtein_ratio.restype = c_double -_mecab_init = utilsdll.mecab_init -_mecab_init.argtypes = c_char_p, c_wchar_p -_mecab_init.restype = c_void_p +mecab_init = utilsdll.mecab_init +mecab_init.argtypes = c_char_p, c_wchar_p +mecab_init.restype = c_void_p -_mecab_parse = utilsdll.mecab_parse -_mecab_parse.argtypes = ( - c_void_p, - c_char_p, - POINTER(POINTER(c_char_p)), - POINTER(POINTER(c_char_p)), - POINTER(c_uint), -) -_mecab_parse.restype = c_bool +mecab_parse = utilsdll.mecab_parse +mecab_parse.argtypes = (c_void_p, c_char_p, c_void_p) +mecab_parse.restype = c_bool -_mecab_end = utilsdll.mecab_end -_mecab_end.argtypes = (c_void_p,) +mecab_end = utilsdll.mecab_end +mecab_end.argtypes = (c_void_p,) _clipboard_get = utilsdll.clipboard_get -_clipboard_get.restype = ( - c_void_p # 实际上是c_wchar_p,但是写c_wchar_p 傻逼python自动转成str,没法拿到指针 -) +_clipboard_get.argtypes = (c_void_p,) +_clipboard_get.restype = c_bool _clipboard_set = utilsdll.clipboard_set _clipboard_set.argtypes = ( c_void_p, @@ -106,26 +79,28 @@ def GetProcessMute(pid): def SAPI_List(v): - num = c_uint64() - _list = _SAPI_List(v, pointer(num)) ret = [] - for i in range(num.value): - ret.append(_list[i]) - _freewstringlist(_list, num.value) + _SAPI_List(v, CFUNCTYPE(None, c_wchar_p)(ret.append)) return ret def SAPI_Speak(content, v, voiceid, rate, volume): - length = c_int() - buff = c_void_p() + ret = [] + + def _cb(ptr, size): + ret.append(cast(ptr, POINTER(c_char))[:size]) + succ = _SAPI_Speak( - content, v, voiceid, int(rate), int(volume), pointer(length), pointer(buff) + content, + v, + voiceid, + int(rate), + int(volume), + CFUNCTYPE(None, c_void_p, c_size_t)(_cb), ) if not succ: return None - data = cast(buff, POINTER(c_char))[: length.value] - c_free(buff) - return data + return ret[0] def distance( @@ -138,38 +113,6 @@ def distance_ratio(s1, s2): return levenshtein_ratio(len(s1), s1, len(s2), s2) -class mecabwrap: - def __init__(self, mecabpath) -> None: - self.kks = _mecab_init( - mecabpath.encode("utf8"), gobject.GetDllpath("libmecab.dll") - ) - - def __del__(self): - _mecab_end(self.kks) - - def parse(self, text, codec): - surface = POINTER(c_char_p)() - feature = POINTER(c_char_p)() - num = c_uint() - succ = _mecab_parse( - self.kks, - text.encode(codec), - pointer(surface), - pointer(feature), - pointer(num), - ) - if not succ: - raise Exception # failed - res = [] - for i in range(num.value): - f = feature[i] - fields = list(csv.reader([f.decode(codec)]))[0] - res.append((surface[i].decode(codec), fields)) - _freestringlist(feature, num.value) - _freestringlist(surface, num.value) - return res - - clphwnd = windll.user32.CreateWindowExW(0, "STATIC", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) @@ -180,13 +123,10 @@ def clipboard_set(text): def clipboard_get(): - p = _clipboard_get() - if p: - v = cast(p, c_wchar_p).value - _free_all(p) - return v - else: + ret = [] + if not _clipboard_get(CFUNCTYPE(None, c_wchar_p)(ret.append)): return "" + return ret[0] html_version = utilsdll.html_version @@ -267,24 +207,20 @@ def otsu_binary(image, thresh): _extracticon2data = utilsdll.extracticon2data -_extracticon2data.argtypes = c_wchar_p, POINTER(c_size_t) -_extracticon2data.restype = c_void_p +_extracticon2data.argtypes = c_wchar_p, c_void_p +_extracticon2data.restype = c_bool def extracticon2data(fname): - length = c_size_t() - datap = _extracticon2data(fname, pointer(length)) - if datap: - save = create_string_buffer(length.value) - memmove(save, datap, length.value) - _free_all(datap) - return save - else: + ret = [] + + def cb(ptr, size): + ret.append(cast(ptr, POINTER(c_char))[:size]) + + succ = _extracticon2data(fname, CFUNCTYPE(None, c_void_p, c_size_t)(cb)) + if not succ: return None - - -c_free = utilsdll.c_free -c_free.argtypes = (c_void_p,) + return ret[0] _queryversion = utilsdll.queryversion @@ -380,23 +316,25 @@ PlayAudioInMem_Stop = utilsdll.PlayAudioInMem_Stop PlayAudioInMem_Stop.argtypes = c_void_p, c_void_p _gdi_screenshot = utilsdll.gdi_screenshot -_gdi_screenshot.argtypes = HWND, RECT, POINTER(c_size_t) -_gdi_screenshot.restype = POINTER(BYTE) +_gdi_screenshot.argtypes = HWND, RECT, c_void_p +_gdi_screenshot.restype = c_bool def gdi_screenshot(x1, y1, x2, y2, hwnd=None): - sz = c_size_t() rect = RECT() rect.left = x1 rect.top = y1 rect.right = x2 rect.bottom = y2 - bf = _gdi_screenshot(hwnd, rect, pointer(sz)) - if not (sz.value and bf): + ret = [] + + def cb(ptr, size): + ret.append(cast(ptr, POINTER(c_char))[:size]) + + bf = _gdi_screenshot(hwnd, rect, CFUNCTYPE(None, c_void_p, c_size_t)(cb)) + if not bf: return None - data = cast(bf, POINTER(c_char))[: sz.value] - c_free(bf) - return data + return ret[0] maximum_window = utilsdll.maximum_window diff --git a/plugins/implsapi.cpp b/plugins/implsapi.cpp index 930fee2c..5a9b38c2 100644 --- a/plugins/implsapi.cpp +++ b/plugins/implsapi.cpp @@ -1,16 +1,16 @@ -bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume, int *length, char **buffer) +std::optional> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume) { ISpVoice *pVoice = NULL; if (FAILED(::CoInitialize(NULL))) - return false; - bool ret = true; + return {}; + std::optional> ret = {}; do { HRESULT hr = CoCreateInstance(CLSID_SpVoice, NULL, CLSCTX_ALL, IID_ISpVoice, (void **)&pVoice); if (FAILED(hr) || (NULL == pVoice)) { - ret = false; + ret = {}; break; } IEnumSpObjectTokens *pSpEnumTokens = NULL; @@ -32,7 +32,7 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, hr = pVoice->GetOutputStream(&cpOldStream); if (FAILED(hr) || (NULL == cpOldStream)) { - ret = false; + ret = {}; break; } originalFmt.AssignFormat(cpOldStream); @@ -52,7 +52,7 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, hr = cpWavStream->SetBaseStream(pMemStream, SPDFID_WaveFormatEx, originalFmt.WaveFormatExPtr()); if (FAILED(hr)) { - ret = false; + ret = {}; break; } } @@ -84,8 +84,10 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, ULONG sSize = stats.cbSize.QuadPart; // size of the data to be read auto wavfmt = *originalFmt.WaveFormatExPtr(); - ULONG bytesRead; // this will tell the number of bytes that have been read - char *pBuffer = new char[sSize + 0x3ea]; // buffer to read the data + ULONG bytesRead; // this will tell the number of bytes that have been read + std::vector datas; + datas.resize(sSize + 0x3ea); + auto pBuffer = datas.data(); // buffer to read the data // memcpy(pBuffer,&wavHeader,sizeof(WAV_HEADER)); int fsize = sSize + 0x3ea; int ptr = 0; @@ -128,8 +130,7 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, cout << pBuffer[i] << " "; cout << endl; */ - *buffer = pBuffer; - *length = fsize; + ret = std::move(datas); pIstream->Release(); } diff --git a/plugins/shareddllproxy/neospeech.cpp b/plugins/shareddllproxy/neospeech.cpp index fb9344ee..f90f660c 100644 --- a/plugins/shareddllproxy/neospeech.cpp +++ b/plugins/shareddllproxy/neospeech.cpp @@ -1,4 +1,4 @@ -bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume, int *length, char **buffer); +std::optional> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume); std::vector _List(const wchar_t *token); int neospeechlist(int argc, wchar_t *argv[]) @@ -54,11 +54,18 @@ int neospeech(int argc, wchar_t *argv[]) break; std::wstring content = text; int fsize; - char *buff; - _Speak(content, hkey, idx, speed, 100, &fsize, &buff); - memcpy(mapview, buff, fsize); - delete buff; - WriteFile(hPipe, &fsize, 4, &_, NULL); + auto data = std::move(_Speak(content, hkey, idx, speed, 100)); + if (data) + { + memcpy(mapview, data.value().data(), data.value().size()); + fsize = data.value().size(); + WriteFile(hPipe, &fsize, 4, &_, NULL); + } + else + { + fsize = 0; + WriteFile(hPipe, &fsize, 4, &_, NULL); + } } return 0; } \ No newline at end of file diff --git a/plugins/wcocr/wcocr.cpp b/plugins/wcocr/wcocr.cpp index 9db65784..b3ae02ea 100644 --- a/plugins/wcocr/wcocr.cpp +++ b/plugins/wcocr/wcocr.cpp @@ -1,6 +1,5 @@ #include #include -#include #define DECLARE extern "C" __declspec(dllexport) DECLARE void *wcocr_init(const wchar_t *wexe, const wchar_t *wwcdir) @@ -24,28 +23,19 @@ DECLARE void wcocr_destroy(void *pobj) auto obj = reinterpret_cast(pobj); delete obj; } -DECLARE void wcocr_free_str(char *ptr) -{ - delete[] ptr; -} -DECLARE char *wcocr_ocr(void *pobj, const char *u8path) +DECLARE bool wcocr_ocr(void *pobj, const char *u8path, void (*cb)(int, int, int, int, LPCSTR)) { if (!pobj) - return 0; + return false; auto obj = reinterpret_cast(pobj); CWeChatOCR::result_t res; - std::string imgpath = u8path; - if (!obj->doOCR(imgpath, &res)) - return 0; + if (!obj->doOCR(u8path, &res)) + return false; std::vector rets; std::vector xs, ys, xs2, ys2; - nlohmann::json js = std::vector{}; for (auto &blk : res.ocr_response) { - js.push_back({blk.left, blk.top, blk.right, blk.bottom, blk.text}); + cb(blk.left, blk.top, blk.right, blk.bottom, blk.text.c_str()); } - std::string _s = js.dump(); - auto s = new char[_s.size() + 1]; - strcpy(s, _s.c_str()); - return s; + return true; } \ No newline at end of file diff --git a/plugins/winrtutils/CMakeLists.txt b/plugins/winrtutils/CMakeLists.txt index 84d20185..03b4a787 100644 --- a/plugins/winrtutils/CMakeLists.txt +++ b/plugins/winrtutils/CMakeLists.txt @@ -10,7 +10,7 @@ generate_product_version( VERSION_PATCH ${VERSION_PATCH} ) -add_library(winrtutils MODULE winrtsnapshot.cpp cinterface.cpp dllmain.cpp winrtocr.cpp ${versioninfo}) +add_library(winrtutils MODULE winrtsnapshot.cpp dllmain.cpp winrtocr.cpp ${versioninfo}) target_precompile_headers(winrtutils REUSE_FROM pch) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) diff --git a/plugins/winrtutils/cinterface.cpp b/plugins/winrtutils/cinterface.cpp deleted file mode 100644 index b77db08d..00000000 --- a/plugins/winrtutils/cinterface.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "define.h" - -void free_all(void *str) -{ - delete str; -} -void freewstringlist(wchar_t **strlist, int num) -{ - for (int i = 0; i < num; i++) - { - delete strlist[i]; - } - delete strlist; -} -void freestringlist(char **strlist, int num) -{ - for (int i = 0; i < num; i++) - { - delete strlist[i]; - } - delete strlist; -} -void freeocrres(ocrres res, int num) -{ - freewstringlist(res.lines, num); - delete res.xs; - delete res.ys; - delete res.xs2; - delete res.ys2; -} - -int *vecint2c(std::vector &vs) -{ - int *argv = new int[vs.size() + 1]; - - for (size_t i = 0; i < vs.size(); i++) - { - argv[i] = vs[i]; - } - return argv; -} - -char **vecstr2c(std::vector &vs) -{ - char **argv = new char *[vs.size() + 1]; - - for (size_t i = 0; i < vs.size(); i++) - { - argv[i] = new char[vs[i].size() + 1]; - strcpy_s(argv[i], vs[i].size() + 1, vs[i].c_str()); - argv[i][vs[i].size()] = 0; - } - return argv; -} - -wchar_t **vecwstr2c(std::vector &vs) -{ - wchar_t **argv = new wchar_t *[vs.size() + 1]; - - for (size_t i = 0; i < vs.size(); i++) - { - argv[i] = new wchar_t[vs[i].size() + 1]; - wcscpy_s(argv[i], vs[i].size() + 1, vs[i].c_str()); - argv[i][vs[i].size()] = 0; - } - return argv; -} diff --git a/plugins/winrtutils/define.h b/plugins/winrtutils/define.h index 55d97efe..558fcbd5 100644 --- a/plugins/winrtutils/define.h +++ b/plugins/winrtutils/define.h @@ -1,23 +1,10 @@ #pragma once -struct ocrres -{ - wchar_t **lines; - int *xs; - int *ys; - int *xs2; - int *ys2; -}; extern "C" { __declspec(dllexport) void winrt_capture_window(wchar_t *savepath, HWND hwnd); __declspec(dllexport) bool check_language_valid(wchar_t *); - __declspec(dllexport) wchar_t **getlanguagelist(int *); - __declspec(dllexport) ocrres OCR(void* ptr, size_t size, wchar_t *lang, wchar_t *, int *); + __declspec(dllexport) void getlanguagelist(void (*cb)(LPCWSTR)); + __declspec(dllexport) void OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *, void (*)(int, int, int, int, LPCWSTR)); - __declspec(dllexport) void freewstringlist(wchar_t **, int); - __declspec(dllexport) void freeocrres(ocrres, int); -} -char **vecstr2c(std::vector &vs); -int *vecint2c(std::vector &vs); -wchar_t **vecwstr2c(std::vector &vs); \ No newline at end of file +} \ No newline at end of file diff --git a/plugins/winrtutils/winrtocr.cpp b/plugins/winrtutils/winrtocr.cpp index 5010b3c9..42d8a7bb 100644 --- a/plugins/winrtutils/winrtocr.cpp +++ b/plugins/winrtutils/winrtocr.cpp @@ -40,24 +40,18 @@ bool check_language_valid(wchar_t *language) return false; } } -wchar_t **getlanguagelist(int *num) +void getlanguagelist(void(*cb)(LPCWSTR)) { OcrEngine ocrEngine = OcrEngine::TryCreateFromUserProfileLanguages(); auto languages = ocrEngine.AvailableRecognizerLanguages(); - auto ret = new wchar_t *[languages.Size()]; - int i = 0; + for (auto &&language : languages) { auto lang = language.LanguageTag(); - size_t len = lang.size() + 1; - ret[i] = new wchar_t[len]; - wcscpy_s(ret[i], len, lang.c_str()); - i += 1; + cb(lang.c_str()); } - *num = languages.Size(); - return ret; } -ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num) +void OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, void (*cb)(int, int, int, int, LPCWSTR)) { IBuffer buffer = CryptographicBuffer::CreateFromByteArray( winrt::array_view(static_cast(ptr), size)); @@ -71,13 +65,8 @@ ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num) OcrEngine ocrEngine = OcrEngine::TryCreateFromLanguage(language); OcrResult ocrResult = ocrEngine.RecognizeAsync(softwareBitmap).get(); auto res = ocrResult.Lines(); - std::vector rets; - std::vector xs, ys, xs2, ys2; - int i = 0; - std::wstring sspace = space; for (auto line : res) { - std::wstring xx = L""; bool start = true; unsigned int x1 = -1, x2 = 0, y1 = -1, y2 = 0; @@ -85,7 +74,7 @@ ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num) for (auto word : line.Words()) { if (!start) - xx += sspace; + xx += space; start = false; xx += word.Text(); auto &rect = word.BoundingRect(); @@ -94,13 +83,7 @@ ocrres OCR(void *ptr, size_t size, wchar_t *lang, wchar_t *space, int *num) y1 = std::min((unsigned int)rect.Y, y1); y2 = std::max(y2, (unsigned int)(rect.Y + rect.Height)); } - ys.push_back(y1); - xs.push_back(x1); - xs2.push_back(x2); - ys2.push_back(y2); - rets.emplace_back(xx); - i += 1; + cb(x1,y2,x2,y2,xx.c_str()); } - *num = res.Size(); - return ocrres{vecwstr2c(rets), vecint2c(xs), vecint2c(ys), vecint2c(xs2), vecint2c(ys2)}; + } diff --git a/plugins/winsharedutils/CMakeLists.txt b/plugins/winsharedutils/CMakeLists.txt index 4039bdc7..8ca9a82b 100644 --- a/plugins/winsharedutils/CMakeLists.txt +++ b/plugins/winsharedutils/CMakeLists.txt @@ -11,7 +11,7 @@ generate_product_version( VERSION_PATCH ${VERSION_PATCH} ) -add_library(winsharedutils MODULE webview2_extra.cpp AreoAcrylic.cpp screenshot.cpp audio.cpp ../implsapi.cpp 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 ${versioninfo}) +add_library(winsharedutils MODULE webview2_extra.cpp AreoAcrylic.cpp screenshot.cpp audio.cpp ../implsapi.cpp hwnd.cpp darklistener.cpp theme.cpp version.cpp otsu.cpp clipboard.cpp lnk.cpp dllmain.cpp levenshtein.cpp muteprocess.cpp sapi_dll.cpp simplemecab.cpp SimpleBrowser.cpp MWebBrowser.cpp icon.cpp maglistener.cpp ${versioninfo}) target_precompile_headers(winsharedutils REUSE_FROM pch) if(${CMAKE_SIZEOF_VOID_P} EQUAL 8) set_target_properties(winsharedutils PROPERTIES OUTPUT_NAME "winsharedutils64") diff --git a/plugins/winsharedutils/cinterface.cpp b/plugins/winsharedutils/cinterface.cpp deleted file mode 100644 index 20c3be3b..00000000 --- a/plugins/winsharedutils/cinterface.cpp +++ /dev/null @@ -1,64 +0,0 @@ - -#include "define.h" -void free_all(void *str) -{ - delete str; -} -void freewstringlist(wchar_t **strlist, int num) -{ - for (int i = 0; i < num; i++) - { - delete strlist[i]; - } - delete strlist; -} -void freestringlist(char **strlist, int num) -{ - for (int i = 0; i < num; i++) - { - delete strlist[i]; - } - delete strlist; -} - -int *vecint2c(std::vector &vs) -{ - int *argv = new int[vs.size() + 1]; - - for (size_t i = 0; i < vs.size(); i++) - { - argv[i] = vs[i]; - } - return argv; -} - -char **vecstr2c(std::vector &vs) -{ - char **argv = new char *[vs.size() + 1]; - - for (size_t i = 0; i < vs.size(); i++) - { - argv[i] = new char[vs[i].size() + 1]; - strcpy_s(argv[i], vs[i].size() + 1, vs[i].c_str()); - argv[i][vs[i].size()] = 0; - } - return argv; -} - -wchar_t **vecwstr2c(std::vector &vs) -{ - wchar_t **argv = new wchar_t *[vs.size() + 1]; - - for (size_t i = 0; i < vs.size(); i++) - { - argv[i] = new wchar_t[vs[i].size() + 1]; - wcscpy_s(argv[i], vs[i].size() + 1, vs[i].c_str()); - argv[i][vs[i].size()] = 0; - } - return argv; -} - -void c_free(void *ptr) -{ - free(ptr); -} diff --git a/plugins/winsharedutils/cinterface.h b/plugins/winsharedutils/cinterface.h deleted file mode 100644 index cf6952b2..00000000 --- a/plugins/winsharedutils/cinterface.h +++ /dev/null @@ -1,3 +0,0 @@ -char **vecstr2c(std::vector &vs); -int *vecint2c(std::vector &vs); -wchar_t **vecwstr2c(std::vector &vs); \ No newline at end of file diff --git a/plugins/winsharedutils/clipboard.cpp b/plugins/winsharedutils/clipboard.cpp index ac41455e..e2324d12 100644 --- a/plugins/winsharedutils/clipboard.cpp +++ b/plugins/winsharedutils/clipboard.cpp @@ -17,11 +17,12 @@ bool tryopenclipboard(HWND hwnd = 0) } return success; } -wchar_t *clipboard_get() + +std::optional clipboard_get_internal() { - wchar_t *data = 0; + std::optional data = {}; if (tryopenclipboard() == false) - return 0; + return {}; do { HANDLE hData = GetClipboardData(CF_UNICODETEXT); @@ -31,14 +32,22 @@ wchar_t *clipboard_get() if (pszText == 0) break; int sz = GlobalSize(hData); - data = new wchar_t[sz + 1]; - wcscpy_s(data, sz, pszText); - data[sz] = 0; + data = std::move(std::wstring(pszText, sz)); GlobalUnlock(hData); } while (false); CloseClipboard(); return data; } + +bool clipboard_get(void (*cb)(const wchar_t *)) +{ + auto data = std::move(clipboard_get_internal()); + if (!data) + return false; + cb(data.value().c_str()); + return true; +} + bool clipboard_set(HWND hwnd, wchar_t *text) { bool success = false; @@ -66,7 +75,7 @@ bool clipboard_set(HWND hwnd, wchar_t *text) return success; } -static void clipboard_callback_1(void (*callback)(wchar_t *, bool), HANDLE hsema, HWND *hwnd) +static void clipboard_callback_1(void (*callback)(const wchar_t *, bool), HANDLE hsema, HWND *hwnd) { const wchar_t CLASS_NAME[] = L"LunaClipboardListener"; @@ -75,15 +84,14 @@ static void clipboard_callback_1(void (*callback)(wchar_t *, bool), HANDLE hsema { if (WM_CLIPBOARDUPDATE == message) { - auto data = clipboard_get(); + auto data = clipboard_get_internal(); auto callback_ = reinterpret_cast(GetWindowLongPtrW(hWnd, GWLP_USERDATA)); if (data && callback_) { auto ohwnd = GetClipboardOwner(); DWORD pid; GetWindowThreadProcessId(ohwnd, &pid); - callback_(data, pid == GetCurrentProcessId()); - delete data; + callback_(data.value().c_str(), pid == GetCurrentProcessId()); } } return DefWindowProc(hWnd, message, wParam, lParam); @@ -109,7 +117,7 @@ static void clipboard_callback_1(void (*callback)(wchar_t *, bool), HANDLE hsema } } -DECLARE HWND clipboard_callback(void (*callback)(wchar_t *, bool)) +DECLARE HWND clipboard_callback(void (*callback)(const wchar_t *, bool)) { HANDLE hsema = CreateSemaphoreW(0, 0, 10, 0); HWND hwnd; diff --git a/plugins/winsharedutils/define.h b/plugins/winsharedutils/define.h index d6771301..06b334f8 100644 --- a/plugins/winsharedutils/define.h +++ b/plugins/winsharedutils/define.h @@ -6,7 +6,7 @@ extern "C" __declspec(dllexport) HANDLE startdarklistener(); __declspec(dllexport) bool queryversion(const wchar_t *exe, WORD *_1, WORD *_2, WORD *_3, WORD *_4); - __declspec(dllexport) wchar_t **SAPI_List(int version, size_t *); + __declspec(dllexport) void SAPI_List(int version, void (*cb)(const wchar_t *)); __declspec(dllexport) BOOL SetProcessMute(DWORD Pid, bool mute); __declspec(dllexport) bool GetProcessMute(DWORD Pid); @@ -15,20 +15,14 @@ extern "C" __declspec(dllexport) double levenshtein_ratio(size_t len1, const wchar_t *string1, size_t len2, const wchar_t *string2); - __declspec(dllexport) void freewstringlist(wchar_t **, int); - __declspec(dllexport) void free_all(void *str); - __declspec(dllexport) void freestringlist(char **, int); - __declspec(dllexport) void *mecab_init(char *utf8path, wchar_t *); - __declspec(dllexport) bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***features, int *num); + __declspec(dllexport) bool mecab_parse(void *trigger, char *utf8string, void (*callback)(const char *, const char *)); __declspec(dllexport) void mecab_end(void *trigger); - __declspec(dllexport) wchar_t *clipboard_get(); + __declspec(dllexport) bool clipboard_get(void (*)(const wchar_t *)); __declspec(dllexport) bool clipboard_set(HWND hwnd, wchar_t *text); __declspec(dllexport) void GetLnkTargetPath(wchar_t *lnkFilePath, wchar_t *path, wchar_t *tgtpath, wchar_t *iconpath, wchar_t *dirpath); __declspec(dllexport) bool otsu_binary(const void *image, int thresh); - __declspec(dllexport) void *extracticon2data(const wchar_t *name, size_t *l); - - __declspec(dllexport) void c_free(void *); + __declspec(dllexport) bool extracticon2data(const wchar_t *name, void (*)(const char *, size_t)); } \ No newline at end of file diff --git a/plugins/winsharedutils/icon.cpp b/plugins/winsharedutils/icon.cpp index 4b34e61a..4ef43c1a 100644 --- a/plugins/winsharedutils/icon.cpp +++ b/plugins/winsharedutils/icon.cpp @@ -1,13 +1,13 @@ #include "define.h" #include "BMP.h" -void *extracticon2data(const wchar_t *name, size_t *l) +bool extracticon2data(const wchar_t *name, void (*cb)(const char *, size_t)) { HICON h1, h2; ExtractIconExW(name, 0, &h1, &h2, 1); if (h1 == 0) - return 0; + return false; HDC hdc = GetDC(NULL); HDC memDC = CreateCompatibleDC(hdc); ICONINFO iconInfo; @@ -63,8 +63,6 @@ void *extracticon2data(const wchar_t *name, size_t *l) } std::string data; bmpp.write_tomem(data); - auto sdata = new char[data.size()]; - memcpy(sdata, data.data(), data.size()); - *l = data.size(); - return sdata; + cb(data.c_str(),data.size()); + return true; } \ No newline at end of file diff --git a/plugins/winsharedutils/sapi_dll.cpp b/plugins/winsharedutils/sapi_dll.cpp index eca7e73a..6c217c19 100644 --- a/plugins/winsharedutils/sapi_dll.cpp +++ b/plugins/winsharedutils/sapi_dll.cpp @@ -1,58 +1,61 @@  #include "define.h" -#include "cinterface.h" -bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume, int *length, char **buffer); +std::optional> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume); std::vector _List(const wchar_t *token); namespace SAPI { - bool Speak(std::wstring &Content, int version, int voiceid, int rate, int volume, int *length, char **buffer); - std::vector List(int version); + constexpr wchar_t SPCAT_VOICES_7[] = L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech\\Voices"; constexpr wchar_t SPCAT_VOICES_10[] = L"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Speech_OneCore\\Voices"; + + std::vector List(int version) + { + if (version == 7) + { + return _List(SPCAT_VOICES_7); + } + else if (version == 10) + { + return _List(SPCAT_VOICES_10); + } + else + { + return {}; + } + } + std::optional> Speak(std::wstring &Content, int version, int voiceid, int rate, int volume) + { + const wchar_t *_; + switch (version) + { + case 7: + _ = SPCAT_VOICES_7; + break; + case 10: + _ = SPCAT_VOICES_10; + break; + return {}; + } + return _Speak(Content, _, voiceid, rate, volume); + } }; -bool SAPI::Speak(std::wstring &Content, int version, int voiceid, int rate, int volume, int *length, char **buffer) -{ - if (version == 7) - { - return _Speak(Content, SPCAT_VOICES_7, voiceid, rate, volume, length, buffer); - } - else if (version == 10) - { - return _Speak(Content, SPCAT_VOICES_10, voiceid, rate, volume, length, buffer); - } - else - { - return false; - } -} -std::vector SAPI::List(int version) -{ - if (version == 7) - { - return _List(SPCAT_VOICES_7); - } - else if (version == 10) - { - return _List(SPCAT_VOICES_10); - } - else - { - return {}; - } -} - -DECLARE bool SAPI_Speak(const wchar_t *Content, int version, int voiceid, int rate, int volume, int *length, char **buffer) +DECLARE bool SAPI_Speak(const wchar_t *Content, int version, int voiceid, int rate, int volume, void (*cb)(byte *, size_t)) { auto _c = std::wstring(Content); - return SAPI::Speak(_c, version, voiceid, rate, volume, length, buffer); + if (auto _ = std::move(SAPI::Speak(_c, version, voiceid, rate, volume))) + { + cb(_.value().data(), _.value().size()); + return true; + } + return false; } -wchar_t **SAPI_List(int version, size_t *num) +void SAPI_List(int version, void (*cb)(const wchar_t *)) { auto _list = SAPI::List(version); - *num = _list.size(); - return vecwstr2c(_list); + for (auto _ : _list) + cb(_.c_str()); } \ No newline at end of file diff --git a/plugins/winsharedutils/screenshot.cpp b/plugins/winsharedutils/screenshot.cpp index afae32b8..66f2b5d4 100644 --- a/plugins/winsharedutils/screenshot.cpp +++ b/plugins/winsharedutils/screenshot.cpp @@ -97,7 +97,7 @@ int SaveBitmapToFile(HBITMAP hBitmap, LPCWSTR lpFileName) return TRUE; } -BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size) +std::vector SaveBitmapToBuffer(HBITMAP hBitmap) { WORD wBitCount; // 位图中每个像素所占字节数 // 定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数 @@ -131,7 +131,9 @@ BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size) bmfHdr.bfReserved1 = 0; bmfHdr.bfReserved2 = 0; bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER); - auto buffer = new BYTE[sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize]; + std::vector data; + data.resize(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize); + auto buffer = data.data(); // 写入位图文件头 // WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); // 写入位图信息头 @@ -150,28 +152,28 @@ BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size) // 写位图数据 // WriteFile(fh, lpbk, dwBmBitsSize, &dwWritten, NULL); - *size = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwBmBitsSize; // 清除 delete[] lpmem; - return buffer; + return data; } -DECLARE BYTE *gdi_screenshot(HWND hwnd, RECT rect, size_t *size) +DECLARE bool gdi_screenshot(HWND hwnd, RECT rect, void (*cb)(byte *, size_t)) { - *size = 0; if (rect.bottom == rect.top || rect.left == rect.right) - return nullptr; + return false; if (!hwnd) hwnd = GetDesktopWindow(); auto hdc = GetDC(hwnd); if (!hdc) - return nullptr; + return false; auto bm = GetBitmap(rect, hdc); // SaveBitmapToFile(bm, LR"(.\2.bmp)"); - auto bf = SaveBitmapToBuffer(bm, size); + size_t size; + auto bf = std::move(SaveBitmapToBuffer(bm)); + cb(bf.data(), bf.size()); DeleteObject(bm); ReleaseDC(hwnd, hdc); - return bf; + return true; } DECLARE void maximum_window(HWND hwnd) diff --git a/plugins/winsharedutils/simplemecab.cpp b/plugins/winsharedutils/simplemecab.cpp index b2aaa9dc..d5ec10ca 100644 --- a/plugins/winsharedutils/simplemecab.cpp +++ b/plugins/winsharedutils/simplemecab.cpp @@ -1,7 +1,5 @@ -#pragma execution_character_set("utf-8") #include "define.h" -#include "cinterface.h" struct mecab_node_t { struct mecab_node_t *prev; @@ -41,11 +39,8 @@ void *mecab_init(char *utf8path, wchar_t *mepath) auto _mecab_new = (mecab_new)GetProcAddress(mecablib, "mecab_new"); if (_mecab_new == 0) return 0; - std::vector vargv = {"fugashi", "-C", "-r", "nul", "-d", utf8path, "-Owakati"}; - - auto argv = vecstr2c(vargv); - auto trigger = _mecab_new(vargv.size(), argv); - freestringlist(argv, vargv.size()); + char *argv[] = {"fugashi", "-C", "-r", "nul", "-d", utf8path, "-Owakati"}; + auto trigger = _mecab_new(ARRAYSIZE(argv), argv); return trigger; } void mecab_end(void *trigger) @@ -59,7 +54,8 @@ void mecab_end(void *trigger) return; mecab_destroy((mecab_t *)trigger); } -bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***features, int *num) + +bool mecab_parse(void *trigger, char *utf8string, void (*callback)(const char *, const char *)) { if (trigger == 0) return false; @@ -72,8 +68,6 @@ bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***featu std::string cstr = utf8string; auto node = _mecab_sparse_tonode((mecab_t *)trigger, cstr.c_str()); - std::vector surfs; - std::vector featuresv; while (node->next) { node = node->next; @@ -81,13 +75,8 @@ bool mecab_parse(void *trigger, char *utf8string, char ***surface, char ***featu { break; } - std::string surf = node->surface; - surf = surf.substr(0, node->length); - surfs.emplace_back(surf); - featuresv.emplace_back(node->feature); + std::string surf = std::string(node->surface, node->length); + callback(surf.c_str(), node->feature); } - *surface = vecstr2c(surfs); - *features = vecstr2c(featuresv); - *num = surfs.size(); return true; } \ No newline at end of file