This commit is contained in:
恍兮惚兮 2024-07-21 19:28:47 +08:00
parent 5c048ee8b2
commit 3e66a81e40
19 changed files with 1941 additions and 1548 deletions

View File

@ -92,7 +92,7 @@
#define HS_SEARCH_FOR_TEXT L"Search for specific text" #define HS_SEARCH_FOR_TEXT L"Search for specific text"
#define VersionLatest L"Latest version" #define VersionLatest L"Latest version"
#define VersionCurrent L"Current version" #define VersionCurrent L"Current version"
#define ProjectHomePage L"Github: https://github.com/HIllya51/LunaHook\nHomepage: https://lunatranslator.xyz\nDiscord: https://discord.gg/f8NSvaDU" #define ProjectHomePage L"Github: https://github.com/HIllya51/LunaHook\nHomepage: https://lunatranslator.xyz\npatreon: https://patreon.com/HIllya51\nDiscord: https://discord.gg/f8NSvaDU\n\nThis program is a core submodule of LunaTranslator and is fully integrated in Lunatranslator. This program contains only some simple functions, if you need more functions, please use LunaTranslator.\n\nIf you find unsupported games, please submit an issue\nhttps://github.com/HIllya51/LunaHook/issues/new?assignees=&labels=enhancement&projects=&template=01_game_request.yaml"
#define LIST_HOOK L"Hook" #define LIST_HOOK L"Hook"
#define LIST_TEXT L"Text" #define LIST_TEXT L"Text"
#define PROC_CONN L"process connected %d" #define PROC_CONN L"process connected %d"

View File

@ -92,7 +92,7 @@
#define HS_SEARCH_FOR_TEXT L"Искать определенный текст" #define HS_SEARCH_FOR_TEXT L"Искать определенный текст"
#define VersionLatest L"Последняя версия" #define VersionLatest L"Последняя версия"
#define VersionCurrent L"Текущая версия" #define VersionCurrent L"Текущая версия"
#define ProjectHomePage L"Github: https://github.com/HIllya51/LunaHook\nСтраница проекта: https://lunatranslator.xyz\nDiscord: https://discord.gg/f8NSvaDU\nПеревод на русский: https://github.com/NekoIriyaRu" #define ProjectHomePage L"Github: https://github.com/HIllya51/LunaHook\nСтраница проекта: https://lunatranslator.xyz\npatreon: https://patreon.com/HIllya51\nDiscord: https://discord.gg/f8NSvaDU\nПеревод на русский: https://github.com/NekoIriyaRu\n\nЭта программа является основным подмодулем LunaTranslator и полностью интегрирована в Lunatranslator. Эта программа содержит только некоторые простые функции. Если вам нужны дополнительные функции, используйте LunaTranslator.\n\nЕсли вы обнаружите какие-либо неподдерживаемые игры, сообщите о проблеме.\nhttps://github.com/HIllya51/LunaHook/issues/new?assignees=&labels=enhancement&projects=&template=01_game_request.yaml"
#define LIST_HOOK L"Хук" #define LIST_HOOK L"Хук"
#define LIST_TEXT L"Текст" #define LIST_TEXT L"Текст"
#define PROC_CONN L"Процесс подключен %d" #define PROC_CONN L"Процесс подключен %d"

View File

@ -92,7 +92,7 @@
#define HS_SEARCH_FOR_TEXT L"搜索指定文本" #define HS_SEARCH_FOR_TEXT L"搜索指定文本"
#define VersionLatest L"最新版本" #define VersionLatest L"最新版本"
#define VersionCurrent L"当前版本" #define VersionCurrent L"当前版本"
#define ProjectHomePage L"Github https://github.com/HIllya51/LunaHook\n项目主页 https://lunatranslator.xyz\nDiscordhttps://discord.gg/f8NSvaDU" #define ProjectHomePage L"Github https://github.com/HIllya51/LunaHook\n项目主页 https://lunatranslator.xyz\npatreonhttps://patreon.com/HIllya51\nDiscordhttps://discord.gg/f8NSvaDU\n\n本程序是LunaTranslator 的核心子模块并完全集成在Lunatranslator中。本程序仅包含一些简单功能如果您需要更多功能请使用 LunaTranslator。\n\n如果你发现有不支持的游戏请提交issue\nhttps://github.com/HIllya51/LunaHook/issues/new?assignees=&labels=enhancement&projects=&template=01_game_request.yaml"
#define LIST_HOOK L"Hook" #define LIST_HOOK L"Hook"
#define LIST_TEXT L"文本" #define LIST_TEXT L"文本"
#define PROC_CONN L"进程已连接 %d" #define PROC_CONN L"进程已连接 %d"

View File

