This commit is contained in:
恍兮惚兮 2024-07-14 15:09:37 +08:00
parent a5473ad1a1
commit 856c901f63
21 changed files with 244 additions and 468 deletions

View File

@ -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))

View File

@ -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)

View File

@ -1,6 +1,4 @@
import time, os
import winsharedutils
from tts.basettsclass import TTSbase
@ -36,7 +34,5 @@ class TTS(TTSbase):
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

View File

@ -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

View File

@ -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

View File

@ -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<std::vector<byte>> _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<std::vector<byte>> 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;
}
}
@ -85,7 +85,9 @@ bool _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate,
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
std::vector<byte> 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();
}

View File

@ -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<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume);
std::vector<std::wstring> _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;
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;
}

View File

@ -1,6 +1,5 @@
#include <stdafx.h>
#include <wechatocr.h>
#include <nlohmann/json.hpp>
#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<CWeChatOCR *>(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<CWeChatOCR *>(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<std::wstring> rets;
std::vector<int> xs, ys, xs2, ys2;
nlohmann::json js = std::vector<nlohmann::json>{};
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;
}

View File

@ -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)

View File

@ -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<int> &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<std::string> &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<std::wstring> &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;
}

View File

@ -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<std::string> &vs);
int *vecint2c(std::vector<int> &vs);
wchar_t **vecwstr2c(std::vector<std::wstring> &vs);

View File

@ -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<uint8_t>(static_cast<uint8_t *>(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<std::wstring> rets;
std::vector<int> 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)};
}

View File

@ -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")

View File

@ -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<int> &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<std::string> &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<std::wstring> &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);
}

View File

@ -1,3 +0,0 @@
char **vecstr2c(std::vector<std::string> &vs);
int *vecint2c(std::vector<int> &vs);
wchar_t **vecwstr2c(std::vector<std::wstring> &vs);

View File

@ -17,11 +17,12 @@ bool tryopenclipboard(HWND hwnd = 0)
}
return success;
}
wchar_t *clipboard_get()
std::optional<std::wstring> clipboard_get_internal()
{
wchar_t *data = 0;
std::optional<std::wstring> 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<decltype(callback)>(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;

View File

@ -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));
}

View File

@ -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;
}

View File

@ -1,35 +1,17 @@

#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<std::vector<byte>> _Speak(std::wstring &Content, const wchar_t *token, int voiceid, int rate, int volume);
std::vector<std::wstring> _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<std::wstring> 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";
};
bool SAPI::Speak(std::wstring &Content, int version, int voiceid, int rate, int volume, int *length, char **buffer)
{
if (version == 7)
std::vector<std::wstring> List(int version)
{
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<std::wstring> SAPI::List(int version)
{
if (version == 7)
{
return _List(SPCAT_VOICES_7);
@ -42,17 +24,38 @@ std::vector<std::wstring> SAPI::List(int version)
{
return {};
}
}
}
std::optional<std::vector<byte>> 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);
}
};
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());
}

View File

@ -97,7 +97,7 @@ int SaveBitmapToFile(HBITMAP hBitmap, LPCWSTR lpFileName)
return TRUE;
}
BYTE *SaveBitmapToBuffer(HBITMAP hBitmap, size_t *size)
std::vector<byte> 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<byte> 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)

View File

@ -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<std::string> 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<std::string> surfs;
std::vector<std::string> 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;
}