@ -31,7 +31,7 @@ namespace{
GlobalUnlock(hClipboardData); GlobalUnlock(hClipboardData);
s->ARG2=(uintptr_t)hClipboardData; s->ARG2=(uintptr_t)hClipboardData;
}; };
return NewHook(hp,"hookClipboard"); return NewHook(hp,"nwjs/electron");
} }
} }
namespace v8script{ namespace v8script{

View File

@ -10,8 +10,10 @@
#include "Lang/Lang.h" #include "Lang/Lang.h"
#include "http.hpp" #include "http.hpp"
bool sendclipboarddata_i(const std::wstring&text,HWND hwnd){ bool sendclipboarddata_i(const std::wstring &text, HWND hwnd)
if (!OpenClipboard((HWND)hwnd)) return false; {
if (!OpenClipboard((HWND)hwnd))
return false;
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, (text.size() + 1) * sizeof(wchar_t)); HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, (text.size() + 1) * sizeof(wchar_t));
memcpy(GlobalLock(hMem), text.c_str(), (text.size() + 1) * sizeof(wchar_t)); memcpy(GlobalLock(hMem), text.c_str(), (text.size() + 1) * sizeof(wchar_t));
EmptyClipboard(); EmptyClipboard();
@ -20,20 +22,25 @@ bool sendclipboarddata_i(const std::wstring&text,HWND hwnd){
CloseClipboard(); CloseClipboard();
return true; return true;
} }
bool sendclipboarddata(const std::wstring&text,HWND hwnd){ bool sendclipboarddata(const std::wstring &text, HWND hwnd)
for (int loop = 0; loop < 10; loop++) { {
for (int loop = 0; loop < 10; loop++)
{
auto succ = sendclipboarddata_i(text, hwnd); auto succ = sendclipboarddata_i(text, hwnd);
if(succ)return true; if (succ)
return true;
std::this_thread::sleep_for(std::chrono::milliseconds(50)); std::this_thread::sleep_for(std::chrono::milliseconds(50));
} }
return false; return false;
} }
void LunaHost::on_close(){ void LunaHost::on_close()
{
hasstoped = true; hasstoped = true;
savesettings(); savesettings();
delete configs; delete configs;
auto _attachedprocess = attachedprocess; auto _attachedprocess = attachedprocess;
for(auto pid:_attachedprocess){ for (auto pid : _attachedprocess)
{
Host::DetachProcess(pid); Host::DetachProcess(pid);
} }
if (_attachedprocess.size()) if (_attachedprocess.size())
@ -53,10 +60,17 @@ void LunaHost::savesettings()
configs->set("defaultCodepage", Host::defaultCodepage); configs->set("defaultCodepage", Host::defaultCodepage);
configs->set("autoattachexes", autoattachexes); configs->set("autoattachexes", autoattachexes);
configs->set("savedhookcontext", savedhookcontext); configs->set("savedhookcontext", savedhookcontext);
configs->set("DefaultFont",defaultFont); configs->set("DefaultFont2", WideStringToString(uifont.fontfamily));
configs->set("fontsize", uifont.fontsize);
configs->set("font_italic", uifont.italic);
configs->set("font_bold", uifont.bold);
} }
void LunaHost::loadsettings(){ void LunaHost::loadsettings()
defaultFont=configs->get("DefaultFont",std::wstring(DefaultFont)); {
uifont.italic = configs->get("font_italic", false);
uifont.bold = configs->get("font_bold", false);
uifont.fontsize = configs->get("fontsize", 14);
uifont.fontfamily = StringToWideString(configs->get("DefaultFont2", WideStringToString(std::wstring(DefaultFont))));
check_toclipboard_selection = configs->get("ToClipboardSelection", false); check_toclipboard_selection = configs->get("ToClipboardSelection", false);
check_toclipboard = configs->get("ToClipboard", false); check_toclipboard = configs->get("ToClipboard", false);
autoattach = configs->get("AutoAttach", false); autoattach = configs->get("AutoAttach", false);
@ -74,17 +88,23 @@ std::unordered_map<std::wstring,std::vector<int>> getprocesslist();
void LunaHost::doautoattach() void LunaHost::doautoattach()
{ {
if(autoattach==false&&autoattach_savedonly==false)return; if (autoattach == false && autoattach_savedonly == false)
return;
if(autoattachexes.empty())return; if (autoattachexes.empty())
return;
for (auto [pexe, pids] : getprocesslist()) for (auto [pexe, pids] : getprocesslist())
{ {
auto &&u8procname = WideStringToString(pexe); auto &&u8procname = WideStringToString(pexe);
if(autoattachexes.find(u8procname)==autoattachexes.end())continue; if (autoattachexes.find(u8procname) == autoattachexes.end())
if(autoattach_savedonly && savedhookcontext.find(u8procname)==savedhookcontext.end())continue; continue;
for(auto pid:pids){ if (autoattach_savedonly && savedhookcontext.find(u8procname) == savedhookcontext.end())
if(userdetachedpids.find(pid)!=userdetachedpids.end())continue; continue;
for (auto pid : pids)
{
if (userdetachedpids.find(pid) != userdetachedpids.end())
continue;
if (attachedprocess.find(pid) == attachedprocess.end()) if (attachedprocess.find(pid) == attachedprocess.end())
Host::InjectProcess(pid); Host::InjectProcess(pid);
@ -92,7 +112,6 @@ void LunaHost::doautoattach()
break; break;
} }
} }
void LunaHost::on_proc_disconnect(DWORD pid) void LunaHost::on_proc_disconnect(DWORD pid)
@ -108,9 +127,11 @@ void LunaHost::on_proc_connect(DWORD pid)
{ {
autoattachexes.insert(WideStringToString(pexe.value())); autoattachexes.insert(WideStringToString(pexe.value()));
auto u8procname = WideStringToString(pexe.value()); auto u8procname = WideStringToString(pexe.value());
if(savedhookcontext.find(u8procname)!=savedhookcontext.end()){ if (savedhookcontext.find(u8procname) != savedhookcontext.end())
{
std::string name = safequeryjson(savedhookcontext[u8procname], "name", std::string()); std::string name = safequeryjson(savedhookcontext[u8procname], "name", std::string());
if(startWith(name,"UserHook")){ if (startWith(name, "UserHook"))
{
if (auto hp = HookCode::Parse(StringToWideString(savedhookcontext[u8procname]["hookcode"]))) if (auto hp = HookCode::Parse(StringToWideString(savedhookcontext[u8procname]["hookcode"])))
Host::InsertHook(pid, hp.value()); Host::InsertHook(pid, hp.value());
} }
@ -156,20 +177,23 @@ bool queryversion(WORD *_1, WORD *_2, WORD *_3, WORD *_4)
return true; return true;
} }
LunaHost::LunaHost(){ LunaHost::LunaHost()
{
configs = new confighelper; configs = new confighelper;
loadsettings(); loadsettings();
setfont(25,defaultFont.c_str()); setfont(uifont);
btnshowsettionwindow = new button(this, BtnShowSettingWindow); btnshowsettionwindow = new button(this, BtnShowSettingWindow);
g_selectprocessbutton = new button(this, BtnSelectProcess); g_selectprocessbutton = new button(this, BtnSelectProcess);
// btnsavehook=new button(this,BtnSaveHook,10,10,10,10); // btnsavehook=new button(this,BtnSaveHook,10,10,10,10);
// btnsavehook->onclick=std::bind(&LunaHost::btnsavehookscallback,this); // btnsavehook->onclick=std::bind(&LunaHost::btnsavehookscallback,this);
btndetachall = new button(this, BtnDetach); btndetachall = new button(this, BtnDetach);
btndetachall->onclick=[&](){ btndetachall->onclick = [&]()
for(auto pid:attachedprocess){ {
for (auto pid : attachedprocess)
{
Host::DetachProcess(pid); Host::DetachProcess(pid);
userdetachedpids.insert(pid); userdetachedpids.insert(pid);
} }
@ -179,34 +203,45 @@ LunaHost::LunaHost(){
btnplugin = new button(this, BtnPlugin); btnplugin = new button(this, BtnPlugin);
plugins = new Pluginmanager(this); plugins = new Pluginmanager(this);
btnplugin->onclick=[&](){ btnplugin->onclick = [&]()
if(pluginwindow==0) pluginwindow=new Pluginwindow(this,plugins); {
if (pluginwindow == 0)
pluginwindow = new Pluginwindow(this, plugins);
pluginwindow->show(); pluginwindow->show();
}; };
g_hButton_insert = new button(this, BtnInsertUserHook); g_hButton_insert = new button(this, BtnInsertUserHook);
btnshowsettionwindow->onclick=[&](){ btnshowsettionwindow->onclick = [&]()
if(settingwindow==0) settingwindow=new Settingwindow(this); {
if (settingwindow == 0)
settingwindow = new Settingwindow(this);
settingwindow->show(); settingwindow->show();
}; };
g_selectprocessbutton->onclick=[&](){ g_selectprocessbutton->onclick = [&]()
if(_processlistwindow==0) _processlistwindow=new processlistwindow(this); {
if (_processlistwindow == 0)
_processlistwindow = new processlistwindow(this);
_processlistwindow->show(); _processlistwindow->show();
}; };
g_hButton_insert->onclick=[&](){ g_hButton_insert->onclick = [&]()
{
auto hp = HookCode::Parse(std::move(g_hEdit_userhook->text())); auto hp = HookCode::Parse(std::move(g_hEdit_userhook->text()));
if(hp){ if (hp)
for(auto _:attachedprocess){ {
for (auto _ : attachedprocess)
{
Host::InsertHook(_, hp.value()); Host::InsertHook(_, hp.value());
} }
} }
else{ else
{
showtext(NotifyInvalidHookCode, false); showtext(NotifyInvalidHookCode, false);
} }
}; };
g_hListBox_listtext = new listview(this, false, false); g_hListBox_listtext = new listview(this, false, false);
g_hListBox_listtext->setheader({LIST_HOOK, LIST_TEXT}); g_hListBox_listtext->setheader({LIST_HOOK, LIST_TEXT});
g_hListBox_listtext->oncurrentchange=[&](int idx){ g_hListBox_listtext->oncurrentchange = [&](int idx)
{
auto thread_p = g_hListBox_listtext->getdata(idx); auto thread_p = g_hListBox_listtext->getdata(idx);
std::wstring get; std::wstring get;
currentselect = thread_p; currentselect = thread_p;
@ -214,32 +249,35 @@ LunaHost::LunaHost(){
strReplace(copy, L"\n", L"\r\n"); strReplace(copy, L"\n", L"\r\n");
showtext(copy, true); showtext(copy, true);
}; };
g_hListBox_listtext->on_menu=[&]()->maybehavemenu{ g_hListBox_listtext->on_menu = [&]() -> maybehavemenu
{
auto tt = (TextThread *)g_hListBox_listtext->getdata(g_hListBox_listtext->currentidx()); auto tt = (TextThread *)g_hListBox_listtext->getdata(g_hListBox_listtext->currentidx());
Menu menu; Menu menu;
menu.add(MenuCopyHookCode,[&,tt](){sendclipboarddata(tt->hp.hookcode,winId);}); menu.add(MenuCopyHookCode, [&, tt]()
{ sendclipboarddata(tt->hp.hookcode, winId); });
menu.add_sep(); menu.add_sep();
menu.add(MenuRemoveHook,[&,tt](){Host::RemoveHook(tt->tp.processId,tt->tp.addr);}); menu.add(MenuRemoveHook, [&, tt]()
menu.add(MenuDetachProcess,[&,tt](){ { Host::RemoveHook(tt->tp.processId, tt->tp.addr); });
menu.add(MenuDetachProcess, [&, tt]()
{
Host::DetachProcess(tt->tp.processId); Host::DetachProcess(tt->tp.processId);
userdetachedpids.insert(tt->tp.processId); userdetachedpids.insert(tt->tp.processId); });
});
menu.add_sep(); menu.add_sep();
menu.add(MenuRemeberSelect,[&,tt](){ menu.add(MenuRemeberSelect, [&, tt]()
{
if(auto pexe=getModuleFilename(tt->tp.processId)) if(auto pexe=getModuleFilename(tt->tp.processId))
savedhookcontext[WideStringToString(pexe.value())]={ savedhookcontext[WideStringToString(pexe.value())]={
{"hookcode",WideStringToString(tt->hp.hookcode)}, {"hookcode",WideStringToString(tt->hp.hookcode)},
{"ctx1",tt->tp.ctx}, {"ctx1",tt->tp.ctx},
{"ctx2",tt->tp.ctx2}, {"ctx2",tt->tp.ctx2},
{"name",WideStringToString(tt->name)} {"name",WideStringToString(tt->name)}
}; }; });
}); menu.add(MenuForgetSelect, [&, tt]()
menu.add(MenuForgetSelect,[&,tt](){ {
if(auto pexe=getModuleFilename(tt->tp.processId)) if(auto pexe=getModuleFilename(tt->tp.processId))
savedhookcontext.erase(WideStringToString(pexe.value())); savedhookcontext.erase(WideStringToString(pexe.value())); });
});
return menu; return menu;
}; };
@ -247,8 +285,10 @@ LunaHost::LunaHost(){
g_showtexts->setreadonly(true); g_showtexts->setreadonly(true);
btnsearchhooks = new button(this, BtnSearchHook); btnsearchhooks = new button(this, BtnSearchHook);
btnsearchhooks->onclick=[&](){ btnsearchhooks->onclick = [&]()
if(hooksearchwindow==0) hooksearchwindow=new Hooksearchwindow(this); {
if (hooksearchwindow == 0)
hooksearchwindow = new Hooksearchwindow(this);
hooksearchwindow->show(); hooksearchwindow->show();
}; };
@ -257,8 +297,7 @@ LunaHost::LunaHost(){
std::bind(&LunaHost::on_proc_disconnect, this, std::placeholders::_1), std::bind(&LunaHost::on_proc_disconnect, this, std::placeholders::_1),
std::bind(&LunaHost::on_thread_create, this, std::placeholders::_1), std::bind(&LunaHost::on_thread_create, this, std::placeholders::_1),
std::bind(&LunaHost::on_thread_delete, this, std::placeholders::_1), std::bind(&LunaHost::on_thread_delete, this, std::placeholders::_1),
std::bind(&LunaHost::on_text_recv,this,std::placeholders::_1,std::placeholders::_2) std::bind(&LunaHost::on_text_recv, this, std::placeholders::_1, std::placeholders::_2));
);
mainlayout = new gridlayout(); mainlayout = new gridlayout();
mainlayout->addcontrol(g_selectprocessbutton, 0, 0); mainlayout->addcontrol(g_selectprocessbutton, 0, 0);
@ -279,7 +318,8 @@ LunaHost::LunaHost(){
std::wstring title = WndLunaHostGui; std::wstring title = WndLunaHostGui;
settext(title); settext(title);
std::thread([&](){ std::thread([&]()
{
//https://lunatranslator.xyz/Github/LunaHook/issues/14 //https://lunatranslator.xyz/Github/LunaHook/issues/14
std::wstring sel; std::wstring sel;
while(1) while(1)
@ -294,24 +334,26 @@ LunaHost::LunaHost(){
sendclipboarddata(sel,winId); sendclipboarddata(sel,winId);
} }
} }
} } })
}).detach(); .detach();
std::thread([&]{ std::thread([&]
{
while(1){ while(1){
doautoattach(); doautoattach();
std::this_thread::sleep_for(std::chrono::seconds(2)); std::this_thread::sleep_for(std::chrono::seconds(2));
} } })
}).detach(); .detach();
WORD _1, _2, _3, _4; WORD _1, _2, _3, _4;
WCHAR vs[32]; WCHAR vs[32];
if(queryversion(&_1,&_2,&_3,&_4)){ if (queryversion(&_1, &_2, &_3, &_4))
{
wsprintf(vs, L" | %s v%d.%d.%d", VersionCurrent, _1, _2, _3); wsprintf(vs, L" | %s v%d.%d.%d", VersionCurrent, _1, _2, _3);
title += vs; title += vs;
settext(title); settext(title);
std::thread([&](){ std::thread([&]()
{
if (HttpRequest httpRequest{ if (HttpRequest httpRequest{
L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36", L"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36",
L"lunatranslator.xyz", L"lunatranslator.xyz",
@ -325,8 +367,8 @@ LunaHost::LunaHost(){
settext(text()+L" | "+VersionLatest+L" "+ StringToWideString(ver)); settext(text()+L" | "+VersionLatest+L" "+ StringToWideString(ver));
} }
catch(std::exception&e){} catch(std::exception&e){}
} } })
}).detach(); .detach();
} }
} }
void LunaHost::on_text_recv_checkissaved(TextThread &thread) void LunaHost::on_text_recv_checkissaved(TextThread &thread)
@ -334,7 +376,8 @@ void LunaHost::on_text_recv_checkissaved(TextThread& thread)
if (auto exe = getModuleFilename(thread.tp.processId)) if (auto exe = getModuleFilename(thread.tp.processId))
{ {
auto exea = WideStringToString(exe.value()); auto exea = WideStringToString(exe.value());
if(savedhookcontext.find(exea)==savedhookcontext.end())return; if (savedhookcontext.find(exea) == savedhookcontext.end())
return;
std::string hc = savedhookcontext[exea]["hookcode"]; std::string hc = savedhookcontext[exea]["hookcode"];
uint64_t ctx1 = savedhookcontext[exea]["ctx1"]; uint64_t ctx1 = savedhookcontext[exea]["ctx1"];
@ -350,21 +393,20 @@ void LunaHost::on_text_recv_checkissaved(TextThread& thread)
break; break;
} }
} }
}
}
} }
} std::wstring sanitize(const std::wstring &s1)
{
}
std::wstring sanitize(const std::wstring& s1) {
std::wstring s = s1; std::wstring s = s1;
s.erase(std::remove_if(s.begin(), s.end(), [](wchar_t ch) { s.erase(std::remove_if(s.begin(), s.end(), [](wchar_t ch)
return (ch >= 0xD800 && ch <= 0xDBFF) || (ch >= 0xDC00 && ch <= 0xDFFF); { return (ch >= 0xD800 && ch <= 0xDBFF) || (ch >= 0xDC00 && ch <= 0xDFFF); }),
}), s.end()); s.end());
return s; return s;
} }
void LunaHost::showtext(const std::wstring&text,bool clear){ void LunaHost::showtext(const std::wstring &text, bool clear)
{
auto output = sanitize(text); auto output = sanitize(text);
strReplace(output, L"\n", L"\r\n"); strReplace(output, L"\n", L"\r\n");
if (clear) if (clear)
@ -372,34 +414,43 @@ void LunaHost::showtext(const std::wstring&text,bool clear){
g_showtexts->settext(output); g_showtexts->settext(output);
g_showtexts->scrolltoend(); g_showtexts->scrolltoend();
} }
else{ else
{
g_showtexts->scrolltoend(); g_showtexts->scrolltoend();
g_showtexts->appendtext(output); g_showtexts->appendtext(output);
} }
} }
void LunaHost::updatelisttext(const std::wstring&text,LONG_PTR data){ void LunaHost::updatelisttext(const std::wstring &text, LONG_PTR data)
{
auto idx = g_hListBox_listtext->querydataidx(data); auto idx = g_hListBox_listtext->querydataidx(data);
if(idx>=0){ if (idx >= 0)
{
auto __output = sanitize(text); auto __output = sanitize(text);
strReplace(__output, L"\n", L" "); strReplace(__output, L"\n", L" ");
if(__output.size()>0x40){ if (__output.size() > 0x40)
{
__output = __output.substr(0, 0x40) + L"..."; __output = __output.substr(0, 0x40) + L"...";
} }
g_hListBox_listtext->settext(idx, 1, __output); g_hListBox_listtext->settext(idx, 1, __output);
} }
} }
bool LunaHost::on_text_recv(TextThread& thread, std::wstring& output){ bool LunaHost::on_text_recv(TextThread &thread, std::wstring &output)
if(hasstoped)return true; {
if(!plugins->dispatch(thread,output))return false; if (hasstoped)
return true;
if (!plugins->dispatch(thread, output))
return false;
updatelisttext(output, (LONG_PTR)&thread); updatelisttext(output, (LONG_PTR)&thread);
if(currentselect==(LONG_PTR)&thread){ if (currentselect == (LONG_PTR)&thread)
{
showtext(output, false); showtext(output, false);
} }
return true; return true;
} }
void LunaHost::on_thread_create(TextThread& thread){ void LunaHost::on_thread_create(TextThread &thread)
{
wchar_t buff[65535]; wchar_t buff[65535];
swprintf_s(buff, L"%I64X:%s:%s:%I32X:%I64X:%I64X", swprintf_s(buff, L"%I64X:%s:%s:%I32X:%I64X:%I64X",
thread.handle, thread.handle,
@ -407,57 +458,67 @@ void LunaHost::on_thread_create(TextThread& thread){
thread.hp.hookcode, thread.hp.hookcode,
thread.tp.processId, thread.tp.processId,
thread.tp.ctx, thread.tp.ctx,
thread.tp.ctx2 thread.tp.ctx2);
);
int index = g_hListBox_listtext->additem(buff, NULL); int index = g_hListBox_listtext->additem(buff, NULL);
g_hListBox_listtext->setdata(index, (LONG_PTR)&thread); g_hListBox_listtext->setdata(index, (LONG_PTR)&thread);
on_text_recv_checkissaved(thread); on_text_recv_checkissaved(thread);
} }
void LunaHost::on_thread_delete(TextThread& thread){ void LunaHost::on_thread_delete(TextThread &thread)
{
if (currentselect == (LONG_PTR)&thread) if (currentselect == (LONG_PTR)&thread)
currentselect = 0; currentselect = 0;
int count = g_hListBox_listtext->count(); int count = g_hListBox_listtext->count();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++)
{
auto thread_p = g_hListBox_listtext->getdata(i); auto thread_p = g_hListBox_listtext->getdata(i);
if (thread_p== (LONG_PTR)&thread) { if (thread_p == (LONG_PTR)&thread)
{
g_hListBox_listtext->deleteitem(i); g_hListBox_listtext->deleteitem(i);
break; break;
} }
} }
} }
Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){ Settingwindow::Settingwindow(LunaHost *host) : mainwindow(host)
int height=30;int curry=10;int space=10; {
int labelwidth=300;int spinwidth=200; int height = 30;
int curry = 10;
int space = 10;
int labelwidth = 300;
int spinwidth = 200;
g_timeout = new spinbox(this, TextThread::flushDelay); g_timeout = new spinbox(this, TextThread::flushDelay);
g_codepage = new spinbox(this, Host::defaultCodepage); g_codepage = new spinbox(this, Host::defaultCodepage);
spinmaxbuffsize = new spinbox(this, TextThread::maxBufferSize); spinmaxbuffsize = new spinbox(this, TextThread::maxBufferSize);
;curry+=height+space; ;
curry += height + space;
spinmaxbuffsize->onvaluechange=[=](int v){ spinmaxbuffsize->onvaluechange = [=](int v)
{
TextThread::maxBufferSize = v; TextThread::maxBufferSize = v;
}; };
spinmaxhistsize = new spinbox(this, TextThread::maxHistorySize); spinmaxhistsize = new spinbox(this, TextThread::maxHistorySize);
;curry+=height+space; ;
curry += height + space;
spinmaxhistsize->onvaluechange=[=](int v){ spinmaxhistsize->onvaluechange = [=](int v)
{
TextThread::maxHistorySize = v; TextThread::maxHistorySize = v;
}; };
ckbfilterrepeat = new checkbox(this, LblFilterRepeat); ckbfilterrepeat = new checkbox(this, LblFilterRepeat);
ckbfilterrepeat->onclick=[=](){ ckbfilterrepeat->onclick = [=]()
{
TextThread::filterRepetition = ckbfilterrepeat->ischecked(); TextThread::filterRepetition = ckbfilterrepeat->ischecked();
}; };
ckbfilterrepeat->setcheck(TextThread::filterRepetition); ckbfilterrepeat->setcheck(TextThread::filterRepetition);
g_check_clipboard = new checkbox(this, BtnToClipboard); g_check_clipboard = new checkbox(this, BtnToClipboard);
g_check_clipboard->onclick=[=](){ g_check_clipboard->onclick = [=]()
{
host->check_toclipboard = g_check_clipboard->ischecked(); host->check_toclipboard = g_check_clipboard->ischecked();
}; };
g_check_clipboard->setcheck(host->check_toclipboard); g_check_clipboard->setcheck(host->check_toclipboard);
@ -469,45 +530,51 @@ Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){
// copyselect->setcheck(host->check_toclipboard_selection); // copyselect->setcheck(host->check_toclipboard_selection);
autoattach = new checkbox(this, LblAutoAttach); autoattach = new checkbox(this, LblAutoAttach);
autoattach->onclick=[=](){ autoattach->onclick = [=]()
{
host->autoattach = autoattach->ischecked(); host->autoattach = autoattach->ischecked();
}; };
autoattach->setcheck(host->autoattach); autoattach->setcheck(host->autoattach);
autoattach_so = new checkbox(this, LblAutoAttach_savedonly); autoattach_so = new checkbox(this, LblAutoAttach_savedonly);
autoattach_so->onclick=[=](){ autoattach_so->onclick = [=]()
{
host->autoattach_savedonly = autoattach_so->ischecked(); host->autoattach_savedonly = autoattach_so->ischecked();
}; };
autoattach_so->setcheck(host->autoattach_savedonly); autoattach_so->setcheck(host->autoattach_savedonly);
readonlycheck = new checkbox(this, BtnReadOnly); readonlycheck = new checkbox(this, BtnReadOnly);
readonlycheck->onclick=[=](){ readonlycheck->onclick = [=]()
{
host->g_showtexts->setreadonly(readonlycheck->ischecked()); host->g_showtexts->setreadonly(readonlycheck->ischecked());
}; };
readonlycheck->setcheck(true); readonlycheck->setcheck(true);
g_timeout->onvaluechange=[=](int v){ g_timeout->onvaluechange = [=](int v)
{
TextThread::flushDelay = v; TextThread::flushDelay = v;
}; };
g_codepage->onvaluechange=[=](int v){ g_codepage->onvaluechange = [=](int v)
if(IsValidCodePage(v)){ {
if (IsValidCodePage(v))
{
Host::defaultCodepage = v; Host::defaultCodepage = v;
} }
}; };
g_codepage->setminmax(0, CP_UTF8); g_codepage->setminmax(0, CP_UTF8);
showfont = new lineedit(this); showfont = new lineedit(this);
showfont->settext(host->defaultFont); showfont->settext(host->uifont.fontfamily);
showfont->setreadonly(true); showfont->setreadonly(true);
selectfont = new button(this, FONTSELECT); selectfont = new button(this, FONTSELECT);
selectfont->onclick=[=](){ selectfont->onclick = [=]()
FontSelector(winId,host->defaultFont, [=](const std::wstring& _t){ {
showfont->settext(_t); FontSelector(winId, host->uifont, [=](const Font &f)
host->defaultFont=_t; {
host->setfont(25,_t.c_str()); host->uifont=f;
}); showfont->settext(f.fontfamily);
host->setfont(f); });
}; };
mainlayout = new gridlayout(); mainlayout = new gridlayout();
@ -535,15 +602,19 @@ Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){
setcentral(600, 500); setcentral(600, 500);
settext(WndSetting); settext(WndSetting);
} }
void Pluginwindow::on_size(int w,int h){ void Pluginwindow::on_size(int w, int h)
{
listplugins->setgeo(10, 10, w - 20, h - 20); listplugins->setgeo(10, 10, w - 20, h - 20);
} }
void Pluginwindow::pluginrankmove(int moveoffset){ void Pluginwindow::pluginrankmove(int moveoffset)
{
auto idx = listplugins->currentidx(); auto idx = listplugins->currentidx();
if(idx==-1)return; if (idx == -1)
return;
auto idx2 = idx + moveoffset; auto idx2 = idx + moveoffset;
auto a = min(idx, idx2), b = max(idx, idx2); auto a = min(idx, idx2), b = max(idx, idx2);
if(a<0||b>=listplugins->count())return; if (a < 0 || b >= listplugins->count())
return;
pluginmanager->swaprank(a, b); pluginmanager->swaprank(a, b);
auto pa = ((LPCWSTR)listplugins->getdata(a)); auto pa = ((LPCWSTR)listplugins->getdata(a));
@ -553,18 +624,23 @@ void Pluginwindow::pluginrankmove(int moveoffset){
listplugins->insertitem(b, std::filesystem::path(pa).stem()); listplugins->insertitem(b, std::filesystem::path(pa).stem());
listplugins->setdata(b, (LONG_PTR)pa); listplugins->setdata(b, (LONG_PTR)pa);
} }
Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginmanager(pl){ Pluginwindow::Pluginwindow(mainwindow *p, Pluginmanager *pl) : mainwindow(p), pluginmanager(pl)
{
static auto listadd=[&](const std::wstring& s){ static auto listadd = [&](const std::wstring &s)
{
auto idx = listplugins->additem(std::filesystem::path(s).stem()); auto idx = listplugins->additem(std::filesystem::path(s).stem());
auto _s=new wchar_t[s.size()+1];wcscpy(_s,s.c_str()); auto _s = new wchar_t[s.size() + 1];
wcscpy(_s, s.c_str());
listplugins->setdata(idx, (LONG_PTR)_s); listplugins->setdata(idx, (LONG_PTR)_s);
}; };
listplugins = new listbox(this); listplugins = new listbox(this);
listplugins->on_menu=[&](){ listplugins->on_menu = [&]()
{
Menu menu; Menu menu;
menu.add(MenuAddPlugin,[&](){ menu.add(MenuAddPlugin, [&]()
{
if(auto f=pluginmanager->selectpluginfile()) if(auto f=pluginmanager->selectpluginfile())
switch (auto res=pluginmanager->addplugin(f.value())) switch (auto res=pluginmanager->addplugin(f.value()))
{ {
@ -578,48 +654,49 @@ Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p),pluginm
{addpluginresult::dumplicate,InvalidDump}, {addpluginresult::dumplicate,InvalidDump},
}; };
MessageBoxW(winId,errorlog[res],MsgError,0); MessageBoxW(winId,errorlog[res],MsgError,0);
} } });
});
auto idx = listplugins->currentidx(); auto idx = listplugins->currentidx();
if (idx != -1) if (idx != -1)
{ {
menu.add(MenuRemovePlugin,[&,idx](){ menu.add(MenuRemovePlugin, [&, idx]()
{
pluginmanager->remove((LPCWSTR)listplugins->getdata(idx)); pluginmanager->remove((LPCWSTR)listplugins->getdata(idx));
listplugins->deleteitem(idx); listplugins->deleteitem(idx); });
});
menu.add_sep(); menu.add_sep();
menu.add(MenuPluginRankUp, std::bind(&Pluginwindow::pluginrankmove, this, -1)); menu.add(MenuPluginRankUp, std::bind(&Pluginwindow::pluginrankmove, this, -1));
menu.add(MenuPluginRankDown, std::bind(&Pluginwindow::pluginrankmove, this, 1)); menu.add(MenuPluginRankDown, std::bind(&Pluginwindow::pluginrankmove, this, 1));
menu.add_sep(); menu.add_sep();
menu.add_checkable(MenuPluginEnable,pluginmanager->getenable(idx),[&,idx](bool check){ menu.add_checkable(MenuPluginEnable, pluginmanager->getenable(idx), [&, idx](bool check)
{
pluginmanager->setenable(idx,check); pluginmanager->setenable(idx,check);
if(check) if(check)
pluginmanager->load((LPCWSTR)listplugins->getdata(idx)); pluginmanager->load((LPCWSTR)listplugins->getdata(idx));
else else
pluginmanager->unload((LPCWSTR)listplugins->getdata(idx)); pluginmanager->unload((LPCWSTR)listplugins->getdata(idx)); });
});
if (pluginmanager->getvisible_setable(idx)) if (pluginmanager->getvisible_setable(idx))
menu.add_checkable(MenuPluginVisSetting,pluginmanager->getvisible(idx),[&,idx](bool check){ menu.add_checkable(MenuPluginVisSetting, pluginmanager->getvisible(idx), [&, idx](bool check)
pluginmanager->setvisible(idx,check); { pluginmanager->setvisible(idx, check); });
});
} }
return menu; return menu;
}; };
for (int i = 0; i < pluginmanager->count(); i++)
for(int i=0;i<pluginmanager->count();i++){ {
listadd(pluginmanager->getname(i)); listadd(pluginmanager->getname(i));
} }
settext(WndPlugins); settext(WndPlugins);
setcentral(500, 400); setcentral(500, 400);
} }
void HooksearchText::call(std::set<DWORD>pids){ void HooksearchText::call(std::set<DWORD> pids)
{
edittext->settext(L""); edittext->settext(L"");
checkok->onclick=[&,pids](){ checkok->onclick = [&, pids]()
{
close(); close();
auto cp = codepage->getcurr(); auto cp = codepage->getcurr();
if(!IsValidCodePage(cp)) return; if (!IsValidCodePage(cp))
return;
SearchParam sp = {}; SearchParam sp = {};
sp.codepage = cp; sp.codepage = cp;
wcsncpy_s(sp.text, edittext->text().c_str(), PATTERN_SIZE - 1); wcsncpy_s(sp.text, edittext->text().c_str(), PATTERN_SIZE - 1);
@ -628,7 +705,8 @@ void HooksearchText::call(std::set<DWORD>pids){
}; };
show(); show();
} }
HooksearchText::HooksearchText(mainwindow* p):mainwindow(p){ HooksearchText::HooksearchText(mainwindow *p) : mainwindow(p)
{
codepage = new spinbox(this, Host::defaultCodepage); codepage = new spinbox(this, Host::defaultCodepage);
codepage->setminmax(0, CP_UTF8); codepage->setminmax(0, CP_UTF8);
@ -643,19 +721,22 @@ HooksearchText::HooksearchText(mainwindow* p):mainwindow(p){
setlayout(layout); setlayout(layout);
setcentral(500, 200); setcentral(500, 200);
} }
std::wstring tohex(BYTE* bs,int len){ std::wstring tohex(BYTE *bs, int len)
{
std::wstring buffer; std::wstring buffer;
for (int i = 0; i < len; i += 1){ for (int i = 0; i < len; i += 1)
{
buffer.append(FormatString(L"%02hX ", bs[i])); buffer.append(FormatString(L"%02hX ", bs[i]));
} }
return buffer; return buffer;
} }
std::wstring addr2hex(uintptr_t addr){ std::wstring addr2hex(uintptr_t addr)
{
return FormatString(L"%p", addr); return FormatString(L"%p", addr);
} }
void realcallsearchhooks(std::set<DWORD>pids,std::wstring filter,SearchParam sp){ void realcallsearchhooks(std::set<DWORD> pids, std::wstring filter, SearchParam sp)
{
auto hooks = std::make_shared<std::vector<std::wstring>>(); auto hooks = std::make_shared<std::vector<std::wstring>>();
@ -666,17 +747,18 @@ void realcallsearchhooks(std::set<DWORD>pids,std::wstring filter,SearchParam sp)
[hooks, filter](HookParam hp, std::wstring text) [hooks, filter](HookParam hp, std::wstring text)
{ {
std::wsmatch matches; std::wsmatch matches;
if (std::regex_search(text, matches, std::wregex(filter))) { if (std::regex_search(text, matches, std::wregex(filter)))
{
hooks->emplace_back(std::wstring(hp.hookcode) + L"=>" + text); hooks->emplace_back(std::wstring(hp.hookcode) + L"=>" + text);
} }
}); });
} }
catch (std::exception &e) { catch (std::exception &e)
{
// std::wcout<<e.what(); // std::wcout<<e.what();
return; return;
} }
std::thread([hooks] std::thread([hooks]
{ {
for (int lastSize = 0; hooks->size() == 0 || hooks->size() != lastSize; Sleep(2000)) lastSize = hooks->size(); for (int lastSize = 0; hooks->size() == 0 || hooks->size() != lastSize; Sleep(2000)) lastSize = hooks->size();
@ -685,10 +767,11 @@ void realcallsearchhooks(std::set<DWORD>pids,std::wstring filter,SearchParam sp)
of.open("savehooks.txt"); of.open("savehooks.txt");
for (auto line:*hooks) of<<WideStringToString(line)<<"\n"; for (auto line:*hooks) of<<WideStringToString(line)<<"\n";
of.close(); of.close();
hooks->clear(); hooks->clear(); })
}).detach(); .detach();
} }
Hooksearchsetting::Hooksearchsetting(mainwindow* p):mainwindow(p){ Hooksearchsetting::Hooksearchsetting(mainwindow *p) : mainwindow(p)
{
layout = new gridlayout(); layout = new gridlayout();
SearchParam sp{}; SearchParam sp{};
spinduration = new spinbox(this, sp.searchTime); spinduration = new spinbox(this, sp.searchTime);
@ -731,30 +814,36 @@ Hooksearchsetting::Hooksearchsetting(mainwindow* p):mainwindow(p){
setlayout(layout); setlayout(layout);
setcentral(1000, 600); setcentral(1000, 600);
} }
std::vector<BYTE> hexStringToBytes(const std::wstring& hexString_) { std::vector<BYTE> hexStringToBytes(const std::wstring &hexString_)
{
auto hexString = hexString_; auto hexString = hexString_;
strReplace(hexString, L" ", L""); strReplace(hexString, L" ", L"");
strReplace(hexString, L"??", FormatString(L"%02hX", XX)); strReplace(hexString, L"??", FormatString(L"%02hX", XX));
std::vector<BYTE> bytes; std::vector<BYTE> bytes;
if (hexString.length() % 2 != 0) { if (hexString.length() % 2 != 0)
{
return {}; return {};
} }
for (int i = 0; i < hexString.size() / 2; i++) { for (int i = 0; i < hexString.size() / 2; i++)
{
auto byteValue = std::stoi(hexString.substr(i * 2, 2), nullptr, 16); auto byteValue = std::stoi(hexString.substr(i * 2, 2), nullptr, 16);
bytes.push_back(byteValue); bytes.push_back(byteValue);
} }
return bytes; return bytes;
} }
void Hooksearchsetting::call(std::set<DWORD>pids,std::wstring reg){ void Hooksearchsetting::call(std::set<DWORD> pids, std::wstring reg)
if(pids.empty())return; {
if (pids.empty())
return;
if (auto filename = getModuleFilename(*pids.begin())) if (auto filename = getModuleFilename(*pids.begin()))
editmodule->settext(std::filesystem::path(filename.value()).filename().wstring()); editmodule->settext(std::filesystem::path(filename.value()).filename().wstring());
editregex->settext(reg); editregex->settext(reg);
spincodepage->setcurr(Host::defaultCodepage); spincodepage->setcurr(Host::defaultCodepage);
start->onclick=[&,pids](){ start->onclick = [&, pids]()
{
close(); close();
SearchParam sp{}; SearchParam sp{};
sp.searchTime = spinduration->getcurr(); sp.searchTime = spinduration->getcurr();
@ -762,12 +851,14 @@ void Hooksearchsetting::call(std::set<DWORD>pids,std::wstring reg){
sp.maxRecords = spincap->getcurr(); sp.maxRecords = spincap->getcurr();
sp.codepage = spincodepage->getcurr(); sp.codepage = spincodepage->getcurr();
if(editpattern->text().find(L".")==std::wstring::npos){ if (editpattern->text().find(L".") == std::wstring::npos)
{
auto hex = hexStringToBytes(editpattern->text()); auto hex = hexStringToBytes(editpattern->text());
memcpy(sp.pattern, hex.data(), hex.size()); memcpy(sp.pattern, hex.data(), hex.size());
sp.length = hex.size(); sp.length = hex.size();
} }
else{ else
{
wcsncpy_s(sp.exportModule, editpattern->text().c_str(), MAX_MODULE_SIZE - 1); wcsncpy_s(sp.exportModule, editpattern->text().c_str(), MAX_MODULE_SIZE - 1);
sp.length = 1; sp.length = 1;
} }
@ -780,7 +871,8 @@ void Hooksearchsetting::call(std::set<DWORD>pids,std::wstring reg){
}; };
show(); show();
} }
Hooksearchwindow::Hooksearchwindow(LunaHost* host):mainwindow(host){ Hooksearchwindow::Hooksearchwindow(LunaHost *host) : mainwindow(host)
{
cjkcheck = new checkbox(this, SEARCH_CJK); cjkcheck = new checkbox(this, SEARCH_CJK);
hs_default = new button(this, HS_START_HOOK_SEARCH); hs_default = new button(this, HS_START_HOOK_SEARCH);
@ -803,14 +895,14 @@ Hooksearchwindow::Hooksearchwindow(LunaHost* host):mainwindow(host){
close(); close();
if (type == 1) if (type == 1)
{ {
if(hooksearchText==0) hooksearchText=new HooksearchText(this); if (hooksearchText == 0)
hooksearchText = new HooksearchText(this);
hooksearchText->call(host->attachedprocess); hooksearchText->call(host->attachedprocess);
return; return;
} }
auto filter = (cjkcheck->ischecked() ? L"[\\u3000-\\ua000]{4,}" : L"[\\u0020-\\u1000]{4,}"); auto filter = (cjkcheck->ischecked() ? L"[\\u3000-\\ua000]{4,}" : L"[\\u0020-\\u1000]{4,}");
if (type == 0) if (type == 0)
{ {
SearchParam sp = {}; SearchParam sp = {};
@ -820,11 +912,11 @@ Hooksearchwindow::Hooksearchwindow(LunaHost* host):mainwindow(host){
} }
else if (type == 2) else if (type == 2)
{ {
if(hooksearchsetting==0) hooksearchsetting=new Hooksearchsetting(this); if (hooksearchsetting == 0)
hooksearchsetting = new Hooksearchsetting(this);
hooksearchsetting->call(host->attachedprocess, filter); hooksearchsetting->call(host->attachedprocess, filter);
return; return;
} }
}; };
hs_default->onclick = std::bind(dohooksearchdispatch, 0); hs_default->onclick = std::bind(dohooksearchdispatch, 0);

View File

@ -4,15 +4,18 @@
#include "pluginmanager.h" #include "pluginmanager.h"
#include "confighelper.h" #include "confighelper.h"
class LunaHost; class LunaHost;
class Pluginwindow:public mainwindow{ class Pluginwindow : public mainwindow
{
listbox *listplugins; listbox *listplugins;
Pluginmanager *pluginmanager; Pluginmanager *pluginmanager;
public: public:
Pluginwindow(mainwindow *, Pluginmanager *); Pluginwindow(mainwindow *, Pluginmanager *);
void on_size(int w, int h); void on_size(int w, int h);
void pluginrankmove(int); void pluginrankmove(int);
}; };
class Settingwindow:public mainwindow{ class Settingwindow : public mainwindow
{
checkbox *ckbfilterrepeat; checkbox *ckbfilterrepeat;
spinbox *g_timeout; spinbox *g_timeout;
spinbox *g_codepage; spinbox *g_codepage;
@ -26,11 +29,13 @@ class Settingwindow:public mainwindow{
gridlayout *mainlayout; gridlayout *mainlayout;
lineedit *showfont; lineedit *showfont;
button *selectfont; button *selectfont;
public: public:
Settingwindow(LunaHost *); Settingwindow(LunaHost *);
}; };
class processlistwindow:public mainwindow{ class processlistwindow : public mainwindow
{
gridlayout *mainlayout; gridlayout *mainlayout;
lineedit *g_hEdit; lineedit *g_hEdit;
button *g_hButton; button *g_hButton;
@ -38,20 +43,24 @@ class processlistwindow:public mainwindow{
button *g_refreshbutton; button *g_refreshbutton;
std::unordered_map<std::wstring, std::vector<int>> g_exe_pid; std::unordered_map<std::wstring, std::vector<int>> g_exe_pid;
void PopulateProcessList(listview *, std::unordered_map<std::wstring, std::vector<int>> &); void PopulateProcessList(listview *, std::unordered_map<std::wstring, std::vector<int>> &);
public: public:
processlistwindow(mainwindow *parent = 0); processlistwindow(mainwindow *parent = 0);
void on_show(); void on_show();
}; };
class HooksearchText:public mainwindow{ class HooksearchText : public mainwindow
{
gridlayout *layout; gridlayout *layout;
lineedit *edittext; lineedit *edittext;
button *checkok; button *checkok;
spinbox *codepage; spinbox *codepage;
public: public:
HooksearchText(mainwindow *); HooksearchText(mainwindow *);
void call(std::set<DWORD> pids); void call(std::set<DWORD> pids);
}; };
class Hooksearchsetting:public mainwindow{ class Hooksearchsetting : public mainwindow
{
gridlayout *layout; gridlayout *layout;
spinbox *spinduration; spinbox *spinduration;
spinbox *spinoffset; spinbox *spinoffset;
@ -64,20 +73,24 @@ class Hooksearchsetting:public mainwindow{
spinbox *spinpadding; spinbox *spinpadding;
lineedit *editregex; lineedit *editregex;
button *start; button *start;
public: public:
Hooksearchsetting(mainwindow *); Hooksearchsetting(mainwindow *);
void call(std::set<DWORD> pids, std::wstring); void call(std::set<DWORD> pids, std::wstring);
}; };
class Hooksearchwindow:public mainwindow{ class Hooksearchwindow : public mainwindow
{
checkbox *cjkcheck; checkbox *cjkcheck;
button *hs_default, *hs_text, *hs_user; button *hs_default, *hs_text, *hs_user;
gridlayout *layout; gridlayout *layout;
Hooksearchsetting *hooksearchsetting = 0; Hooksearchsetting *hooksearchsetting = 0;
HooksearchText *hooksearchText = 0; HooksearchText *hooksearchText = 0;
public: public:
Hooksearchwindow(LunaHost *parent); Hooksearchwindow(LunaHost *parent);
}; };
class LunaHost:public mainwindow{ class LunaHost : public mainwindow
{
Pluginwindow *pluginwindow = 0; Pluginwindow *pluginwindow = 0;
std::set<DWORD> attachedprocess; std::set<DWORD> attachedprocess;
lineedit *g_hEdit_userhook; lineedit *g_hEdit_userhook;
@ -106,12 +119,13 @@ class LunaHost:public mainwindow{
void showtext(const std::wstring &text, bool clear); void showtext(const std::wstring &text, bool clear);
void updatelisttext(const std::wstring &text, LONG_PTR data); void updatelisttext(const std::wstring &text, LONG_PTR data);
public: public:
confighelper *configs; confighelper *configs;
int64_t currentselect = 0; int64_t currentselect = 0;
bool check_toclipboard; bool check_toclipboard;
bool check_toclipboard_selection; bool check_toclipboard_selection;
std::wstring defaultFont; Font uifont;
bool autoattach; bool autoattach;
bool autoattach_savedonly; bool autoattach_savedonly;
std::set<std::string> autoattachexes; std::set<std::string> autoattachexes;
@ -121,10 +135,10 @@ public:
LunaHost(); LunaHost();
friend class Settingwindow; friend class Settingwindow;
friend class Hooksearchwindow; friend class Hooksearchwindow;
private: private:
void loadsettings(); void loadsettings();
void savesettings(); void savesettings();
void doautoattach(); void doautoattach();
}; };

View File

@ -33,20 +33,21 @@
#endif #endif
#define fnQApplication_processEvents "?processEvents@QCoreApplication@@SAXV?$QFlags@W4ProcessEventsFlag@QEventLoop@@@@@Z" #define fnQApplication_processEvents "?processEvents@QCoreApplication@@SAXV?$QFlags@W4ProcessEventsFlag@QEventLoop@@@@@Z"
FARPROC QString_fromStdWString, QCoreApplication_addLibraryPath, QString_dtor, QApplication_ctor, QFont_ctor, QFont_dtor, QApplication_setFont, QApplication_exec, QApplication_dtor, QApplication_processEvents; FARPROC QString_fromStdWString, QCoreApplication_addLibraryPath, QString_dtor, QApplication_ctor, QFont_ctor, QFont_dtor, QApplication_setFont, QApplication_exec, QApplication_dtor, QApplication_processEvents;
bool checkqterror()
bool checkqterror(){ {
return QString_fromStdWString == 0 || QCoreApplication_addLibraryPath == 0 || QString_dtor == 0 || QApplication_ctor == 0 || QFont_ctor == 0 || QFont_dtor == 0 || QApplication_setFont == 0 || QApplication_exec == 0 || QApplication_dtor == 0 || QApplication_processEvents == 0; return QString_fromStdWString == 0 || QCoreApplication_addLibraryPath == 0 || QString_dtor == 0 || QApplication_ctor == 0 || QFont_ctor == 0 || QFont_dtor == 0 || QApplication_setFont == 0 || QApplication_exec == 0 || QApplication_dtor == 0 || QApplication_processEvents == 0;
} }
void loadqtdlls(){ void loadqtdlls()
{
QString_fromStdWString = QCoreApplication_addLibraryPath = QString_dtor = QApplication_ctor = QFont_ctor = QFont_dtor = QApplication_setFont = QApplication_exec = QApplication_dtor = QApplication_processEvents = 0; QString_fromStdWString = QCoreApplication_addLibraryPath = QString_dtor = QApplication_ctor = QFont_ctor = QFont_dtor = QApplication_setFont = QApplication_exec = QApplication_dtor = QApplication_processEvents = 0;
auto Qt5Widgets = LoadLibrary(L"Qt5Widgets.dll"); auto Qt5Widgets = LoadLibrary(L"Qt5Widgets.dll");
auto Qt5Gui = LoadLibrary(L"Qt5Gui.dll"); auto Qt5Gui = LoadLibrary(L"Qt5Gui.dll");
auto Qt5Core = LoadLibrary(L"Qt5Core.dll"); auto Qt5Core = LoadLibrary(L"Qt5Core.dll");
if(Qt5Core==0||Qt5Gui==0||Qt5Widgets==0)return; if (Qt5Core == 0 || Qt5Gui == 0 || Qt5Widgets == 0)
return;
QString_fromStdWString = GetProcAddress(Qt5Core, fnQString_fromStdWString); QString_fromStdWString = GetProcAddress(Qt5Core, fnQString_fromStdWString);
QCoreApplication_addLibraryPath = GetProcAddress(Qt5Core, fnQCoreApplication_addLibraryPath); QCoreApplication_addLibraryPath = GetProcAddress(Qt5Core, fnQCoreApplication_addLibraryPath);
@ -59,7 +60,8 @@ void loadqtdlls(){
QApplication_dtor = GetProcAddress(Qt5Widgets, fnQApplication_dtor); QApplication_dtor = GetProcAddress(Qt5Widgets, fnQApplication_dtor);
QApplication_processEvents = GetProcAddress(Qt5Core, fnQApplication_processEvents); QApplication_processEvents = GetProcAddress(Qt5Core, fnQApplication_processEvents);
} }
struct info{ struct info
{
int type; int type;
std::wstring dll; std::wstring dll;
HMODULE hdll; HMODULE hdll;
@ -67,18 +69,23 @@ struct info{
lockedqueue<info> waitingtask; lockedqueue<info> waitingtask;
lockedqueue<HMODULE> waitingresult; lockedqueue<HMODULE> waitingresult;
extern "C" __declspec(dllexport) void QtStartUp(std::vector<std::wstring>* dlls){ extern "C" __declspec(dllexport) void QtStartUp(std::vector<std::wstring> *dlls)
{
static bool once = false; static bool once = false;
if(once)return; if (once)
return;
loadqtdlls(); loadqtdlls();
once = !checkqterror(); once = !checkqterror();
if(!once)return; if (!once)
std::thread([=](){ return;
std::thread([=]()
{
static void *qapp; // 必须static static void *qapp; // 必须static
void *qstring; void *qstring;
void *qfont; void *qfont;
for(int i=0;i<dlls->size();i++){ for (int i = 0; i < dlls->size(); i++)
{
auto dirname = std::filesystem::path(dlls->at(i)).parent_path().wstring(); auto dirname = std::filesystem::path(dlls->at(i)).parent_path().wstring();
((void *(_CDECL *)(void *, void *))QString_fromStdWString)(&qstring, &dirname); ((void *(_CDECL *)(void *, void *))QString_fromStdWString)(&qstring, &dirname);
((void(_CDECL *)(void *))QCoreApplication_addLibraryPath)(&qstring); ((void(_CDECL *)(void *))QCoreApplication_addLibraryPath)(&qstring);
@ -117,31 +124,33 @@ extern "C" __declspec(dllexport) void QtStartUp(std::vector<std::wstring>* dlls)
// ((void(*)())QApplication_exec)(); // ((void(*)())QApplication_exec)();
// ((void(THISCALL*)(void*))QApplication_dtor)(&qapp); // ((void(THISCALL*)(void*))QApplication_dtor)(&qapp);
})
}).detach(); .detach();
} }
std::mutex loadmutex; std::mutex loadmutex;
extern "C" __declspec(dllexport) std::vector<HMODULE>* QtLoadLibraryBatch(std::vector<std::wstring>* dlls){ extern "C" __declspec(dllexport) std::vector<HMODULE> *QtLoadLibraryBatch(std::vector<std::wstring> *dlls)
{
std::lock_guard _(loadmutex); std::lock_guard _(loadmutex);
QtStartUp(dlls); QtStartUp(dlls);
auto hdlls = new std::vector<HMODULE>; auto hdlls = new std::vector<HMODULE>;
for(int i=0;i<dlls->size();i++){ for (int i = 0; i < dlls->size(); i++)
if(checkqterror()){ {
if (checkqterror())
{
hdlls->push_back(0); hdlls->push_back(0);
} }
else{ else
{
waitingtask.push({1, dlls->at(i)}); waitingtask.push({1, dlls->at(i)});
hdlls->push_back(waitingresult.pop()); hdlls->push_back(waitingresult.pop());
} }
} }
return hdlls; return hdlls;
} }
extern "C" __declspec(dllexport) void QtFreeLibrary(HMODULE hd)
extern "C" __declspec(dllexport) void QtFreeLibrary(HMODULE hd){ {
std::lock_guard _(loadmutex); std::lock_guard _(loadmutex);
waitingtask.push({2, L"", hd}); waitingtask.push({2, L"", hd});
} }

View File

@ -1,9 +1,11 @@
#include "confighelper.h" #include "confighelper.h"
#include "stringutils.h" #include "stringutils.h"
std::string readfile(const wchar_t* fname) { std::string readfile(const wchar_t *fname)
{
FILE *f; FILE *f;
_wfopen_s(&f, fname, L"rb"); _wfopen_s(&f, fname, L"rb");
if (f == 0)return {}; if (f == 0)
return {};
fseek(f, 0, SEEK_END); fseek(f, 0, SEEK_END);
auto len = ftell(f); auto len = ftell(f);
fseek(f, 0, SEEK_SET); fseek(f, 0, SEEK_SET);
@ -13,28 +15,33 @@ std::string readfile(const wchar_t* fname) {
fclose(f); fclose(f);
return buff; return buff;
} }
void writefile(const wchar_t* fname,const std::string& s){ void writefile(const wchar_t *fname, const std::string &s)
{
FILE *f; FILE *f;
_wfopen_s(&f, fname, L"w"); _wfopen_s(&f, fname, L"w");
fprintf(f, "%s", s.c_str()); fprintf(f, "%s", s.c_str());
fclose(f); fclose(f);
} }
confighelper::confighelper(){ confighelper::confighelper()
{
configpath = std::filesystem::current_path() / (x64 ? "config64.json" : "config32.json"); configpath = std::filesystem::current_path() / (x64 ? "config64.json" : "config32.json");
try{ try
{
configs = nlohmann::json::parse(readfile(configpath.c_str())); configs = nlohmann::json::parse(readfile(configpath.c_str()));
} }
catch(std::exception &){ catch (std::exception &)
{
configs = {}; configs = {};
} }
if(configs.find("plugins")==configs.end()){ if (configs.find("plugins") == configs.end())
{
configs["plugins"] = {}; configs["plugins"] = {};
} }
} }
confighelper::~confighelper(){ confighelper::~confighelper()
{
writefile(configpath.c_str(), configs.dump(4)); writefile(configpath.c_str(), configs.dump(4));
} }

View File

@ -2,25 +2,32 @@
#define LUNA_CONFIG_HELPER #define LUNA_CONFIG_HELPER
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
class confighelper{ class confighelper
{
std::wstring configpath; std::wstring configpath;
public: public:
nlohmann::json configs; nlohmann::json configs;
confighelper(); confighelper();
~confighelper(); ~confighelper();
template <class T> template <class T>
T get(const std::string&key,T default1){ T get(const std::string &key, T default1)
if(configs.find(key)==configs.end())return default1; {
if (configs.find(key) == configs.end())
return default1;
return configs[key]; return configs[key];
} }
template <class T> template <class T>
void set(const std::string&key,T v){ void set(const std::string &key, T v)
{
configs[key] = v; configs[key] = v;
} }
}; };
template <typename T> template <typename T>
T safequeryjson(const nlohmann::json& js,const std::string& key,const T &defaultv){ T safequeryjson(const nlohmann::json &js, const std::string &key, const T &defaultv)
if(js.find(key)==js.end()){ {
if (js.find(key) == js.end())
{
return defaultv; return defaultv;
} }
return js[key]; return js[key];

View File

@ -1,8 +1,10 @@
#include "controls.h" #include "controls.h"
#include "window.h" #include "window.h"
#include <commdlg.h> #include <commdlg.h>
control::control(mainwindow*_parent){ control::control(mainwindow *_parent)
if(_parent==0)return; {
if (_parent == 0)
return;
parent = _parent; parent = _parent;
parent->controls.push_back(this); parent->controls.push_back(this);
} }
@ -14,12 +16,15 @@ button::button(mainwindow* parent,const std::wstring& text):control(parent)
winId = CreateWindowEx(0, L"BUTTON", text.c_str(), WS_CHILD | WS_VISIBLE, winId = CreateWindowEx(0, L"BUTTON", text.c_str(), WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, parent->winId, NULL, NULL, NULL); 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
} }
void button::dispatch(WPARAM wparam){ void button::dispatch(WPARAM wparam)
if(wparam==BN_CLICKED){ {
if (wparam == BN_CLICKED)
{
onclick(); onclick();
} }
} }
bool checkbox::ischecked(){ bool checkbox::ischecked()
{
int state = SendMessage(winId, BM_GETCHECK, 0, 0); int state = SendMessage(winId, BM_GETCHECK, 0, 0);
return (state == BST_CHECKED); return (state == BST_CHECKED);
} }
@ -28,13 +33,16 @@ checkbox::checkbox(mainwindow* parent,const std::wstring& text):button(parent)
winId = CreateWindowEx(0, L"BUTTON", text.c_str(), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_RIGHTBUTTON, winId = CreateWindowEx(0, L"BUTTON", text.c_str(), WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX | BS_RIGHTBUTTON,
0, 0, 0, 0, parent->winId, NULL, NULL, NULL); 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
} }
void checkbox::setcheck(bool b){ void checkbox::setcheck(bool b)
{
SendMessage(winId, BM_SETCHECK, (WPARAM)BST_CHECKED * b, 0); SendMessage(winId, BM_SETCHECK, (WPARAM)BST_CHECKED * b, 0);
} }
int spinbox::getcurr(){ int spinbox::getcurr()
{
return SendMessage(hUpDown, UDM_GETPOS32, 0, 0); return SendMessage(hUpDown, UDM_GETPOS32, 0, 0);
} }
spinbox::spinbox(mainwindow* parent,int value):control(parent){ spinbox::spinbox(mainwindow *parent, int value) : control(parent)
{
winId = CreateWindowEx(0, L"EDIT", std::to_wstring(value).c_str(), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER, winId = CreateWindowEx(0, L"EDIT", std::to_wstring(value).c_str(), WS_CHILD | WS_VISIBLE | WS_BORDER | ES_NUMBER,
0, 0, 0, 0, parent->winId, NULL, NULL, NULL); 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
@ -51,215 +59,269 @@ void spinbox::setgeo(int x,int y,int w,int h)
MoveWindow(winId, x, y, w, h, TRUE); MoveWindow(winId, x, y, w, h, TRUE);
SendMessage(hUpDown, UDM_SETBUDDY, (WPARAM)winId, 0); SendMessage(hUpDown, UDM_SETBUDDY, (WPARAM)winId, 0);
} }
void spinbox::setcurr(int cur){ void spinbox::setcurr(int cur)
{
SendMessage(hUpDown, UDM_SETPOS32, 0, cur); SendMessage(hUpDown, UDM_SETPOS32, 0, cur);
} }
void spinbox::dispatch(WPARAM wparam){ void spinbox::dispatch(WPARAM wparam)
if(HIWORD(wparam)==EN_CHANGE){ {
bool ok=false;int value; if (HIWORD(wparam) == EN_CHANGE)
try{ {
bool ok = false;
int value;
try
{
value = std::stoi(text()); value = std::stoi(text());
ok = true; ok = true;
} }
catch(std::exception&){} catch (std::exception &)
if(ok){ {
if(value>maxv){ }
if (ok)
{
if (value > maxv)
{
setcurr(maxv); setcurr(maxv);
value = maxv; value = maxv;
} }
else if(value<minv){ else if (value < minv)
{
setcurr(minv); setcurr(minv);
value = minv; value = minv;
} }
else{ else
{
onvaluechange(value); onvaluechange(value);
} }
} }
} }
} }
std::pair<int,int>spinbox::getminmax(){ std::pair<int, int> spinbox::getminmax()
{
int minValue, maxValue; int minValue, maxValue;
SendMessage(hUpDown, UDM_GETRANGE32, (WPARAM)&minValue, (LPARAM)&maxValue); SendMessage(hUpDown, UDM_GETRANGE32, (WPARAM)&minValue, (LPARAM)&maxValue);
return {minValue, maxValue}; return {minValue, maxValue};
} }
void spinbox::setminmax(int min,int max){ void spinbox::setminmax(int min, int max)
{
SendMessage(hUpDown, UDM_SETRANGE32, min, max); SendMessage(hUpDown, UDM_SETRANGE32, min, max);
std::tie(minv, maxv) = getminmax(); std::tie(minv, maxv) = getminmax();
} }
multilineedit::multilineedit(mainwindow* parent):texteditbase(parent){ multilineedit::multilineedit(mainwindow *parent) : texteditbase(parent)
{
winId = CreateWindowEx(0, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL, winId = CreateWindowEx(0, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL,
0, 0, 0, 0, parent->winId, NULL, NULL, NULL); 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
SendMessage(winId, EM_SETLIMITTEXT, 0, 0); SendMessage(winId, EM_SETLIMITTEXT, 0, 0);
} }
std::wstring multilineedit::getsel(){ std::wstring multilineedit::getsel()
{
DWORD start, end; DWORD start, end;
SendMessage(winId, EM_GETSEL, reinterpret_cast<WPARAM>(&start), reinterpret_cast<LPARAM>(&end)); SendMessage(winId, EM_GETSEL, reinterpret_cast<WPARAM>(&start), reinterpret_cast<LPARAM>(&end));
int length = end - start; int length = end - start;
return text().substr(start, length); return text().substr(start, length);
} }
lineedit::lineedit(mainwindow* parent):texteditbase(parent){ lineedit::lineedit(mainwindow *parent) : texteditbase(parent)
{
winId = CreateWindowEx(0, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL, winId = CreateWindowEx(0, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
0, 0, 0, 0, parent->winId, NULL, NULL, NULL); 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
} }
texteditbase::texteditbase(mainwindow *parent) : control(parent) {} texteditbase::texteditbase(mainwindow *parent) : control(parent) {}
void texteditbase::setreadonly(bool ro){ void texteditbase::setreadonly(bool ro)
{
SendMessage(winId, EM_SETREADONLY, ro, 0); SendMessage(winId, EM_SETREADONLY, ro, 0);
} }
void texteditbase::scrolltoend(){ void texteditbase::scrolltoend()
{
int textLength = GetWindowTextLength(winId); int textLength = GetWindowTextLength(winId);
SendMessage(winId, EM_SETSEL, (WPARAM)textLength, (LPARAM)textLength); SendMessage(winId, EM_SETSEL, (WPARAM)textLength, (LPARAM)textLength);
SendMessage(winId, EM_SCROLLCARET, 0, 0); SendMessage(winId, EM_SCROLLCARET, 0, 0);
} }
void texteditbase::appendtext(const std::wstring& text){ void texteditbase::appendtext(const std::wstring &text)
{
auto _ = std::wstring(L"\r\n") + text; auto _ = std::wstring(L"\r\n") + text;
SendMessage(winId, EM_REPLACESEL, 0, (LPARAM)_.c_str()); SendMessage(winId, EM_REPLACESEL, 0, (LPARAM)_.c_str());
} }
void texteditbase::dispatch(WPARAM wparam){ void texteditbase::dispatch(WPARAM wparam)
if(HIWORD(wparam)==EN_CHANGE){ {
if (HIWORD(wparam) == EN_CHANGE)
{
ontextchange(text()); ontextchange(text());
} }
} }
label::label(mainwindow* parent,const std::wstring& text):control(parent){ label::label(mainwindow *parent, const std::wstring &text) : control(parent)
{
winId = CreateWindowEx(0, L"STATIC", text.c_str(), WS_CHILD | WS_VISIBLE, winId = CreateWindowEx(0, L"STATIC", text.c_str(), WS_CHILD | WS_VISIBLE,
0, 0, 0, 0, parent->winId, NULL, NULL, NULL); 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
} }
listbox::listbox(mainwindow* parent):control(parent){ listbox::listbox(mainwindow *parent) : control(parent)
{
winId = CreateWindowEx(WS_EX_CLIENTEDGE, L"LISTBOX", L"", WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT, winId = CreateWindowEx(WS_EX_CLIENTEDGE, L"LISTBOX", L"", WS_CHILD | WS_VISIBLE | WS_VSCROLL | LBS_NOTIFY | LBS_NOINTEGRALHEIGHT,
0, 0, 0, 0, parent->winId, NULL, NULL, NULL); 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
} }
void listbox::dispatch(WPARAM wparam){ void listbox::dispatch(WPARAM wparam)
if(HIWORD(wparam) == LBN_SELCHANGE){ {
if (HIWORD(wparam) == LBN_SELCHANGE)
{
auto idx = currentidx(); auto idx = currentidx();
if (idx != -1) if (idx != -1)
oncurrentchange(idx); oncurrentchange(idx);
} }
} }
void listbox::setcurrent(int idx){ void listbox::setcurrent(int idx)
{
SendMessage(winId, LB_SETCURSEL, idx, 0); SendMessage(winId, LB_SETCURSEL, idx, 0);
if (idx != -1) if (idx != -1)
oncurrentchange(idx); oncurrentchange(idx);
} }
int listbox::currentidx(){ int listbox::currentidx()
{
return SendMessage(winId, LB_GETCURSEL, 0, 0); return SendMessage(winId, LB_GETCURSEL, 0, 0);
} }
std::wstring listbox::text(int idx){ std::wstring listbox::text(int idx)
{
int textLength = SendMessage(winId, LB_GETTEXTLEN, idx, 0); int textLength = SendMessage(winId, LB_GETTEXTLEN, idx, 0);
std::vector<wchar_t> buffer(textLength + 1); std::vector<wchar_t> buffer(textLength + 1);
SendMessage(winId, LB_GETTEXT, idx, (LPARAM)buffer.data()); SendMessage(winId, LB_GETTEXT, idx, (LPARAM)buffer.data());
return buffer.data(); return buffer.data();
} }
void listbox::clear(){ void listbox::clear()
{
SendMessage(winId, LB_RESETCONTENT, 0, 0); SendMessage(winId, LB_RESETCONTENT, 0, 0);
} }
int listbox::additem(const std::wstring& text){ int listbox::additem(const std::wstring &text)
{
return SendMessage(winId, LB_ADDSTRING, 0, (LPARAM)text.c_str()); return SendMessage(winId, LB_ADDSTRING, 0, (LPARAM)text.c_str());
} }
void listbox::deleteitem(int i){ void listbox::deleteitem(int i)
{
SendMessage(winId, LB_DELETESTRING, (WPARAM)i, (LPARAM)i); SendMessage(winId, LB_DELETESTRING, (WPARAM)i, (LPARAM)i);
} }
void listbox::setdata(int idx,LONG_PTR data){ void listbox::setdata(int idx, LONG_PTR data)
{
SendMessage(winId, LB_SETITEMDATA, idx, (LPARAM)data); SendMessage(winId, LB_SETITEMDATA, idx, (LPARAM)data);
} }
LONG_PTR listbox::getdata(int idx){ LONG_PTR listbox::getdata(int idx)
{
return SendMessage(winId, LB_GETITEMDATA, idx, 0); return SendMessage(winId, LB_GETITEMDATA, idx, 0);
} }
int listbox::count(){ int listbox::count()
{
return SendMessage(winId, LB_GETCOUNT, 0, 0); return SendMessage(winId, LB_GETCOUNT, 0, 0);
} }
int listbox::insertitem(int i,const std::wstring& t){ int listbox::insertitem(int i, const std::wstring &t)
{
return SendMessage(winId, LB_INSERTSTRING, i, (LPARAM)t.c_str()); return SendMessage(winId, LB_INSERTSTRING, i, (LPARAM)t.c_str());
} }
void listview::deleteitem(int i){ void listview::deleteitem(int i)
{
std::lock_guard _(lockdataidx); std::lock_guard _(lockdataidx);
assodata.erase(assodata.begin() + i); assodata.erase(assodata.begin() + i);
for(auto& data:remapidx){ for (auto &data : remapidx)
{
if (data.second >= i) if (data.second >= i)
data.second -= 1; data.second -= 1;
} }
ListView_DeleteItem(winId, i); ListView_DeleteItem(winId, i);
} }
listview::listview(mainwindow* parent,bool _addicon,bool notheader):control(parent),addicon(_addicon){ listview::listview(mainwindow *parent, bool _addicon, bool notheader) : control(parent), addicon(_addicon)
{
auto style = WS_VISIBLE | WS_VSCROLL | WS_CHILD | LVS_REPORT | LVS_SINGLESEL; auto style = WS_VISIBLE | WS_VSCROLL | WS_CHILD | LVS_REPORT | LVS_SINGLESEL;
if(notheader)style|=LVS_NOCOLUMNHEADER; if (notheader)
style |= LVS_NOCOLUMNHEADER;
winId = CreateWindowEx(0, WC_LISTVIEW, NULL, style, 0, 0, 0, 0, parent->winId, NULL, NULL, NULL); winId = CreateWindowEx(0, WC_LISTVIEW, NULL, style, 0, 0, 0, 0, parent->winId, NULL, NULL, NULL);
ListView_SetExtendedListViewStyle(winId, LVS_EX_FULLROWSELECT); // Set extended styles ListView_SetExtendedListViewStyle(winId, LVS_EX_FULLROWSELECT); // Set extended styles
if(addicon){ if (addicon)
{
hImageList = ImageList_Create(22, 22, // GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON), hImageList = ImageList_Create(22, 22, // GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
ILC_COLOR32, 1, 1); ILC_COLOR32, 1, 1);
ListView_SetImageList(winId, hImageList, LVSIL_SMALL); ListView_SetImageList(winId, hImageList, LVSIL_SMALL);
} }
} }
int listview::insertcol(int i,const std::wstring& text){ int listview::insertcol(int i, const std::wstring &text)
{
LVCOLUMN lvc; LVCOLUMN lvc;
lvc.mask = LVCF_TEXT; lvc.mask = LVCF_TEXT;
lvc.pszText = const_cast<LPWSTR>(text.c_str()); lvc.pszText = const_cast<LPWSTR>(text.c_str());
// lvc.cx = 100; // lvc.cx = 100;
return ListView_InsertColumn(winId, i, &lvc); return ListView_InsertColumn(winId, i, &lvc);
} }
void listview::settext(int row,int col,const std::wstring& text){ void listview::settext(int row, int col, const std::wstring &text)
{
ListView_SetItemText(winId, row, col, const_cast<LPWSTR>(text.c_str())); ListView_SetItemText(winId, row, col, const_cast<LPWSTR>(text.c_str()));
} }
int listview::insertitem(int row,const std::wstring& text,HICON hicon){ int listview::insertitem(int row, const std::wstring &text, HICON hicon)
{
LVITEM lvi; LVITEM lvi;
lvi.pszText = const_cast<LPWSTR>(text.c_str()); lvi.pszText = const_cast<LPWSTR>(text.c_str());
lvi.iItem = row; lvi.iItem = row;
lvi.iSubItem = 0; lvi.iSubItem = 0;
lvi.mask = LVIF_TEXT; lvi.mask = LVIF_TEXT;
if(addicon && hicon && hImageList){ if (addicon && hicon && hImageList)
{
lvi.mask |= LVIF_IMAGE; lvi.mask |= LVIF_IMAGE;
lvi.iImage = ImageList_AddIcon(hImageList, hicon); lvi.iImage = ImageList_AddIcon(hImageList, hicon);
} }
std::lock_guard _(lockdataidx); std::lock_guard _(lockdataidx);
assodata.resize(assodata.size() + 1); assodata.resize(assodata.size() + 1);
std::rotate(assodata.begin() + row, assodata.begin() + row + 1, assodata.end()); std::rotate(assodata.begin() + row, assodata.begin() + row + 1, assodata.end());
for(auto& data:remapidx){ for (auto &data : remapidx)
{
if (data.second >= row) if (data.second >= row)
data.second += 1; data.second += 1;
} }
return ListView_InsertItem(winId, &lvi); return ListView_InsertItem(winId, &lvi);
} }
int listview::additem(const std::wstring& text,HICON hicon){ int listview::additem(const std::wstring &text, HICON hicon)
{
return insertitem(count(), text, hicon); return insertitem(count(), text, hicon);
} }
LONG_PTR listview::getdata(int idx){ LONG_PTR listview::getdata(int idx)
{
std::lock_guard _(lockdataidx); std::lock_guard _(lockdataidx);
return assodata[idx]; return assodata[idx];
} }
int listview::querydataidx(LONG_PTR data){ int listview::querydataidx(LONG_PTR data)
{
std::lock_guard _(lockdataidx); std::lock_guard _(lockdataidx);
if(remapidx.find(data)==remapidx.end())return -1; if (remapidx.find(data) == remapidx.end())
return -1;
return remapidx[data]; return remapidx[data];
} }
void listview::setdata(int idx,LONG_PTR data){ void listview::setdata(int idx, LONG_PTR data)
{
std::lock_guard _(lockdataidx); std::lock_guard _(lockdataidx);
assodata[idx] = data; assodata[idx] = data;
remapidx[data] = idx; remapidx[data] = idx;
} }
void listview::clear(){ void listview::clear()
{
ListView_DeleteAllItems(winId); ListView_DeleteAllItems(winId);
if (addicon && hImageList) if (addicon && hImageList)
ImageList_RemoveAll(hImageList); ImageList_RemoveAll(hImageList);
} }
int listview::count(){ int listview::count()
{
return ListView_GetItemCount(winId); return ListView_GetItemCount(winId);
} }
int listview::currentidx(){ int listview::currentidx()
{
return ListView_GetNextItem(winId, -1, LVNI_SELECTED); return ListView_GetNextItem(winId, -1, LVNI_SELECTED);
} }
void listview::setcurrent(int idx){ void listview::setcurrent(int idx)
{
ListView_SetItemState(winId, idx, LVIS_SELECTED, LVIS_SELECTED); ListView_SetItemState(winId, idx, LVIS_SELECTED, LVIS_SELECTED);
} }
void listview::dispatch_2(WPARAM wParam, LPARAM lParam){ void listview::dispatch_2(WPARAM wParam, LPARAM lParam)
{
NMHDR *pnmhdr = (NMHDR *)lParam; NMHDR *pnmhdr = (NMHDR *)lParam;
switch (pnmhdr->code){ switch (pnmhdr->code)
{
case LVN_ITEMCHANGED: case LVN_ITEMCHANGED:
{ {
@ -272,8 +334,10 @@ void listview::dispatch_2(WPARAM wParam, LPARAM lParam){
} }
} }
} }
std::wstring listview::text(int row,int col){ std::wstring listview::text(int row, int col)
std::wstring text;text.resize(65535); {
std::wstring text;
text.resize(65535);
LV_ITEM _macro_lvi; LV_ITEM _macro_lvi;
_macro_lvi.iSubItem = (col); _macro_lvi.iSubItem = (col);
_macro_lvi.cchTextMax = (65535); _macro_lvi.cchTextMax = (65535);
@ -281,43 +345,51 @@ std::wstring listview::text(int row,int col){
SNDMSG((winId), LVM_GETITEMTEXT, (WPARAM)(row), (LPARAM)(LV_ITEM *)&_macro_lvi); SNDMSG((winId), LVM_GETITEMTEXT, (WPARAM)(row), (LPARAM)(LV_ITEM *)&_macro_lvi);
return text.c_str(); return text.c_str();
} }
void listview::setheader(const std::vector<std::wstring>& headers){ void listview::setheader(const std::vector<std::wstring> &headers)
for(int i=0;i<headers.size();i++){ {
for (int i = 0; i < headers.size(); i++)
{
insertcol(i, headers[i]); insertcol(i, headers[i]);
} }
headernum = headers.size(); headernum = headers.size();
if (headernum == 1) if (headernum == 1)
ListView_SetColumnWidth(winId, 0, LVSCW_AUTOSIZE_USEHEADER); ListView_SetColumnWidth(winId, 0, LVSCW_AUTOSIZE_USEHEADER);
else if(headernum==2){ else if (headernum == 2)
{
ListView_SetColumnWidth(winId, 0, 0x180); ListView_SetColumnWidth(winId, 0, 0x180);
} }
} }
void listview::on_size(int w,int){ void listview::on_size(int w, int)
{
if (headernum == 1) if (headernum == 1)
ListView_SetColumnWidth(winId, 0, LVSCW_AUTOSIZE_USEHEADER); ListView_SetColumnWidth(winId, 0, LVSCW_AUTOSIZE_USEHEADER);
else if(headernum==2){ else if (headernum == 2)
{
auto w0 = ListView_GetColumnWidth(winId, 0); auto w0 = ListView_GetColumnWidth(winId, 0);
ListView_SetColumnWidth(winId, 1, w - w0); ListView_SetColumnWidth(winId, 1, w - w0);
} }
} }
void gridlayout::setgeo(int x,int y,int w,int h){ void gridlayout::setgeo(int x, int y, int w, int h)
{
auto dynarow = maxrow; auto dynarow = maxrow;
auto dynacol = maxcol; auto dynacol = maxcol;
for(auto fw:fixedwidth){ for (auto fw : fixedwidth)
{
dynacol -= 1; dynacol -= 1;
w -= fw.second + margin; w -= fw.second + margin;
} }
for(auto fh:fixedheight){ for (auto fh : fixedheight)
{
dynarow -= 1; dynarow -= 1;
h -= fh.second + margin; h -= fh.second + margin;
} }
auto wpercol = (w - margin * (dynacol + 1)) / dynacol; auto wpercol = (w - margin * (dynacol + 1)) / dynacol;
auto hperrow = (h - margin * (dynarow + 1)) / dynarow; auto hperrow = (h - margin * (dynarow + 1)) / dynarow;
for(auto ctr:savecontrol){ for (auto ctr : savecontrol)
{
int _x = 0, _y = 0, _w = 0, _h = 0; int _x = 0, _y = 0, _w = 0, _h = 0;
for (int c = 0; c < ctr.col + ctr.colrange; c++) for (int c = 0; c < ctr.col + ctr.colrange; c++)
@ -327,12 +399,10 @@ void gridlayout::setgeo(int x,int y,int w,int h){
_x += fixedwidth[c]; _x += fixedwidth[c];
else else
_w += fixedwidth[c]; _w += fixedwidth[c];
else else if (c < ctr.col)
if(c<ctr.col)
_x += wpercol; _x += wpercol;
else else
_w += wpercol; _w += wpercol;
} }
_x += (ctr.col + 1) * margin; _x += (ctr.col + 1) * margin;
_w += (ctr.colrange - 1) * margin; _w += (ctr.colrange - 1) * margin;
@ -343,8 +413,7 @@ void gridlayout::setgeo(int x,int y,int w,int h){
_y += fixedheight[r]; _y += fixedheight[r];
else else
_h += fixedheight[r]; _h += fixedheight[r];
else else if (r < ctr.row)
if(r<ctr.row)
_y += hperrow; _y += hperrow;
else else
_h += hperrow; _h += hperrow;
@ -355,60 +424,70 @@ void gridlayout::setgeo(int x,int y,int w,int h){
ctr.ctr->setgeo(_x, _y, _w, _h); ctr.ctr->setgeo(_x, _y, _w, _h);
} }
} }
void gridlayout::setfixedwidth(int col,int width){ void gridlayout::setfixedwidth(int col, int width)
{
fixedwidth.insert({col, width}); fixedwidth.insert({col, width});
} }
void gridlayout::setfixedheigth(int row,int height){ void gridlayout::setfixedheigth(int row, int height)
{
fixedheight.insert({row, height}); fixedheight.insert({row, height});
} }
void gridlayout::addcontrol(control* _c,int row,int col,int rowrange,int colrange){ void gridlayout::addcontrol(control *_c, int row, int col, int rowrange, int colrange)
{
maxrow = max(maxrow, row + rowrange); maxrow = max(maxrow, row + rowrange);
maxcol = max(maxcol, col + colrange); maxcol = max(maxcol, col + colrange);
savecontrol.push_back( savecontrol.push_back(
{_c,row,col,rowrange,colrange} {_c, row, col, rowrange, colrange});
);
} }
gridlayout::gridlayout(int row,int col):control(0){ gridlayout::gridlayout(int row, int col) : control(0)
{
maxrow = row; maxrow = row;
maxcol = col; maxcol = col;
margin = 10; margin = 10;
} }
void gridlayout::setmargin(int m){ void gridlayout::setmargin(int m)
{
margin = m; margin = m;
} }
void Menu::dispatch(WPARAM wparam){ void Menu::dispatch(WPARAM wparam)
{
auto idx = LOWORD(wparam); auto idx = LOWORD(wparam);
menu_callbacks[idx].callback(); menu_callbacks[idx].callback();
DestroyMenu(hmenu); DestroyMenu(hmenu);
} }
HMENU Menu::load(){ HMENU Menu::load()
{
hmenu = CreatePopupMenu(); hmenu = CreatePopupMenu();
for(int i=0;i<menu_callbacks.size();i++){ for (int i = 0; i < menu_callbacks.size(); i++)
{
AppendMenuW(hmenu, menu_callbacks[i].type, i, menu_callbacks[i].str.c_str()); AppendMenuW(hmenu, menu_callbacks[i].type, i, menu_callbacks[i].str.c_str());
} }
return hmenu; return hmenu;
} }
void Menu::add(const std::wstring& str,std::function<void()> callback){ void Menu::add(const std::wstring &str, std::function<void()> callback)
{
menu_callbacks.push_back({MF_STRING, callback, str}); menu_callbacks.push_back({MF_STRING, callback, str});
} }
void Menu::add_checkable(const std::wstring& str,bool check,std::function<void(bool)> callback){ void Menu::add_checkable(const std::wstring &str, bool check, std::function<void(bool)> callback)
{
menu_callbacks.push_back({(UINT)(MF_STRING | (check ? MF_CHECKED : MF_UNCHECKED)), std::bind(callback, !check), str}); menu_callbacks.push_back({(UINT)(MF_STRING | (check ? MF_CHECKED : MF_UNCHECKED)), std::bind(callback, !check), str});
} }
void Menu::add_sep(){ void Menu::add_sep()
{
menu_callbacks.push_back({MF_SEPARATOR}); menu_callbacks.push_back({MF_SEPARATOR});
} }
FontSelector::FontSelector(HWND hwnd, const Font &font, std::function<void(const Font &)> callback)
FontSelector::FontSelector(HWND hwnd,const std::wstring& init,std::function<void(const std::wstring&)>callback){ {
CHOOSEFONTW cf; CHOOSEFONTW cf;
ZeroMemory(&cf, sizeof(CHOOSEFONTW)); ZeroMemory(&cf, sizeof(CHOOSEFONTW));
LOGFONT lf = font.logfont();
cf.lStructSize = sizeof(CHOOSEFONTW); cf.lStructSize = sizeof(CHOOSEFONTW);
cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS;
LOGFONT lf;
wcscpy_s(lf.lfFaceName,init.c_str());
cf.hwndOwner = hwnd; cf.hwndOwner = hwnd;
cf.lpLogFont = &lf; cf.lpLogFont = &lf;
cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; // | CF_EFFECTS;
if (ChooseFontW(&cf)) if (ChooseFontW(&cf))
{ {
callback(lf.lfFaceName); Font f{lf.lfFaceName, cf.iPointSize / 10.0f, !!(cf.nFontType & BOLD_FONTTYPE), !!(cf.nFontType & ITALIC_FONTTYPE)};
callback(f);
} }
} }

View File

@ -2,10 +2,12 @@
#define LUNA_BASE_CONTROLS_H #define LUNA_BASE_CONTROLS_H
#include "window.h" #include "window.h"
#include <CommCtrl.h> #include <CommCtrl.h>
class Menu{ class Menu
{
public: public:
void dispatch(WPARAM); void dispatch(WPARAM);
struct menuinfos{ struct menuinfos
{
UINT type; UINT type;
std::function<void()> callback; std::function<void()> callback;
std::wstring str; std::wstring str;
@ -19,31 +21,35 @@ public:
}; };
using maybehavemenu = std::optional<Menu>; using maybehavemenu = std::optional<Menu>;
class control:public basewindow{ class control : public basewindow
{
public: public:
mainwindow *parent; mainwindow *parent;
control(mainwindow *); control(mainwindow *);
virtual void dispatch(WPARAM); virtual void dispatch(WPARAM);
virtual void dispatch_2(WPARAM wParam, LPARAM lParam); virtual void dispatch_2(WPARAM wParam, LPARAM lParam);
maybehavemenu menu; maybehavemenu menu;
std::function<maybehavemenu()> on_menu=[]()->maybehavemenu{return {};}; std::function<maybehavemenu()> on_menu = []() -> maybehavemenu
{ return {}; };
}; };
class button:public control{ class button : public control
{
public: public:
button(mainwindow *parent); button(mainwindow *parent);
button(mainwindow *, const std::wstring &); //,int,int,int,int,DWORD=BS_PUSHBUTTON); button(mainwindow *, const std::wstring &); //,int,int,int,int,DWORD=BS_PUSHBUTTON);
void dispatch(WPARAM); void dispatch(WPARAM);
std::function<void()> onclick = []() {}; std::function<void()> onclick = []() {};
}; };
class checkbox:public button{ class checkbox : public button
{
public: public:
checkbox(mainwindow *, const std::wstring &); //,int,int,int,int); checkbox(mainwindow *, const std::wstring &); //,int,int,int,int);
bool ischecked(); bool ischecked();
void setcheck(bool); void setcheck(bool);
}; };
class texteditbase:public control{ class texteditbase : public control
{
public: public:
texteditbase(mainwindow *); texteditbase(mainwindow *);
void dispatch(WPARAM); void dispatch(WPARAM);
@ -52,18 +58,22 @@ public:
void scrolltoend(); void scrolltoend();
void setreadonly(bool); void setreadonly(bool);
}; };
class multilineedit:public texteditbase{ class multilineedit : public texteditbase
{
public: public:
multilineedit(mainwindow *); multilineedit(mainwindow *);
std::wstring getsel(); std::wstring getsel();
}; };
class lineedit:public texteditbase{ class lineedit : public texteditbase
{
public: public:
lineedit(mainwindow *); lineedit(mainwindow *);
}; };
class spinbox:public control{ class spinbox : public control
{
HWND hUpDown; HWND hUpDown;
int minv, maxv; int minv, maxv;
public: public:
void dispatch(WPARAM); void dispatch(WPARAM);
spinbox(mainwindow *, int); spinbox(mainwindow *, int);
@ -74,12 +84,14 @@ class spinbox:public control{
std::function<void(int)> onvaluechange = [&](int) {}; std::function<void(int)> onvaluechange = [&](int) {};
void setgeo(int, int, int, int); void setgeo(int, int, int, int);
}; };
class label:public control{ class label : public control
{
public: public:
label(mainwindow *, const std::wstring &); label(mainwindow *, const std::wstring &);
}; };
class listbox:public control{ class listbox : public control
{
public: public:
listbox(mainwindow *); listbox(mainwindow *);
void dispatch(WPARAM); void dispatch(WPARAM);
@ -95,13 +107,15 @@ public:
LONG_PTR getdata(int); LONG_PTR getdata(int);
int count(); int count();
}; };
class listview:public control{ class listview : public control
{
int headernum = 1; int headernum = 1;
bool addicon; bool addicon;
HIMAGELIST hImageList; HIMAGELIST hImageList;
std::vector<LONG_PTR> assodata; std::vector<LONG_PTR> assodata;
std::map<LONG_PTR, int> remapidx; std::map<LONG_PTR, int> remapidx;
std::mutex lockdataidx; std::mutex lockdataidx;
public: public:
listview(mainwindow *, bool, bool); listview(mainwindow *, bool, bool);
int insertitem(int, const std::wstring &, HICON hicon = NULL); int insertitem(int, const std::wstring &, HICON hicon = NULL);
@ -123,8 +137,10 @@ public:
void dispatch_2(WPARAM wParam, LPARAM lParam); void dispatch_2(WPARAM wParam, LPARAM lParam);
void on_size(int, int); void on_size(int, int);
}; };
class gridlayout:public control{ class gridlayout : public control
struct _c{ {
struct _c
{
control *ctr; control *ctr;
int row, col, rowrange, colrange; int row, col, rowrange, colrange;
}; };
@ -132,6 +148,7 @@ class gridlayout:public control{
int maxrow, maxcol; int maxrow, maxcol;
std::vector<_c> savecontrol; std::vector<_c> savecontrol;
std::map<int, int> fixedwidth, fixedheight; std::map<int, int> fixedwidth, fixedheight;
public: public:
void setgeo(int, int, int, int); void setgeo(int, int, int, int);
void setfixedwidth(int col, int width); void setfixedwidth(int col, int width);
@ -140,9 +157,9 @@ public:
gridlayout(int row = 0, int col = 0); gridlayout(int row = 0, int col = 0);
void setmargin(int m = 10); void setmargin(int m = 10);
}; };
class FontSelector
class FontSelector{ {
public: public:
FontSelector(HWND hwnd,const std::wstring& init,std::function<void(const std::wstring&)>callback); FontSelector(HWND hwnd, const Font &, std::function<void(const Font &)> callback);
}; };
#endif #endif

View File

@ -14,8 +14,7 @@ struct HttpRequest
const wchar_t *referrer = NULL, const wchar_t *referrer = NULL,
DWORD requestFlags = WINHTTP_FLAG_SECURE | WINHTTP_FLAG_ESCAPE_DISABLE, DWORD requestFlags = WINHTTP_FLAG_SECURE | WINHTTP_FLAG_ESCAPE_DISABLE,
const wchar_t *httpVersion = NULL, const wchar_t *httpVersion = NULL,
const wchar_t** acceptTypes = NULL const wchar_t **acceptTypes = NULL);
);
operator bool() { return errorCode == ERROR_SUCCESS; } operator bool() { return errorCode == ERROR_SUCCESS; }
std::wstring response; std::wstring response;
@ -36,11 +35,11 @@ HttpRequest::HttpRequest(
const wchar_t *referrer, const wchar_t *referrer,
DWORD requestFlags, DWORD requestFlags,
const wchar_t *httpVersion, const wchar_t *httpVersion,
const wchar_t** acceptTypes const wchar_t **acceptTypes)
)
{ {
static std::atomic<HINTERNET> internet = NULL; static std::atomic<HINTERNET> internet = NULL;
if (!internet) internet = WinHttpOpen(agentName, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0); if (!internet)
internet = WinHttpOpen(agentName, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, 0);
if (internet) if (internet)
if (InternetHandle connection = WinHttpConnect(internet, serverName, port, 0)) if (InternetHandle connection = WinHttpConnect(internet, serverName, port, 0))
if (InternetHandle request = WinHttpOpenRequest(connection, action, objectName, httpVersion, referrer, acceptTypes, requestFlags)) if (InternetHandle request = WinHttpOpenRequest(connection, action, objectName, httpVersion, referrer, acceptTypes, requestFlags))
@ -58,7 +57,8 @@ HttpRequest::HttpRequest(
{ {
availableSize = 0; availableSize = 0;
WinHttpQueryDataAvailable(request, &availableSize); WinHttpQueryDataAvailable(request, &availableSize);
if (!availableSize) break; if (!availableSize)
break;
std::vector<char> buffer(availableSize); std::vector<char> buffer(availableSize);
WinHttpReadData(request, buffer.data(), availableSize, &downloadedSize); WinHttpReadData(request, buffer.data(), availableSize, &downloadedSize);
data.append(buffer.data(), downloadedSize); data.append(buffer.data(), downloadedSize);
@ -67,8 +67,12 @@ HttpRequest::HttpRequest(
this->connection = std::move(connection); this->connection = std::move(connection);
this->request = std::move(request); this->request = std::move(request);
} }
else errorCode = GetLastError(); else
else errorCode = GetLastError(); errorCode = GetLastError();
else errorCode = GetLastError(); else
else errorCode = GetLastError(); errorCode = GetLastError();
else
errorCode = GetLastError();
else
errorCode = GetLastError();
} }

View File

@ -1,28 +1,35 @@
template <class T> template <class T>
class lockedqueue{ class lockedqueue
{
std::mutex lock; std::mutex lock;
std::queue<T> data; std::queue<T> data;
HANDLE hsema; HANDLE hsema;
public: public:
lockedqueue(){ lockedqueue()
{
hsema = CreateSemaphore(NULL, 0, 65535, NULL); hsema = CreateSemaphore(NULL, 0, 65535, NULL);
} }
~lockedqueue(){ ~lockedqueue()
{
CloseHandle(hsema); CloseHandle(hsema);
} }
void push(T _){ void push(T _)
{
std::lock_guard _l(lock); std::lock_guard _l(lock);
data.push(std::move(_)); data.push(std::move(_));
ReleaseSemaphore(hsema, 1, NULL); ReleaseSemaphore(hsema, 1, NULL);
} }
T pop(){ T pop()
{
WaitForSingleObject(hsema, INFINITE); WaitForSingleObject(hsema, INFINITE);
std::lock_guard _l(lock); std::lock_guard _l(lock);
auto _ = data.front(); auto _ = data.front();
data.pop(); data.pop();
return _; return _;
} }
bool empty(){ bool empty()
{
std::lock_guard _l(lock); std::lock_guard _l(lock);
return data.empty(); return data.empty();
} }

View File

@ -1,5 +1,6 @@
#include "LunaHost.h" #include "LunaHost.h"
int main(){ int main()
{
SetProcessDPIAware(); SetProcessDPIAware();
LunaHost _lunahost; LunaHost _lunahost;
_lunahost.show(); _lunahost.show();

View File

@ -7,7 +7,8 @@
#include "Lang/Lang.h" #include "Lang/Lang.h"
#include "host.h" #include "host.h"
std::optional<std::wstring>SelectFile(HWND hwnd,LPCWSTR lpstrFilter){ std::optional<std::wstring> SelectFile(HWND hwnd, LPCWSTR lpstrFilter)
{
OPENFILENAME ofn; OPENFILENAME ofn;
wchar_t szFileName[MAX_PATH] = {0}; wchar_t szFileName[MAX_PATH] = {0};
@ -23,27 +24,33 @@ std::optional<std::wstring>SelectFile(HWND hwnd,LPCWSTR lpstrFilter){
{ {
return szFileName; return szFileName;
} }
else return {}; else
return {};
} }
typedef std::vector<HMODULE> *(*QtLoadLibrary_t)(std::vector<std::wstring> *dlls); typedef std::vector<HMODULE> *(*QtLoadLibrary_t)(std::vector<std::wstring> *dlls);
typedef std::vector<HMODULE> *(*QtLoadLibraryBatch_t)(std::vector<std::wstring> *dlls); typedef std::vector<HMODULE> *(*QtLoadLibraryBatch_t)(std::vector<std::wstring> *dlls);
typedef void (*QtFreeLibrary_t)(HMODULE hd); typedef void (*QtFreeLibrary_t)(HMODULE hd);
void tryaddqttoenv(std::vector<std::wstring>&collectQtplugs){ void tryaddqttoenv(std::vector<std::wstring> &collectQtplugs)
{
static HMODULE qt5core = 0; static HMODULE qt5core = 0;
if (qt5core == 0) if (qt5core == 0)
{ {
wchar_t env[65535]; wchar_t env[65535];
GetEnvironmentVariableW(L"PATH", env, 65535); GetEnvironmentVariableW(L"PATH", env, 65535);
auto envs = std::wstring(env); auto envs = std::wstring(env);
for(auto&p:collectQtplugs){ for (auto &p : collectQtplugs)
envs+=L";";envs+=std::filesystem::path(p).parent_path(); {
envs += L";";
envs += std::filesystem::path(p).parent_path();
} }
SetEnvironmentVariableW(L"PATH", envs.c_str()); SetEnvironmentVariableW(L"PATH", envs.c_str());
qt5core = LoadLibrary(L"Qt5Core.dll"); qt5core = LoadLibrary(L"Qt5Core.dll");
} }
} }
std::vector<HMODULE>loadqtdllsX(std::vector<std::wstring>&collectQtplugs){ std::vector<HMODULE> loadqtdllsX(std::vector<std::wstring> &collectQtplugs)
if(collectQtplugs.empty())return {}; {
if (collectQtplugs.empty())
return {};
tryaddqttoenv(collectQtplugs); tryaddqttoenv(collectQtplugs);
#if 1 #if 1
HMODULE base = GetModuleHandle(0); HMODULE base = GetModuleHandle(0);
@ -60,31 +67,40 @@ std::vector<HMODULE>loadqtdllsX(std::vector<std::wstring>&collectQtplugs){
delete modules; delete modules;
return _; return _;
} }
HMODULE loadqtdllsX(const std::wstring&collectQtplugs){ HMODULE loadqtdllsX(const std::wstring &collectQtplugs)
{
std::vector<std::wstring> _{collectQtplugs}; std::vector<std::wstring> _{collectQtplugs};
return loadqtdllsX(_)[0]; return loadqtdllsX(_)[0];
} }
void Pluginmanager::loadqtdlls(std::vector<std::wstring>&collectQtplugs){ void Pluginmanager::loadqtdlls(std::vector<std::wstring> &collectQtplugs)
{
auto modules = loadqtdllsX(collectQtplugs); auto modules = loadqtdllsX(collectQtplugs);
for(int i=0;i<collectQtplugs.size();i++){ for (int i = 0; i < collectQtplugs.size(); i++)
{
OnNewSentenceS[collectQtplugs[i]] = {collectQtplugs[i], this, true, modules[i]}; OnNewSentenceS[collectQtplugs[i]] = {collectQtplugs[i], this, true, modules[i]};
} }
} }
Pluginmanager::Pluginmanager(LunaHost* _host):host(_host),configs(_host->configs){ Pluginmanager::Pluginmanager(LunaHost *_host) : host(_host), configs(_host->configs)
try { {
try
{
std::scoped_lock lock(OnNewSentenceSLock); std::scoped_lock lock(OnNewSentenceSLock);
std::vector<std::wstring> collectQtplugs; std::vector<std::wstring> collectQtplugs;
for (auto i=0;i<count();i++) { for (auto i = 0; i < count(); i++)
{
auto plg = get(i); auto plg = get(i);
bool isqt = plg.isQt; bool isqt = plg.isQt;
auto path = plg.wpath(); auto path = plg.wpath();
OnNewSentenceS[path] = {}; OnNewSentenceS[path] = {};
if(isqt){ if (isqt)
if(plg.enable==false)continue; {
if (plg.enable == false)
continue;
collectQtplugs.push_back((path)); collectQtplugs.push_back((path));
} }
else{ else
{
auto base = LoadLibraryW(path.c_str()); auto base = LoadLibraryW(path.c_str());
OnNewSentenceS[path] = {path, this, false, base}; OnNewSentenceS[path] = {path, this, false, base};
} }
@ -92,29 +108,35 @@ Pluginmanager::Pluginmanager(LunaHost* _host):host(_host),configs(_host->configs
loadqtdlls(collectQtplugs); loadqtdlls(collectQtplugs);
OnNewSentenceS[L"InternalClipBoard"] = {L"", this, false, GetModuleHandle(0)}; // 内部链接的剪贴板插件 OnNewSentenceS[L"InternalClipBoard"] = {L"", this, false, GetModuleHandle(0)}; // 内部链接的剪贴板插件
}
catch (const std::exception &ex)
} catch (const std::exception& ex) { {
std::wcerr << "Error: " << ex.what() << std::endl; std::wcerr << "Error: " << ex.what() << std::endl;
} }
} }
bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){ bool Pluginmanager::dispatch(TextThread &thread, std::wstring &sentence)
{
auto sentenceInfo = GetSentenceInfo(thread).data(); auto sentenceInfo = GetSentenceInfo(thread).data();
wchar_t *sentenceBuffer = (wchar_t *)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, (sentence.size() + 1) * sizeof(wchar_t)); wchar_t *sentenceBuffer = (wchar_t *)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, (sentence.size() + 1) * sizeof(wchar_t));
wcscpy_s(sentenceBuffer, sentence.size() + 1, sentence.c_str()); wcscpy_s(sentenceBuffer, sentence.size() + 1, sentence.c_str());
concurrency::reader_writer_lock::scoped_lock_read readLock(OnNewSentenceSLock); concurrency::reader_writer_lock::scoped_lock_read readLock(OnNewSentenceSLock);
for(int i=0;i<count()+1;i++){ for (int i = 0; i < count() + 1; i++)
{
std::wstring path; std::wstring path;
if(i==count())path=L"InternalClipBoard"; if (i == count())
else { path = L"InternalClipBoard";
if(getenable(i)==false)continue; else
{
if (getenable(i) == false)
continue;
path = getname(i); path = getname(i);
} }
auto funptr = OnNewSentenceS[path].OnNewSentence; auto funptr = OnNewSentenceS[path].OnNewSentence;
if(funptr==0)continue; if (funptr == 0)
continue;
if (!*(sentenceBuffer = funptr(sentenceBuffer, sentenceInfo))) if (!*(sentenceBuffer = funptr(sentenceBuffer, sentenceInfo)))
break; break;
} }
@ -124,40 +146,51 @@ bool Pluginmanager::dispatch(TextThread& thread, std::wstring& sentence){
return !sentence.empty(); return !sentence.empty();
} }
void Pluginmanager::add(const pluginitem& item){ void Pluginmanager::add(const pluginitem &item)
{
configs->configs["plugins"].push_back(item.dump()); configs->configs["plugins"].push_back(item.dump());
} }
int Pluginmanager::count(){ int Pluginmanager::count()
{
return configs->configs["plugins"].size(); return configs->configs["plugins"].size();
} }
pluginitem Pluginmanager::get(int i){ pluginitem Pluginmanager::get(int i)
{
return pluginitem{configs->configs["plugins"][i]}; return pluginitem{configs->configs["plugins"][i]};
} }
void Pluginmanager::set(int i,const pluginitem& item){ void Pluginmanager::set(int i, const pluginitem &item)
{
configs->configs["plugins"][i] = item.dump(); configs->configs["plugins"][i] = item.dump();
} }
pluginitem::pluginitem(const nlohmann::json& js){ pluginitem::pluginitem(const nlohmann::json &js)
{
path = js["path"]; path = js["path"];
isQt = safequeryjson(js, "isQt", false); isQt = safequeryjson(js, "isQt", false);
isref = safequeryjson(js, "isref", false); isref = safequeryjson(js, "isref", false);
enable = safequeryjson(js, "enable", true); enable = safequeryjson(js, "enable", true);
vissetting = safequeryjson(js, "vissetting", true); vissetting = safequeryjson(js, "vissetting", true);
} }
std::wstring pluginitem::wpath(){ std::wstring pluginitem::wpath()
{
auto wp = StringToWideString(path); auto wp = StringToWideString(path);
if(isref)return std::filesystem::current_path()/wp; if (isref)
else return wp; return std::filesystem::current_path() / wp;
else
return wp;
} }
std::pair<std::wstring,bool> castabs2ref(const std::wstring&p){ std::pair<std::wstring, bool> castabs2ref(const std::wstring &p)
{
auto curr = std::filesystem::current_path().wstring(); auto curr = std::filesystem::current_path().wstring();
if(startWith(p,curr)){ if (startWith(p, curr))
{
return {p.substr(curr.size() + 1), true}; return {p.substr(curr.size() + 1), true};
} }
return {p, false}; return {p, false};
} }
pluginitem::pluginitem(const std::wstring& pabs,bool _isQt){ pluginitem::pluginitem(const std::wstring &pabs, bool _isQt)
{
isQt = _isQt; isQt = _isQt;
auto [p, _isref] = castabs2ref(pabs); auto [p, _isref] = castabs2ref(pabs);
isref = _isref; isref = _isref;
@ -165,47 +198,58 @@ pluginitem::pluginitem(const std::wstring& pabs,bool _isQt){
enable = true; enable = true;
vissetting = true; vissetting = true;
} }
nlohmann::json pluginitem::dump() const{ nlohmann::json pluginitem::dump() const
{
return { return {
{"path", path}, {"path", path},
{"isQt", isQt}, {"isQt", isQt},
{"isref", isref}, {"isref", isref},
{"enable", enable}, {"enable", enable},
{"vissetting",vissetting} {"vissetting", vissetting}};
};
} }
bool Pluginmanager::getvisible_setable(int idx){ bool Pluginmanager::getvisible_setable(int idx)
{
return OnNewSentenceS[getname(idx)].VisSetting; return OnNewSentenceS[getname(idx)].VisSetting;
} }
bool Pluginmanager::getvisible(int idx){ bool Pluginmanager::getvisible(int idx)
{
return get(idx).vissetting; return get(idx).vissetting;
} }
void Pluginmanager::setvisible(int idx,bool vis){ void Pluginmanager::setvisible(int idx, bool vis)
{
auto item = get(idx); auto item = get(idx);
item.vissetting = vis; item.vissetting = vis;
set(idx, item); set(idx, item);
OnNewSentenceS[getname(idx)].VisSetting(vis); OnNewSentenceS[getname(idx)].VisSetting(vis);
} }
bool Pluginmanager::getenable(int idx){ bool Pluginmanager::getenable(int idx)
{
return get(idx).enable; return get(idx).enable;
} }
void Pluginmanager::setenable(int idx,bool en){ void Pluginmanager::setenable(int idx, bool en)
{
auto item = get(idx); auto item = get(idx);
item.enable = en; item.enable = en;
set(idx, item); set(idx, item);
} }
std::wstring Pluginmanager::getname(int idx){ std::wstring Pluginmanager::getname(int idx)
{
return get(idx).wpath(); return get(idx).wpath();
} }
bool Pluginmanager::checkisdump(const std::wstring& dll){ bool Pluginmanager::checkisdump(const std::wstring &dll)
for(auto& p:OnNewSentenceS){ {
if(p.first==dll)return true; for (auto &p : OnNewSentenceS)
{
if (p.first == dll)
return true;
} }
return false; return false;
} }
void Pluginmanager::unload(const std::wstring& wss){ void Pluginmanager::unload(const std::wstring &wss)
{
auto hm = OnNewSentenceS[wss].hmodule; auto hm = OnNewSentenceS[wss].hmodule;
if(OnNewSentenceS[wss].isQt && hm){ if (OnNewSentenceS[wss].isQt && hm)
{
((QtFreeLibrary_t)GetProcAddress(GetModuleHandle(0), "QtFreeLibrary"))(hm); ((QtFreeLibrary_t)GetProcAddress(GetModuleHandle(0), "QtFreeLibrary"))(hm);
} }
else else
@ -213,27 +257,31 @@ void Pluginmanager::unload(const std::wstring& wss){
OnNewSentenceS[wss].clear(); OnNewSentenceS[wss].clear();
} }
void plugindata::clear(){ void plugindata::clear()
{
hmodule = 0; hmodule = 0;
OnNewSentence = 0; OnNewSentence = 0;
VisSetting = 0; VisSetting = 0;
} }
void Pluginmanager::remove(const std::wstring& wss){ void Pluginmanager::remove(const std::wstring &wss)
{
unload(wss); unload(wss);
auto s = WideStringToString(wss); auto s = WideStringToString(wss);
auto &plgs = configs->configs["plugins"]; auto &plgs = configs->configs["plugins"];
auto it=std::remove_if(plgs.begin(),plgs.end(),[&](auto&t){ auto it = std::remove_if(plgs.begin(), plgs.end(), [&](auto &t)
{
std::string p=t["path"]; std::string p=t["path"];
return p==s; return p==s; });
});
plgs.erase(it, plgs.end()); plgs.erase(it, plgs.end());
OnNewSentenceS.erase(wss); OnNewSentenceS.erase(wss);
} }
std::optional<std::wstring>Pluginmanager::selectpluginfile(){ std::optional<std::wstring> Pluginmanager::selectpluginfile()
{
return SelectFile(0, L"Plugin Files\0*.dll;*.xdll\0"); return SelectFile(0, L"Plugin Files\0*.dll;*.xdll\0");
} }
void Pluginmanager::swaprank(int a,int b){ void Pluginmanager::swaprank(int a, int b)
{
auto &plgs = configs->configs["plugins"]; auto &plgs = configs->configs["plugins"];
auto _b = plgs[b]; auto _b = plgs[b];
plgs[b] = plgs[a]; plgs[b] = plgs[a];
@ -257,44 +305,51 @@ DWORD Rva2Offset(DWORD rva, PIMAGE_SECTION_HEADER psh, PIMAGE_NT_HEADERS pnt)
} }
pSeh++; pSeh++;
} }
if(pSeh->VirtualAddress==0||pSeh->PointerToRawData==0)return -1; if (pSeh->VirtualAddress == 0 || pSeh->PointerToRawData == 0)
return -1;
return (rva - pSeh->VirtualAddress + pSeh->PointerToRawData); return (rva - pSeh->VirtualAddress + pSeh->PointerToRawData);
} }
std::set<std::string> getimporttable(const std::wstring&pe){ std::set<std::string> getimporttable(const std::wstring &pe)
{
AutoHandle handle = CreateFile(pe.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); AutoHandle handle = CreateFile(pe.c_str(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(!handle)return {}; if (!handle)
return {};
DWORD byteread, size = GetFileSize(handle, NULL); DWORD byteread, size = GetFileSize(handle, NULL);
PVOID virtualpointer = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE); PVOID virtualpointer = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE);
if(!virtualpointer) return {}; if (!virtualpointer)
return {};
ReadFile(handle, virtualpointer, size, &byteread, NULL); ReadFile(handle, virtualpointer, size, &byteread, NULL);
struct __{ struct __
PVOID _ptr;DWORD size; {
PVOID _ptr;
DWORD size;
__(PVOID ptr, DWORD sz) : _ptr(ptr), size(sz) {} __(PVOID ptr, DWORD sz) : _ptr(ptr), size(sz) {}
~__(){ ~__()
{
VirtualFree(_ptr, size, MEM_DECOMMIT); VirtualFree(_ptr, size, MEM_DECOMMIT);
} }
} _(virtualpointer, size); } _(virtualpointer, size);
if (PIMAGE_DOS_HEADER(virtualpointer)->e_magic != 0x5a4d) if (PIMAGE_DOS_HEADER(virtualpointer)->e_magic != 0x5a4d)
return {}; return {};
PIMAGE_NT_HEADERS ntheaders = (PIMAGE_NT_HEADERS)(PCHAR(virtualpointer) + PIMAGE_DOS_HEADER(virtualpointer)->e_lfanew); PIMAGE_NT_HEADERS ntheaders = (PIMAGE_NT_HEADERS)(PCHAR(virtualpointer) + PIMAGE_DOS_HEADER(virtualpointer)->e_lfanew);
auto magic = ntheaders->OptionalHeader.Magic; auto magic = ntheaders->OptionalHeader.Magic;
if(x64 && (magic!=IMAGE_NT_OPTIONAL_HDR64_MAGIC))return {}; if (x64 && (magic != IMAGE_NT_OPTIONAL_HDR64_MAGIC))
if((!x64)&&(magic!=IMAGE_NT_OPTIONAL_HDR32_MAGIC))return {}; return {};
if ((!x64) && (magic != IMAGE_NT_OPTIONAL_HDR32_MAGIC))
return {};
PIMAGE_SECTION_HEADER pSech = IMAGE_FIRST_SECTION(ntheaders); // Pointer to first section header PIMAGE_SECTION_HEADER pSech = IMAGE_FIRST_SECTION(ntheaders); // Pointer to first section header
PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor; // Pointer to import descriptor PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor; // Pointer to import descriptor
if (ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0) /*if size of the table is 0 - Import Table does not exist */ if (ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0) /*if size of the table is 0 - Import Table does not exist */
return {}; return {};
std::set<std::string> ret; std::set<std::string> ret;
pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)virtualpointer + \ pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD_PTR)virtualpointer +
Rva2Offset(ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, pSech, ntheaders)); Rva2Offset(ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress, pSech, ntheaders));
while (pImportDescriptor->Name != NULL) while (pImportDescriptor->Name != NULL)
@ -309,7 +364,6 @@ std::set<std::string> getimporttable(const std::wstring&pe){
pImportDescriptor++; // advance to next IMAGE_IMPORT_DESCRIPTOR pImportDescriptor++; // advance to next IMAGE_IMPORT_DESCRIPTOR
} }
return ret; return ret;
} }
bool qtchecker(const std::set<std::string> &dll) bool qtchecker(const std::set<std::string> &dll)
{ {
@ -318,20 +372,26 @@ bool qtchecker(const std::set<std::string>& dll)
return true; return true;
return false; return false;
} }
addpluginresult Pluginmanager::load(const std::wstring& p,bool*isqt){ addpluginresult Pluginmanager::load(const std::wstring &p, bool *isqt)
{
auto importtable = getimporttable(p); auto importtable = getimporttable(p);
if(importtable.empty())return addpluginresult::invaliddll; if (importtable.empty())
return addpluginresult::invaliddll;
auto isQt = qtchecker(importtable); auto isQt = qtchecker(importtable);
if(isqt)*isqt=isQt; if (isqt)
*isqt = isQt;
HMODULE base; HMODULE base;
if(isQt){ if (isQt)
{
base = loadqtdllsX(p); base = loadqtdllsX(p);
} }
else{ else
{
base = LoadLibraryW(p.c_str()); base = LoadLibraryW(p.c_str());
} }
if(base==0)return addpluginresult::invaliddll; if (base == 0)
return addpluginresult::invaliddll;
std::scoped_lock lock(OnNewSentenceSLock); std::scoped_lock lock(OnNewSentenceSLock);
@ -340,10 +400,12 @@ addpluginresult Pluginmanager::load(const std::wstring& p,bool*isqt){
return addpluginresult::isnotaplugins; return addpluginresult::isnotaplugins;
return addpluginresult::success; return addpluginresult::success;
} }
bool plugindata::valid(){ bool plugindata::valid()
{
return OnNewSentence; return OnNewSentence;
} }
plugindata::plugindata(const std::wstring& p,Pluginmanager* manager,bool _isQt,HMODULE hm){ plugindata::plugindata(const std::wstring &p, Pluginmanager *manager, bool _isQt, HMODULE hm)
{
hmodule = hm; hmodule = hm;
isQt = _isQt; isQt = _isQt;
OnNewSentence = (OnNewSentence_t)GetProcAddress(hm, "OnNewSentence"); OnNewSentence = (OnNewSentence_t)GetProcAddress(hm, "OnNewSentence");
@ -357,47 +419,56 @@ plugindata::plugindata(const std::wstring& p,Pluginmanager* manager,bool _isQt,H
VisSetting(vis); VisSetting(vis);
} }
} }
void plugindata::initstatus(const pluginitem& plg){ void plugindata::initstatus(const pluginitem &plg)
{
if (plg.vissetting && VisSetting) if (plg.vissetting && VisSetting)
VisSetting(true); VisSetting(true);
} }
std::optional<pluginitem> Pluginmanager::get(const std::wstring&p){ std::optional<pluginitem> Pluginmanager::get(const std::wstring &p)
{
for (int i = 0; i < count(); i++) for (int i = 0; i < count(); i++)
{ {
if(getname(i)==p){ if (getname(i) == p)
{
return get(i); return get(i);
} }
} }
return {}; return {};
} }
addpluginresult Pluginmanager::addplugin(const std::wstring& p){ addpluginresult Pluginmanager::addplugin(const std::wstring &p)
if(checkisdump(p))return addpluginresult::dumplicate; {
if (checkisdump(p))
return addpluginresult::dumplicate;
bool isQt; bool isQt;
auto ret = load(p, &isQt); auto ret = load(p, &isQt);
if(ret==addpluginresult::success){ if (ret == addpluginresult::success)
{
add({p, isQt}); add({p, isQt});
} }
return ret; return ret;
} }
std::array<InfoForExtension, 20> Pluginmanager::GetSentenceInfo(TextThread &thread) std::array<InfoForExtension, 20> Pluginmanager::GetSentenceInfo(TextThread &thread)
{ {
void (*AddText)(int64_t, const wchar_t *) = [](int64_t number, const wchar_t *text) void (*AddText)(int64_t, const wchar_t *) = [](int64_t number, const wchar_t *text)
{ {
if (TextThread* thread = Host::GetThread(number)) thread->Push(text); if (TextThread *thread = Host::GetThread(number))
thread->Push(text);
}; };
void (*AddSentence)(int64_t, const wchar_t *) = [](int64_t number, const wchar_t *sentence) void (*AddSentence)(int64_t, const wchar_t *) = [](int64_t number, const wchar_t *sentence)
{ {
if (TextThread* thread = Host::GetThread(number)) thread->AddSentence(sentence);; if (TextThread *thread = Host::GetThread(number))
thread->AddSentence(sentence);
;
}; };
static DWORD SelectedProcessId; static DWORD SelectedProcessId;
auto currthread = (TextThread *)host->currentselect; auto currthread = (TextThread *)host->currentselect;
SelectedProcessId = (currthread != 0) ? currthread->tp.processId : 0; SelectedProcessId = (currthread != 0) ? currthread->tp.processId : 0;
DWORD (*GetSelectedProcessId)() = [] { return SelectedProcessId; }; DWORD (*GetSelectedProcessId)
() = []
{ return SelectedProcessId; };
return return {{
{ {
{"HostHWND", (int64_t)host->winId}, {"HostHWND", (int64_t)host->winId},
{"toclipboard", host->check_toclipboard}, {"toclipboard", host->check_toclipboard},
{"current select", &thread == currthread}, {"current select", &thread == currthread},

View File

@ -5,13 +5,15 @@
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
class LunaHost; class LunaHost;
class confighelper; class confighelper;
enum class addpluginresult{ enum class addpluginresult
{
success, success,
invaliddll, invaliddll,
isnotaplugins, isnotaplugins,
dumplicate dumplicate
}; };
struct pluginitem{ struct pluginitem
{
std::string path; std::string path;
bool isQt; bool isQt;
bool isref; bool isref;
@ -23,7 +25,8 @@ struct pluginitem{
nlohmann::json dump() const; nlohmann::json dump() const;
}; };
class Pluginmanager; class Pluginmanager;
struct plugindata{ struct plugindata
{
typedef wchar_t *(*OnNewSentence_t)(wchar_t *, const InfoForExtension *); typedef wchar_t *(*OnNewSentence_t)(wchar_t *, const InfoForExtension *);
typedef void (*VisSetting_t)(bool); typedef void (*VisSetting_t)(bool);
std::wstring refpath; std::wstring refpath;
@ -37,7 +40,8 @@ struct plugindata{
bool valid(); bool valid();
void initstatus(const pluginitem &); void initstatus(const pluginitem &);
}; };
class Pluginmanager{ class Pluginmanager
{
std::unordered_map<std::wstring, plugindata> OnNewSentenceS; std::unordered_map<std::wstring, plugindata> OnNewSentenceS;
concurrency::reader_writer_lock OnNewSentenceSLock; concurrency::reader_writer_lock OnNewSentenceSLock;
bool checkisdump(const std::wstring &); bool checkisdump(const std::wstring &);
@ -45,6 +49,7 @@ class Pluginmanager{
LunaHost *host; LunaHost *host;
std::array<InfoForExtension, 20> GetSentenceInfo(TextThread &thread); std::array<InfoForExtension, 20> GetSentenceInfo(TextThread &thread);
void loadqtdlls(std::vector<std::wstring> &collectQtplugs); void loadqtdlls(std::vector<std::wstring> &collectQtplugs);
public: public:
Pluginmanager(LunaHost *); Pluginmanager(LunaHost *);
bool dispatch(TextThread &, std::wstring &sentence); bool dispatch(TextThread &, std::wstring &sentence);

View File

@ -20,24 +20,26 @@ std::unordered_map<std::wstring,std::vector<int>> getprocesslist()
{ {
do do
{ {
auto PROCESS_INJECT_ACCESS = ( auto PROCESS_INJECT_ACCESS = (PROCESS_CREATE_THREAD |
PROCESS_CREATE_THREAD |
PROCESS_QUERY_INFORMATION | PROCESS_QUERY_INFORMATION |
PROCESS_VM_OPERATION | PROCESS_VM_OPERATION |
PROCESS_VM_WRITE | PROCESS_VM_WRITE |
PROCESS_VM_READ); PROCESS_VM_READ);
if(pe32.th32ProcessID==currpid)continue; if (pe32.th32ProcessID == currpid)
continue;
AutoHandle<> handle = OpenProcess(PROCESS_INJECT_ACCESS, 0, pe32.th32ProcessID); AutoHandle<> handle = OpenProcess(PROCESS_INJECT_ACCESS, 0, pe32.th32ProcessID);
if (handle == 0)continue; if (handle == 0)
continue;
DWORD sz = 65535; DWORD sz = 65535;
QueryFullProcessImageNameW(handle, 0, buff, &sz); QueryFullProcessImageNameW(handle, 0, buff, &sz);
auto buffs = std::wstring(buff); auto buffs = std::wstring(buff);
auto str = stolower(buffs); auto str = stolower(buffs);
if(str.find(L":\\windows\\")!=str.npos || str.find(L"\\microsoft")!=str.npos|| str.find(L"\\windowsapps")!=str.npos)continue; if (str.find(L":\\windows\\") != str.npos || str.find(L"\\microsoft") != str.npos || str.find(L"\\windowsapps") != str.npos)
continue;
if (exe_pid.find(buffs) == exe_pid.end())
if(exe_pid.find(buffs)==exe_pid.end()){ {
exe_pid.insert({buffs, {}}); exe_pid.insert({buffs, {}});
} }
exe_pid[buffs].push_back(pe32.th32ProcessID); exe_pid[buffs].push_back(pe32.th32ProcessID);
@ -46,47 +48,61 @@ std::unordered_map<std::wstring,std::vector<int>> getprocesslist()
return exe_pid; return exe_pid;
} }
void processlistwindow::PopulateProcessList(listview* _listbox,std::unordered_map<std::wstring,std::vector<int>>&exe_pid){ void processlistwindow::PopulateProcessList(listview *_listbox, std::unordered_map<std::wstring, std::vector<int>> &exe_pid)
{
_listbox->clear(); _listbox->clear();
for(auto& exe:exe_pid){ for (auto &exe : exe_pid)
{
auto hicon = GetExeIcon(exe.first); auto hicon = GetExeIcon(exe.first);
_listbox->additem(exe.first, hicon); _listbox->additem(exe.first, hicon);
DestroyIcon(hicon); DestroyIcon(hicon);
} }
} }
processlistwindow::processlistwindow(mainwindow* p):mainwindow(p){ processlistwindow::processlistwindow(mainwindow *p) : mainwindow(p)
{
g_hEdit = new lineedit(this); g_hEdit = new lineedit(this);
g_hButton = new button(this, BtnAttach); g_hButton = new button(this, BtnAttach);
g_refreshbutton = new button(this, BtnRefresh); g_refreshbutton = new button(this, BtnRefresh);
g_hButton->onclick=[&](){ g_hButton->onclick = [&]()
{
auto str = g_hEdit->text(); auto str = g_hEdit->text();
if(str.size()){ if (str.size())
{
close(); close();
for(auto _s:strSplit(str,L",")){ for (auto _s : strSplit(str, L","))
{
DWORD pid = 0; DWORD pid = 0;
try{ try
{
pid = std::stoi(_s); pid = std::stoi(_s);
}catch(std::exception&){} }
catch (std::exception &)
{
}
if (pid) if (pid)
Host::InjectProcess(pid); Host::InjectProcess(pid);
} }
} }
}; };
g_refreshbutton->onclick=[&](){ g_refreshbutton->onclick = [&]()
{
g_exe_pid = getprocesslist(); g_exe_pid = getprocesslist();
PopulateProcessList(g_hListBox, g_exe_pid); PopulateProcessList(g_hListBox, g_exe_pid);
}; };
g_hListBox = new listview(this, true, true); g_hListBox = new listview(this, true, true);
g_hListBox->setheader({L""}); g_hListBox->setheader({L""});
g_hListBox->oncurrentchange=[&](int idx){ g_hListBox->oncurrentchange = [&](int idx)
{
auto pids = g_exe_pid[g_hListBox->text(idx)]; auto pids = g_exe_pid[g_hListBox->text(idx)];
std::wstring _; std::wstring _;
bool _1 = false; bool _1 = false;
for(auto &p:pids){ for (auto &p : pids)
if(_1)_+=L","; {
if (_1)
_ += L",";
_ += std::to_wstring(p); _ += std::to_wstring(p);
_1 = true; _1 = true;
} }
@ -102,7 +118,8 @@ processlistwindow::processlistwindow(mainwindow* p):mainwindow(p){
setlayout(mainlayout); setlayout(mainlayout);
setcentral(800, 400); setcentral(800, 400);
} }
void processlistwindow::on_show(){ void processlistwindow::on_show()
{
g_hEdit->settext(L""); g_hEdit->settext(L"");
g_exe_pid = getprocesslist(); g_exe_pid = getprocesslist();
PopulateProcessList(g_hListBox, g_exe_pid); PopulateProcessList(g_hListBox, g_exe_pid);

View File

@ -2,55 +2,64 @@
#include "controls.h" #include "controls.h"
#include "Lang/Lang.h" #include "Lang/Lang.h"
#include <shellapi.h> #include <shellapi.h>
HICON GetExeIcon(const std::wstring& filePath) { HICON GetExeIcon(const std::wstring &filePath)
{
SHFILEINFO fileInfo; SHFILEINFO fileInfo;
HICON hIcon = NULL; HICON hIcon = NULL;
if (SHGetFileInfo(filePath.c_str(), 0, &fileInfo, sizeof(fileInfo), SHGFI_ICON | SHGFI_LARGEICON)) { if (SHGetFileInfo(filePath.c_str(), 0, &fileInfo, sizeof(fileInfo), SHGFI_ICON | SHGFI_LARGEICON))
{
hIcon = fileInfo.hIcon; hIcon = fileInfo.hIcon;
} }
return hIcon; return hIcon;
} }
void mainwindow::visfont(){ void mainwindow::visfont()
if(hfont==0)hfont=parent->hfont; {
if(hfont){ if (hfont == 0)
for(auto ctr:controls){ hfont = parent->hfont;
if (hfont)
{
for (auto ctr : controls)
{
SendMessage(ctr->winId, WM_SETFONT, (LPARAM)hfont, TRUE); SendMessage(ctr->winId, WM_SETFONT, (LPARAM)hfont, TRUE);
} }
} }
} }
void mainwindow::setfont(int sz,LPCWSTR fn){ void mainwindow::setfont(const Font &font)
if(fn==0)fn=DefaultFont; {
hfont=CreateFont(sz, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, hfont = font.hfont();
DEFAULT_CHARSET , OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_DONTCARE, fn);
SendMessage(winId, WM_SETFONT, (WPARAM)hfont, TRUE); SendMessage(winId, WM_SETFONT, (WPARAM)hfont, TRUE);
visfont(); visfont();
for(auto child:childrens){ for (auto child : childrens)
child->setfont(sz,fn); {
child->setfont(font);
} }
} }
std::wstring basewindow::text(){ std::wstring basewindow::text()
{
int textLength = GetWindowTextLength(winId); int textLength = GetWindowTextLength(winId);
std::vector<wchar_t> buffer(textLength + 1); std::vector<wchar_t> buffer(textLength + 1);
GetWindowText(winId, buffer.data(), buffer.size()); GetWindowText(winId, buffer.data(), buffer.size());
return buffer.data(); return buffer.data();
} }
void basewindow::settext(const std::wstring& text){ void basewindow::settext(const std::wstring &text)
{
SetWindowText(winId, text.c_str()); SetWindowText(winId, text.c_str());
} }
void basewindow::setgeo(int x,int y,int w,int h){ void basewindow::setgeo(int x, int y, int w, int h)
{
MoveWindow(winId, x, y, w, h, TRUE); MoveWindow(winId, x, y, w, h, TRUE);
on_size(w, h); on_size(w, h);
} }
RECT basewindow::getgeo(){ RECT basewindow::getgeo()
{
RECT rect; RECT rect;
GetWindowRect(winId, &rect); GetWindowRect(winId, &rect);
return rect; return rect;
} }
LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam){ LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) switch (message)
{ {
case WM_SHOWWINDOW: case WM_SHOWWINDOW:
@ -73,15 +82,19 @@ LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam){
{ {
if (pnmhdr->hwndFrom == ctl->winId) if (pnmhdr->hwndFrom == ctl->winId)
{ {
ctl->dispatch_2(wParam,lParam);break; ctl->dispatch_2(wParam, lParam);
break;
} }
} }
} }
case WM_COMMAND: case WM_COMMAND:
{ {
if(lParam==0){ if (lParam == 0)
for(auto ctl:controls){ {
if(lastcontexthwnd==ctl->winId){ for (auto ctl : controls)
{
if (lastcontexthwnd == ctl->winId)
{
if (ctl->menu) if (ctl->menu)
ctl->menu.value().dispatch(wParam); ctl->menu.value().dispatch(wParam);
break; break;
@ -89,21 +102,28 @@ LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam){
} }
} }
else else
for(auto ctl:controls){ for (auto ctl : controls)
if((HWND)lParam==ctl->winId){ {
ctl->dispatch(wParam);break; if ((HWND)lParam == ctl->winId)
{
ctl->dispatch(wParam);
break;
} }
} }
break; break;
} }
case WM_CONTEXTMENU: case WM_CONTEXTMENU:
{ {
bool succ=false;lastcontexthwnd=0; bool succ = false;
for(auto ctl:controls){ lastcontexthwnd = 0;
if((HWND)wParam==ctl->winId){ for (auto ctl : controls)
{
if ((HWND)wParam == ctl->winId)
{
auto hm = ctl->on_menu(); auto hm = ctl->on_menu();
ctl->menu = hm; ctl->menu = hm;
if(hm){ if (hm)
{
int xPos = LOWORD(lParam); int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam); int yPos = HIWORD(lParam);
TrackPopupMenu(hm.value().load(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON, TrackPopupMenu(hm.value().load(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
@ -114,14 +134,17 @@ LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam){
break; break;
} }
} }
if(succ==false)return DefWindowProc(winId, message, wParam, lParam); if (succ == false)
return DefWindowProc(winId, message, wParam, lParam);
break; break;
} }
case WM_CLOSE: case WM_CLOSE:
{ {
on_close(); on_close();
if(parent==0)PostQuitMessage(0); if (parent == 0)
else ShowWindow(winId,SW_HIDE); PostQuitMessage(0);
else
ShowWindow(winId, SW_HIDE);
break; break;
} }
default: default:
@ -130,29 +153,35 @@ LRESULT mainwindow::wndproc(UINT message, WPARAM wParam, LPARAM lParam){
return 0; return 0;
} }
std::pair<int,int>mainwindow::calculateXY(int w,int h){ std::pair<int, int> mainwindow::calculateXY(int w, int h)
{
int cx, cy; int cx, cy;
if(parent==0){ if (parent == 0)
{
int screenWidth = GetSystemMetrics(SM_CXSCREEN); int screenWidth = GetSystemMetrics(SM_CXSCREEN);
int screenHeight = GetSystemMetrics(SM_CYSCREEN); int screenHeight = GetSystemMetrics(SM_CYSCREEN);
cx = screenWidth / 2; cx = screenWidth / 2;
cy = screenHeight / 2; cy = screenHeight / 2;
} }
else{ else
{
auto rect = parent->getgeo(); auto rect = parent->getgeo();
cx = (rect.left + rect.right) / 2; cx = (rect.left + rect.right) / 2;
cy = (rect.top + rect.bottom) / 2; cy = (rect.top + rect.bottom) / 2;
} }
return {cx - w / 2, cy - h / 2}; return {cx - w / 2, cy - h / 2};
} }
void mainwindow::setcentral(int w,int h){ void mainwindow::setcentral(int w, int h)
{
auto [x, y] = calculateXY(w, h); auto [x, y] = calculateXY(w, h);
setgeo(x, y, w, h); setgeo(x, y, w, h);
} }
void mainwindow::setlayout(control* _l){ void mainwindow::setlayout(control *_l)
{
layout = _l; layout = _l;
} }
mainwindow::mainwindow(mainwindow* _parent){ mainwindow::mainwindow(mainwindow *_parent)
{
layout = 0; layout = 0;
const wchar_t CLASS_NAME[] = L"LunaHostWindow"; const wchar_t CLASS_NAME[] = L"LunaHostWindow";
@ -160,7 +189,8 @@ mainwindow::mainwindow(mainwindow* _parent){
wc.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) wc.lpfnWndProc = [](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
mainwindow *_window = reinterpret_cast<mainwindow *>(GetWindowLongPtrW(hWnd, GWLP_USERDATA)); mainwindow *_window = reinterpret_cast<mainwindow *>(GetWindowLongPtrW(hWnd, GWLP_USERDATA));
if ((!_window)||(_window->winId!=hWnd)) return DefWindowProc(hWnd, message, wParam, lParam); if ((!_window) || (_window->winId != hWnd))
return DefWindowProc(hWnd, message, wParam, lParam);
return _window->wndproc(message, wParam, lParam); return _window->wndproc(message, wParam, lParam);
}; };
wc.hInstance = GetModuleHandle(0); wc.hInstance = GetModuleHandle(0);
@ -172,22 +202,24 @@ mainwindow::mainwindow(mainwindow* _parent){
HWND hWnd = CreateWindowEx( HWND hWnd = CreateWindowEx(
WS_EX_CLIENTEDGE, CLASS_NAME, CLASS_NAME, WS_OVERLAPPEDWINDOW, WS_EX_CLIENTEDGE, CLASS_NAME, CLASS_NAME, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
_parent?_parent->winId:NULL,NULL,GetModuleHandle(0),this _parent ? _parent->winId : NULL, NULL, GetModuleHandle(0), this);
);
winId = hWnd; winId = hWnd;
parent = _parent; parent = _parent;
if (parent) if (parent)
parent->childrens.push_back(this); parent->childrens.push_back(this);
SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this); SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this);
} }
void mainwindow::show(){ void mainwindow::show()
{
ShowWindow(winId, SW_SHOW); ShowWindow(winId, SW_SHOW);
SetForegroundWindow(winId); SetForegroundWindow(winId);
} }
void mainwindow::close(){ void mainwindow::close()
{
ShowWindow(winId, SW_HIDE); ShowWindow(winId, SW_HIDE);
} }
void mainwindow::run(){ void mainwindow::run()
{
MSG msg = {}; MSG msg = {};
while (GetMessage(&msg, NULL, 0, 0)) while (GetMessage(&msg, NULL, 0, 0))
{ {
@ -198,7 +230,8 @@ void mainwindow::run(){
void mainwindow::on_close() {} void mainwindow::on_close() {}
void mainwindow::on_show() {} void mainwindow::on_show() {}
void mainwindow::on_size(int w,int h){ void mainwindow::on_size(int w, int h)
{
if (layout) if (layout)
{ {
layout->setgeo(0, 0, w, h); layout->setgeo(0, 0, w, h);

View File

@ -1,7 +1,8 @@
#ifndef LUNA_BASE_WINDOW_H #ifndef LUNA_BASE_WINDOW_H
#define LUNA_BASE_WINDOW_H #define LUNA_BASE_WINDOW_H
class control; class control;
class basewindow{ class basewindow
{
public: public:
HWND winId; HWND winId;
virtual void setgeo(int, int, int, int); virtual void setgeo(int, int, int, int);
@ -11,10 +12,39 @@ public:
void settext(const std::wstring &); void settext(const std::wstring &);
operator HWND() { return winId; } operator HWND() { return winId; }
}; };
class mainwindow:public basewindow{
struct Font
{
std::wstring fontfamily;
float fontsize;
bool bold;
bool italic;
float calc_height() const
{
return MulDiv(fontsize, GetDeviceCaps(GetDC(NULL), LOGPIXELSY), 72);
}
HFONT hfont() const
{
return CreateFontIndirect(&logfont());
}
LOGFONT logfont() const
{
LOGFONT lf;
ZeroMemory(&lf, sizeof(LOGFONT));
wcscpy_s(lf.lfFaceName, fontfamily.c_str());
if (bold)
lf.lfWeight = FW_BOLD;
lf.lfItalic = italic;
lf.lfHeight = calc_height();
return lf;
}
};
class mainwindow : public basewindow
{
HFONT hfont = 0; HFONT hfont = 0;
public: public:
void setfont(int,LPCWSTR fn=0); void setfont(const Font &);
void visfont(); void visfont();
std::vector<control *> controls; std::vector<control *> controls;
std::vector<mainwindow *> childrens; std::vector<mainwindow *> childrens;