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{

File diff suppressed because it is too large Load Diff

View File

@ -1,130 +1,144 @@
#include"window.h" #include "window.h"
#include"controls.h" #include "controls.h"
#include"textthread.h" #include "textthread.h"
#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; {
Pluginmanager* pluginmanager; listbox *listplugins;
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; {
spinbox* g_timeout; checkbox *ckbfilterrepeat;
spinbox* g_codepage; spinbox *g_timeout;
checkbox* g_check_clipboard; spinbox *g_codepage;
checkbox* readonlycheck; checkbox *g_check_clipboard;
checkbox* autoattach; checkbox *readonlycheck;
checkbox* autoattach_so; checkbox *autoattach;
checkbox* copyselect; checkbox *autoattach_so;
spinbox* spinmaxbuffsize; checkbox *copyselect;
spinbox* spinmaxhistsize; spinbox *spinmaxbuffsize;
gridlayout* mainlayout; spinbox *spinmaxhistsize;
lineedit* showfont; gridlayout *mainlayout;
button* selectfont; lineedit *showfont;
button *selectfont;
public: public:
Settingwindow(LunaHost*); Settingwindow(LunaHost *);
}; };
class processlistwindow:public mainwindow{ class processlistwindow : public mainwindow
gridlayout* mainlayout; {
lineedit* g_hEdit; gridlayout *mainlayout;
button* g_hButton; lineedit *g_hEdit;
listview* g_hListBox; button *g_hButton;
button* g_refreshbutton; listview *g_hListBox;
std::unordered_map<std::wstring,std::vector<int>> g_exe_pid; button *g_refreshbutton;
void PopulateProcessList(listview*,std::unordered_map<std::wstring,std::vector<int>>&); std::unordered_map<std::wstring, std::vector<int>> g_exe_pid;
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; {
lineedit* edittext; gridlayout *layout;
button* checkok; lineedit *edittext;
spinbox* codepage; button *checkok;
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; {
spinbox* spinduration; gridlayout *layout;
spinbox* spinoffset; spinbox *spinduration;
spinbox* spincap; spinbox *spinoffset;
spinbox* spincodepage; spinbox *spincap;
lineedit* editpattern; spinbox *spincodepage;
lineedit* editmodule; lineedit *editpattern;
lineedit* editmaxaddr; lineedit *editmodule;
lineedit* editminaddr; lineedit *editmaxaddr;
spinbox* spinpadding; lineedit *editminaddr;
lineedit* editregex; spinbox *spinpadding;
button* start; lineedit *editregex;
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; {
button* hs_default,*hs_text,*hs_user; checkbox *cjkcheck;
gridlayout* layout; button *hs_default, *hs_text, *hs_user;
Hooksearchsetting* hooksearchsetting=0; gridlayout *layout;
HooksearchText* hooksearchText=0; Hooksearchsetting *hooksearchsetting = 0;
HooksearchText *hooksearchText = 0;
public: public:
Hooksearchwindow(LunaHost* parent); Hooksearchwindow(LunaHost *parent);
}; };
class LunaHost:public mainwindow{ class LunaHost : public mainwindow
Pluginwindow* pluginwindow=0; {
std::set<DWORD>attachedprocess; Pluginwindow *pluginwindow = 0;
lineedit* g_hEdit_userhook; std::set<DWORD> attachedprocess;
gridlayout* mainlayout; lineedit *g_hEdit_userhook;
button* g_hButton_insert; gridlayout *mainlayout;
button* btnplugin; button *g_hButton_insert;
//listbox* g_hListBox_listtext; button *btnplugin;
listview*g_hListBox_listtext; // listbox* g_hListBox_listtext;
multilineedit* g_showtexts; listview *g_hListBox_listtext;
button* g_selectprocessbutton; multilineedit *g_showtexts;
button* btndetachall; button *g_selectprocessbutton;
button* btnsearchhooks; button *btndetachall;
button* btnshowsettionwindow; button *btnsearchhooks;
//button* btnsavehook; button *btnshowsettionwindow;
processlistwindow *_processlistwindow=0; // button* btnsavehook;
Settingwindow *settingwindow=0; processlistwindow *_processlistwindow = 0;
Pluginmanager* plugins; Settingwindow *settingwindow = 0;
Hooksearchwindow * hooksearchwindow=0; Pluginmanager *plugins;
std::atomic<bool> hasstoped=false; Hooksearchwindow *hooksearchwindow = 0;
bool on_text_recv(TextThread& thread, std::wstring& sentence); std::atomic<bool> hasstoped = false;
void on_text_recv_checkissaved(TextThread& thread); bool on_text_recv(TextThread &thread, std::wstring &sentence);
void on_thread_create(TextThread& thread); void on_text_recv_checkissaved(TextThread &thread);
void on_thread_delete(TextThread& thread); void on_thread_create(TextThread &thread);
void on_thread_delete(TextThread &thread);
void on_proc_connect(DWORD pid); void on_proc_connect(DWORD pid);
void on_proc_disconnect(DWORD pid); void on_proc_disconnect(DWORD pid);
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;
std::unordered_map<std::string,nlohmann::json>savedhookcontext; std::unordered_map<std::string, nlohmann::json> savedhookcontext;
std::set<int>userdetachedpids; std::set<int> userdetachedpids;
void on_close(); void on_close();
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

@ -1,11 +1,11 @@
#include<Windows.h> #include <Windows.h>
#include<thread> #include <thread>
#include<mutex> #include <mutex>
#include<Shlwapi.h> #include <Shlwapi.h>
#include<filesystem> #include <filesystem>
#include<queue> #include <queue>
#include"pluginmanager.h" #include "pluginmanager.h"
#include"lockedqueue.hpp" #include "lockedqueue.hpp"
#ifndef _WIN64 #ifndef _WIN64
#define THISCALL __thiscall #define THISCALL __thiscall
#define _CDECL __cdecl #define _CDECL __cdecl
@ -33,115 +33,124 @@
#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()
{
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;
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;
} }
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);
QCoreApplication_addLibraryPath=GetProcAddress(Qt5Core,fnQCoreApplication_addLibraryPath); QString_fromStdWString = GetProcAddress(Qt5Core, fnQString_fromStdWString);
QString_dtor=GetProcAddress(Qt5Core,fnQString_dtor); QCoreApplication_addLibraryPath = GetProcAddress(Qt5Core, fnQCoreApplication_addLibraryPath);
QApplication_ctor=GetProcAddress(Qt5Widgets,fnQApplication_ctor); QString_dtor = GetProcAddress(Qt5Core, fnQString_dtor);
QFont_ctor=GetProcAddress(Qt5Gui,fnQFont_ctor); QApplication_ctor = GetProcAddress(Qt5Widgets, fnQApplication_ctor);
QFont_dtor=GetProcAddress(Qt5Gui,fnQFont_dtor); QFont_ctor = GetProcAddress(Qt5Gui, fnQFont_ctor);
QApplication_setFont=GetProcAddress(Qt5Widgets,fnQApplication_setFont); QFont_dtor = GetProcAddress(Qt5Gui, fnQFont_dtor);
QApplication_exec=GetProcAddress(Qt5Widgets,fnQApplication_exec); QApplication_setFont = GetProcAddress(Qt5Widgets, fnQApplication_setFont);
QApplication_dtor=GetProcAddress(Qt5Widgets,fnQApplication_dtor); QApplication_exec = GetProcAddress(Qt5Widgets, fnQApplication_exec);
QApplication_processEvents=GetProcAddress(Qt5Core,fnQApplication_processEvents); QApplication_dtor = GetProcAddress(Qt5Widgets, fnQApplication_dtor);
QApplication_processEvents = GetProcAddress(Qt5Core, fnQApplication_processEvents);
} }
struct info{ struct info
{
int type; int type;
std::wstring dll; std::wstring dll;
HMODULE hdll; HMODULE hdll;
}; };
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;
if(once)return; static bool once = false;
loadqtdlls(); if (once)
once=!checkqterror(); return;
if(!once)return; loadqtdlls();
std::thread([=](){ once = !checkqterror();
static void* qapp; //必须static if (!once)
void* qstring; return;
void* qfont; std::thread([=]()
for(int i=0;i<dlls->size();i++){
auto dirname=std::filesystem::path(dlls->at(i)).parent_path().wstring();
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&dirname);
((void(_CDECL *)(void*))QCoreApplication_addLibraryPath)(&qstring);
((void(THISCALL*)(void*))QString_dtor)(&qstring);
//QCoreApplication_addLibraryPath(QString_fromStdWString(std::filesystem::path(collectQtplugs[i]).parent_path()));
}
int _=0;
((void*(THISCALL*)(void*,int*,char**,int))QApplication_ctor)(&qapp,&_,0,331266);
std::wstring font=L"MS Shell Dlg 2";
((void* (_CDECL*)(void*,void*))QString_fromStdWString)(&qstring,&font);
((void*(THISCALL*)(void*,void*,int,int,bool))QFont_ctor)(&qfont,&qstring,10,-1,0);
((void(_CDECL*)(void*,void*))QApplication_setFont)(&qfont,0);
((void(THISCALL*)(void*))QFont_dtor)(&qfont);
((void(THISCALL*)(void*))QString_dtor)(&qstring);
while(true)
{
if(!waitingtask.empty())
{
auto top=waitingtask.pop();
if(top.type==1)
{ {
waitingresult.push(LoadLibraryW(top.dll.c_str())); static void *qapp; // 必须static
} void *qstring;
else if(top.type==2) void *qfont;
{ for (int i = 0; i < dlls->size(); i++)
FreeLibrary(top.hdll); {
} auto dirname = std::filesystem::path(dlls->at(i)).parent_path().wstring();
} ((void *(_CDECL *)(void *, void *))QString_fromStdWString)(&qstring, &dirname);
((void(_CDECL*)(DWORD))QApplication_processEvents)(0); ((void(_CDECL *)(void *))QCoreApplication_addLibraryPath)(&qstring);
Sleep(1); ((void(THISCALL *)(void *))QString_dtor)(&qstring);
} // QCoreApplication_addLibraryPath(QString_fromStdWString(std::filesystem::path(collectQtplugs[i]).parent_path()));
}
// ((void(*)())QApplication_exec)();
int _ = 0;
// ((void(THISCALL*)(void*))QApplication_dtor)(&qapp); ((void *(THISCALL *)(void *, int *, char **, int))QApplication_ctor)(&qapp, &_, 0, 331266);
}).detach(); std::wstring font = L"MS Shell Dlg 2";
((void *(_CDECL *)(void *, void *))QString_fromStdWString)(&qstring, &font);
((void *(THISCALL *)(void *, void *, int, int, bool))QFont_ctor)(&qfont, &qstring, 10, -1, 0);
((void(_CDECL *)(void *, void *))QApplication_setFont)(&qfont, 0);
((void(THISCALL *)(void *))QFont_dtor)(&qfont);
((void(THISCALL *)(void *))QString_dtor)(&qstring);
while (true)
{
if (!waitingtask.empty())
{
auto top = waitingtask.pop();
if (top.type == 1)
{
waitingresult.push(LoadLibraryW(top.dll.c_str()));
}
else if (top.type == 2)
{
FreeLibrary(top.hdll);
}
}
((void(_CDECL *)(DWORD))QApplication_processEvents)(0);
Sleep(1);
}
// ((void(*)())QApplication_exec)();
// ((void(THISCALL*)(void*))QApplication_dtor)(&qapp);
})
.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);
@ -12,29 +14,34 @@ std::string readfile(const wchar_t* fname) {
fread(buff.data(), 1, len, f); fread(buff.data(), 1, len, f);
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"); {
try{ configpath = std::filesystem::current_path() / (x64 ? "config64.json" : "config32.json");
configs=nlohmann::json::parse(readfile(configpath.c_str())); try
{
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

@ -1,26 +1,33 @@
#ifndef LUNA_CONFIG_HELPER #ifndef LUNA_CONFIG_HELPER
#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,279 +1,343 @@
#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; {
parent=_parent; if (_parent == 0)
return;
parent = _parent;
parent->controls.push_back(this); parent->controls.push_back(this);
} }
void control::dispatch(WPARAM){} void control::dispatch(WPARAM) {}
void control::dispatch_2(WPARAM wParam, LPARAM lParam){}; void control::dispatch_2(WPARAM wParam, LPARAM lParam) {};
button::button(mainwindow* parent):control(parent){} button::button(mainwindow *parent) : control(parent) {}
button::button(mainwindow* parent,const std::wstring& text):control(parent) 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);
} }
checkbox::checkbox(mainwindow* parent,const std::wstring& text):button(parent) 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 , {
0,0,0,0, parent->winId, NULL, NULL, NULL); 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);
hUpDown = CreateWindowEx(0, UPDOWN_CLASS, NULL, hUpDown = CreateWindowEx(0, UPDOWN_CLASS, NULL,
WS_CHILD | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS , WS_CHILD | WS_VISIBLE | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_NOTHOUSANDS,
0, 0, 0, 0, 0, 0, 0, 0,
parent->winId, NULL, NULL, NULL); parent->winId, NULL, NULL, NULL);
SendMessage(hUpDown, UDM_SETBUDDY, (WPARAM)winId, 0); SendMessage(hUpDown, UDM_SETBUDDY, (WPARAM)winId, 0);
setminmax(0,0x7fffffff); setminmax(0, 0x7fffffff);
std::tie(minv,maxv)= getminmax(); std::tie(minv, maxv) = getminmax();
} }
void spinbox::setgeo(int x,int y,int w,int h) 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{ {
value=std::stoi(text()); bool ok = false;
ok=true; int value;
try
{
value = std::stoi(text());
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); {
std::tie(minv,maxv)= getminmax(); SendMessage(hUpDown, UDM_SETRANGE32, min, max);
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 , {
0,0,0,0, parent->winId, NULL, NULL, NULL); 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);
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 , {
0,0,0,0, parent->winId, NULL, NULL, NULL); winId = CreateWindowEx(0, L"EDIT", L"", WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
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; {
SendMessage(winId, EM_REPLACESEL, 0, (LPARAM)_.c_str()); auto _ = std::wstring(L"\r\n") + text;
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, {
0,0,0,0, parent->winId , NULL, NULL, NULL); winId = CreateWindowEx(0, L"STATIC", text.c_str(), WS_CHILD | WS_VISIBLE,
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,
0,0,0,0, parent->winId , NULL, NULL, NULL); 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);
} }
void listbox::dispatch(WPARAM wparam){ void listbox::dispatch(WPARAM wparam)
if(HIWORD(wparam) == LBN_SELCHANGE){ {
auto idx=currentidx(); if (HIWORD(wparam) == LBN_SELCHANGE)
if(idx!=-1) {
auto idx = currentidx();
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) {
data.second-=1; if (data.second >= i)
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; {
if(notheader)style|=LVS_NOCOLUMNHEADER; auto style = WS_VISIBLE | WS_VSCROLL | WS_CHILD | LVS_REPORT | LVS_SINGLESEL;
winId=CreateWindowEx(0, WC_LISTVIEW, NULL, style , 0,0,0,0, parent->winId, NULL,NULL, NULL); if (notheader)
style |= LVS_NOCOLUMNHEADER;
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), {
ILC_COLOR32, 1 ,1); hImageList = ImageList_Create(22, 22, // GetSystemMetrics(SM_CXSMICON), GetSystemMetrics(SM_CYSMICON),
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) {
data.second+=1; if (data.second >= row)
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; {
switch (pnmhdr->code){ NMHDR *pnmhdr = (NMHDR *)lParam;
switch (pnmhdr->code)
case LVN_ITEMCHANGED: {
{
NMLISTVIEW* pnmListView = (NMLISTVIEW*)lParam; case LVN_ITEMCHANGED:
if ((pnmListView->uChanged & LVIF_STATE) && (pnmListView->uNewState & LVIS_SELECTED)) {
{ NMLISTVIEW *pnmListView = (NMLISTVIEW *)lParam;
oncurrentchange(pnmListView->iItem); if ((pnmListView->uChanged & LVIF_STATE) && (pnmListView->uNewState & LVIS_SELECTED))
} {
break; oncurrentchange(pnmListView->iItem);
} }
break;
}
} }
} }
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,134 +345,149 @@ 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++){ {
insertcol(i,headers[i]); for (int i = 0; i < headers.size(); 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); {
ListView_SetColumnWidth(winId, 1, w-w0); auto w0 = ListView_GetColumnWidth(winId, 0);
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 dynacol=maxcol; auto dynarow = maxrow;
for(auto fw:fixedwidth){ auto dynacol = maxcol;
dynacol-=1; for (auto fw : fixedwidth)
w-=fw.second+margin; {
dynacol -= 1;
w -= fw.second + margin;
} }
for(auto fh:fixedheight){ for (auto fh : fixedheight)
dynarow-=1; {
h-=fh.second+margin; dynarow -= 1;
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;
for(int c=0;c<ctr.col+ctr.colrange;c++) int _x = 0, _y = 0, _w = 0, _h = 0;
for (int c = 0; c < ctr.col + ctr.colrange; c++)
{ {
if(fixedwidth.find(c)!=fixedwidth.end()) if (fixedwidth.find(c) != fixedwidth.end())
if(c<ctr.col) if (c < ctr.col)
_x+=fixedwidth[c]; _x += fixedwidth[c];
else else
_w+=fixedwidth[c]; _w += fixedwidth[c];
else if (c < ctr.col)
_x += wpercol;
else else
if(c<ctr.col) _w += wpercol;
_x+=wpercol;
else
_w+=wpercol;
} }
_x+=(ctr.col+1)*margin; _x += (ctr.col + 1) * margin;
_w+=(ctr.colrange-1)*margin; _w += (ctr.colrange - 1) * margin;
for(int r=0;r<ctr.row+ctr.rowrange;r++) for (int r = 0; r < ctr.row + ctr.rowrange; r++)
{ {
if(fixedheight.find(r)!=fixedheight.end()) if (fixedheight.find(r) != fixedheight.end())
if(r<ctr.row) if (r < ctr.row)
_y+=fixedheight[r]; _y += fixedheight[r];
else else
_h+=fixedheight[r]; _h += fixedheight[r];
else if (r < ctr.row)
_y += hperrow;
else else
if(r<ctr.row) _h += hperrow;
_y+=hperrow;
else
_h+=hperrow;
} }
_y+=(ctr.row+1)*margin; _y += (ctr.row + 1) * margin;
_h+=(ctr.rowrange-1)*margin; _h += (ctr.rowrange - 1) * margin;
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); {
maxcol=max(maxcol,col+colrange); maxrow = max(maxrow, row + rowrange);
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; {
maxcol=col; maxrow = row;
margin=10; maxcol = col;
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

@ -1,148 +1,165 @@
#ifndef LUNA_BASE_CONTROLS_H #ifndef LUNA_BASE_CONTROLS_H
#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;
}; };
std::vector<menuinfos>menu_callbacks; std::vector<menuinfos> menu_callbacks;
HMENU load(); HMENU load();
HMENU hmenu; HMENU hmenu;
void add(const std::wstring&,std::function<void()> callback); void add(const std::wstring &, std::function<void()> callback);
void add_checkable(const std::wstring&,bool,std::function<void(bool)> callback); void add_checkable(const std::wstring &, bool, std::function<void(bool)> callback);
void add_sep(); void add_sep();
}; };
using maybehavemenu=std::optional<Menu>; using maybehavemenu = std::optional<Menu>;
class control:public basewindow{ class control : public basewindow
public: {
mainwindow* parent; public:
control(mainwindow*); mainwindow *parent;
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);
std::function<void(const std::wstring&)> ontextchange=[&](const std::wstring &text){}; std::function<void(const std::wstring &)> ontextchange = [&](const std::wstring &text) {};
void appendtext(const std::wstring&); void appendtext(const std::wstring &);
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);
void setminmax(int,int); void setminmax(int, int);
std::pair<int,int>getminmax(); std::pair<int, int> getminmax();
void setcurr(int); void setcurr(int);
int getcurr(); int getcurr();
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);
int currentidx(); int currentidx();
std::wstring text(int); std::wstring text(int);
std::function<void(int)> oncurrentchange=[](int){}; std::function<void(int)> oncurrentchange = [](int) {};
void clear(); void clear();
int additem(const std::wstring&); int additem(const std::wstring &);
void deleteitem(int); void deleteitem(int);
void setdata(int,LONG_PTR); void setdata(int, LONG_PTR);
void setcurrent(int idx); void setcurrent(int idx);
int insertitem(int,const std::wstring&); int insertitem(int, const std::wstring &);
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);
void settext(int,int,const std::wstring&); void settext(int, int, const std::wstring &);
int insertcol(int,const std::wstring& ); int insertcol(int, const std::wstring &);
void clear(); void clear();
int count(); int count();
int currentidx(); int currentidx();
void setcurrent(int idx); void setcurrent(int idx);
std::function<void(int)> oncurrentchange=[](int){}; std::function<void(int)> oncurrentchange = [](int) {};
std::wstring text(int,int=0); std::wstring text(int, int = 0);
void setheader(const std::vector<std::wstring>&); void setheader(const std::vector<std::wstring> &);
void deleteitem(int); void deleteitem(int);
int additem(const std::wstring&,HICON hicon=NULL); int additem(const std::wstring &, HICON hicon = NULL);
LONG_PTR getdata(int); LONG_PTR getdata(int);
void setdata(int,LONG_PTR); void setdata(int, LONG_PTR);
int querydataidx(LONG_PTR); int querydataidx(LONG_PTR);
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{ {
control* ctr; struct _c
int row,col,rowrange,colrange; {
control *ctr;
int row, col, rowrange, colrange;
}; };
int margin; int margin;
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:
void setgeo(int,int,int,int);
void setfixedwidth(int col,int width);
void setfixedheigth(int row,int height);
void addcontrol(control*,int row,int col,int rowrange=1,int colrange=1);
gridlayout(int row=0,int col=0);
void setmargin(int m=10);
};
class FontSelector{
public: public:
FontSelector(HWND hwnd,const std::wstring& init,std::function<void(const std::wstring&)>callback); void setgeo(int, int, int, int);
void setfixedwidth(int col, int width);
void setfixedheigth(int row, int height);
void addcontrol(control *, int row, int col, int rowrange = 1, int colrange = 1);
gridlayout(int row = 0, int col = 0);
void setmargin(int m = 10);
};
class FontSelector
{
public:
FontSelector(HWND hwnd, const Font &, std::function<void(const Font &)> callback);
}; };
#endif #endif

View File

@ -4,18 +4,17 @@ using InternetHandle = AutoHandle<Functor<WinHttpCloseHandle>>;
struct HttpRequest struct HttpRequest
{ {
HttpRequest( HttpRequest(
const wchar_t* agentName, const wchar_t *agentName,
const wchar_t* serverName, const wchar_t *serverName,
const wchar_t* action, const wchar_t *action,
const wchar_t* objectName, const wchar_t *objectName,
std::string body = "", std::string body = "",
const wchar_t* headers = NULL, const wchar_t *headers = NULL,
DWORD port = INTERNET_DEFAULT_PORT, DWORD port = INTERNET_DEFAULT_PORT,
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;
@ -26,21 +25,21 @@ struct HttpRequest
}; };
HttpRequest::HttpRequest( HttpRequest::HttpRequest(
const wchar_t* agentName, const wchar_t *agentName,
const wchar_t* serverName, const wchar_t *serverName,
const wchar_t* action, const wchar_t *action,
const wchar_t* objectName, const wchar_t *objectName,
std::string body, std::string body,
const wchar_t* headers, const wchar_t *headers,
DWORD port, DWORD port,
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))
@ -48,17 +47,18 @@ HttpRequest::HttpRequest(
{ {
WinHttpReceiveResponse(request, NULL); WinHttpReceiveResponse(request, NULL);
//DWORD size = 0; // DWORD size = 0;
//WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &size, WINHTTP_NO_HEADER_INDEX); // WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, NULL, &size, WINHTTP_NO_HEADER_INDEX);
//this->headers.resize(size); // this->headers.resize(size);
//WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, this->headers.data(), &size, WINHTTP_NO_HEADER_INDEX); // WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF, WINHTTP_HEADER_NAME_BY_INDEX, this->headers.data(), &size, WINHTTP_NO_HEADER_INDEX);
std::string data; std::string data;
DWORD availableSize, downloadedSize; DWORD availableSize, downloadedSize;
do do
{ {
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:
lockedqueue(){ public:
hsema=CreateSemaphore(NULL,0,65535,NULL); lockedqueue()
{
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

@ -1,15 +1,16 @@
#include"pluginmanager.h" #include "pluginmanager.h"
#include<filesystem> #include <filesystem>
#include"Plugin/extension.h" #include "Plugin/extension.h"
#include<fstream> #include <fstream>
#include <commdlg.h> #include <commdlg.h>
#include"LunaHost.h" #include "LunaHost.h"
#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};
ZeroMemory(&ofn, sizeof(ofn)); ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(ofn); ofn.lStructSize = sizeof(ofn);
@ -23,221 +24,268 @@ 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; {
if(qt5core==0) static HMODULE 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);
#else #else
HMODULE base=LoadLibrary((std::filesystem::current_path()/(x64?"plugin64":"plugin32")/"QtLoader.dll").wstring().c_str()); HMODULE base = LoadLibrary((std::filesystem::current_path() / (x64 ? "plugin64" : "plugin32") / "QtLoader.dll").wstring().c_str());
#endif #endif
//auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(base, "QtLoadLibrary"); // auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(base, "QtLoadLibrary");
auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(base, "QtLoadLibraryBatch"); auto QtLoadLibrary = (QtLoadLibrary_t)GetProcAddress(base, "QtLoadLibraryBatch");
auto modules=QtLoadLibrary(&collectQtplugs); auto modules = QtLoadLibrary(&collectQtplugs);
std::vector<HMODULE> _{*modules}; std::vector<HMODULE> _{*modules};
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); {
for(int i=0;i<collectQtplugs.size();i++){ auto modules = loadqtdllsX(collectQtplugs);
OnNewSentenceS[collectQtplugs[i]]={collectQtplugs[i],this,true,modules[i]}; for (int i = 0; i < collectQtplugs.size(); 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); {
bool isqt=plg.isQt; auto plg = get(i);
auto path=plg.wpath(); bool isqt = plg.isQt;
OnNewSentenceS[path]={}; auto path = plg.wpath();
if(isqt){ OnNewSentenceS[path] = {};
if(plg.enable==false)continue; if (isqt)
{
if (plg.enable == false)
continue;
collectQtplugs.push_back((path)); collectQtplugs.push_back((path));
} }
else{ else
auto base=LoadLibraryW(path.c_str()); {
OnNewSentenceS[path]={path,this,false,base}; auto base = LoadLibraryW(path.c_str());
OnNewSentenceS[path] = {path, this, false, base};
} }
} }
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(); {
wchar_t* sentenceBuffer = (wchar_t*)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, (sentence.size() + 1) * sizeof(wchar_t)); auto sentenceInfo = GetSentenceInfo(thread).data();
wcscpy_s(sentenceBuffer, sentence.size() + 1, sentence.c_str()); 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());
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
path=getname(i); {
if (getenable(i) == false)
continue;
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;
} }
sentence = sentenceBuffer; sentence = sentenceBuffer;
HeapFree(GetProcessHeap(), 0, sentenceBuffer); HeapFree(GetProcessHeap(), 0, sentenceBuffer);
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"]; {
isQt=safequeryjson(js,"isQt",false); path = js["path"];
isref=safequeryjson(js,"isref",false); isQt = safequeryjson(js, "isQt", false);
enable=safequeryjson(js,"enable",true); isref = safequeryjson(js, "isref", false);
vissetting=safequeryjson(js,"vissetting",true); enable = safequeryjson(js, "enable", true);
vissetting = safequeryjson(js, "vissetting", true);
} }
std::wstring pluginitem::wpath(){ std::wstring pluginitem::wpath()
auto wp=StringToWideString(path); {
if(isref)return std::filesystem::current_path()/wp; auto wp = StringToWideString(path);
else return wp; if (isref)
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(); {
if(startWith(p,curr)){ auto curr = std::filesystem::current_path().wstring();
return {p.substr(curr.size()+1),true}; if (startWith(p, curr))
{
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; {
auto [p,_isref]=castabs2ref(pabs); isQt = _isQt;
isref=_isref; auto [p, _isref] = castabs2ref(pabs);
path=WideStringToString(p); isref = _isref;
enable=true; path = WideStringToString(p);
vissetting=true; enable = 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); {
item.vissetting=vis; auto item = get(idx);
set(idx,item); item.vissetting = vis;
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); {
item.enable=en; auto item = get(idx);
set(idx,item); item.enable = en;
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; {
if(OnNewSentenceS[wss].isQt && hm){ auto hm = OnNewSentenceS[wss].hmodule;
((QtFreeLibrary_t)GetProcAddress(GetModuleHandle(0),"QtFreeLibrary"))(hm); if (OnNewSentenceS[wss].isQt && hm)
{
((QtFreeLibrary_t)GetProcAddress(GetModuleHandle(0), "QtFreeLibrary"))(hm);
} }
else else
FreeLibrary(hm); FreeLibrary(hm);
OnNewSentenceS[wss].clear(); OnNewSentenceS[wss].clear();
} }
void plugindata::clear(){ void plugindata::clear()
hmodule=0; {
OnNewSentence=0; hmodule = 0;
VisSetting=0; OnNewSentence = 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 _b=plgs[b]; auto &plgs = configs->configs["plugins"];
plgs[b]=plgs[a]; auto _b = plgs[b];
plgs[a]=_b; plgs[b] = plgs[a];
plgs[a] = _b;
} }
DWORD Rva2Offset(DWORD rva, PIMAGE_SECTION_HEADER psh, PIMAGE_NT_HEADERS pnt) DWORD Rva2Offset(DWORD rva, PIMAGE_SECTION_HEADER psh, PIMAGE_NT_HEADERS pnt)
{ {
@ -251,167 +299,190 @@ DWORD Rva2Offset(DWORD rva, PIMAGE_SECTION_HEADER psh, PIMAGE_NT_HEADERS pnt)
for (i = 0; i < pnt->FileHeader.NumberOfSections; i++) for (i = 0; i < pnt->FileHeader.NumberOfSections; i++)
{ {
if (rva >= pSeh->VirtualAddress && rva < pSeh->VirtualAddress + if (rva >= pSeh->VirtualAddress && rva < pSeh->VirtualAddress +
pSeh->Misc.VirtualSize) pSeh->Misc.VirtualSize)
{ {
break; break;
} }
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 sz):_ptr(ptr),size(sz){} PVOID _ptr;
~__(){ DWORD size;
__(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)
{ {
//Get the name of each DLL // Get the name of each DLL
auto nameoffset=Rva2Offset(pImportDescriptor->Name, pSech, ntheaders); auto nameoffset = Rva2Offset(pImportDescriptor->Name, pSech, ntheaders);
if(nameoffset==(DWORD)-1) if (nameoffset == (DWORD)-1)
//无导入 // 无导入
return {}; return {};
ret.insert((PCHAR)((DWORD_PTR)virtualpointer + nameoffset )); ret.insert((PCHAR)((DWORD_PTR)virtualpointer + nameoffset));
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)
{ {
for(auto qt5:{"Qt5Widgets.dll","Qt5Gui.dll","Qt5Core.dll"}) for (auto qt5 : {"Qt5Widgets.dll", "Qt5Gui.dll", "Qt5Core.dll"})
if(dll.find(qt5)!=dll.end()) if (dll.find(qt5) != dll.end())
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); {
if(importtable.empty())return addpluginresult::invaliddll; auto importtable = getimporttable(p);
auto isQt=qtchecker(importtable); if (importtable.empty())
if(isqt)*isqt=isQt; return addpluginresult::invaliddll;
auto isQt = qtchecker(importtable);
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);
OnNewSentenceS[p]={p,this,isQt,base}; OnNewSentenceS[p] = {p, this, isQt, base};
if(!OnNewSentenceS[p].valid()) if (!OnNewSentenceS[p].valid())
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; {
isQt=_isQt; hmodule = hm;
OnNewSentence=(OnNewSentence_t)GetProcAddress(hm,"OnNewSentence"); isQt = _isQt;
VisSetting=(VisSetting_t)GetProcAddress(hm,"VisSetting"); OnNewSentence = (OnNewSentence_t)GetProcAddress(hm, "OnNewSentence");
refpath=p; VisSetting = (VisSetting_t)GetProcAddress(hm, "VisSetting");
if(VisSetting) refpath = p;
if (VisSetting)
{ {
auto vis=true; auto vis = true;
if(auto plg=manager->get(p)) if (auto plg = manager->get(p))
vis=plg.value().vissetting; vis = plg.value().vissetting;
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 }, {"text number", thread.handle},
{ "text number", thread.handle }, {"process id", thread.tp.processId},
{ "process id", thread.tp.processId }, {"hook address", (int64_t)thread.tp.addr},
{ "hook address", (int64_t)thread.tp.addr }, {"text handle", thread.handle},
{ "text handle", thread.handle }, {"text name", (int64_t)thread.name.c_str()},
{ "text name", (int64_t)thread.name.c_str() }, {"add sentence", (int64_t)AddSentence},
{ "add sentence", (int64_t)AddSentence }, {"add text", (int64_t)AddText},
{ "add text", (int64_t)AddText }, {"get selected process id", (int64_t)GetSelectedProcessId},
{ "get selected process id", (int64_t)GetSelectedProcessId }, {"void (*AddSentence)(int64_t number, const wchar_t* sentence)", (int64_t)AddSentence},
{ "void (*AddSentence)(int64_t number, const wchar_t* sentence)", (int64_t)AddSentence }, {"void (*AddText)(int64_t number, const wchar_t* text)", (int64_t)AddText},
{ "void (*AddText)(int64_t number, const wchar_t* text)", (int64_t)AddText }, {"DWORD (*GetSelectedProcessId)()", (int64_t)GetSelectedProcessId},
{ "DWORD (*GetSelectedProcessId)()", (int64_t)GetSelectedProcessId }, {nullptr, 0} // nullptr marks end of info array
{ nullptr, 0 } // nullptr marks end of info array }};
} };
} }

View File

@ -1,30 +1,33 @@
#ifndef LUNA_PLUGINMANAGER_H #ifndef LUNA_PLUGINMANAGER_H
#define LUNA_PLUGINMANAGER_H #define LUNA_PLUGINMANAGER_H
#include"Plugin/extension.h" #include "Plugin/extension.h"
#include"textthread.h" #include "textthread.h"
#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;
bool enable; bool enable;
bool vissetting; bool vissetting;
pluginitem(const nlohmann::json&); pluginitem(const nlohmann::json &);
pluginitem(const std::wstring&,bool); pluginitem(const std::wstring &, bool);
std::wstring wpath(); std::wstring wpath();
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;
bool isQt; bool isQt;
@ -33,39 +36,41 @@ struct plugindata{
HMODULE hmodule; HMODULE hmodule;
void clear(); void clear();
plugindata(){}; plugindata(){};
plugindata(const std::wstring&,Pluginmanager*,bool,HMODULE); plugindata(const std::wstring &, Pluginmanager *, bool, HMODULE);
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 &);
confighelper* configs; confighelper *configs;
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);
addpluginresult addplugin(const std::wstring&); addpluginresult addplugin(const std::wstring &);
std::optional<std::wstring>selectpluginfile(); std::optional<std::wstring> selectpluginfile();
pluginitem get(int); pluginitem get(int);
std::optional<pluginitem> get(const std::wstring&); std::optional<pluginitem> get(const std::wstring &);
std::wstring getname(int); std::wstring getname(int);
bool getenable(int); bool getenable(int);
void set(int,const pluginitem&); void set(int, const pluginitem &);
void setenable(int ,bool); void setenable(int, bool);
int count(); int count();
void add(const pluginitem&); void add(const pluginitem &);
void remove(const std::wstring&); void remove(const std::wstring &);
void unload(const std::wstring&); void unload(const std::wstring &);
addpluginresult load(const std::wstring&,bool*isqt=0); addpluginresult load(const std::wstring &, bool *isqt = 0);
void swaprank(int,int); void swaprank(int, int);
bool getvisible(int); bool getvisible(int);
bool getvisible_setable(int); bool getvisible_setable(int);
void setvisible(int,bool); void setvisible(int, bool);
}; };
#endif #endif

View File

@ -1,13 +1,13 @@
#include <CommCtrl.h> #include <CommCtrl.h>
#include <TlHelp32.h> #include <TlHelp32.h>
#include"host.h" #include "host.h"
#include"LunaHost.h" #include "LunaHost.h"
#include"Lang/Lang.h" #include "Lang/Lang.h"
#include<shellapi.h> #include <shellapi.h>
std::unordered_map<std::wstring,std::vector<int>> getprocesslist() std::unordered_map<std::wstring, std::vector<int>> getprocesslist()
{ {
std::unordered_map<std::wstring,std::vector<int>>exe_pid; std::unordered_map<std::wstring, std::vector<int>> exe_pid;
AutoHandle<> hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); AutoHandle<> hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot == INVALID_HANDLE_VALUE) if (hSnapshot == INVALID_HANDLE_VALUE)
return {}; return {};
@ -15,30 +15,32 @@ std::unordered_map<std::wstring,std::vector<int>> getprocesslist()
PROCESSENTRY32 pe32; PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32); pe32.dwSize = sizeof(PROCESSENTRY32);
wchar_t buff[65535]; wchar_t buff[65535];
auto currpid=GetCurrentProcessId(); auto currpid = GetCurrentProcessId();
if (Process32First(hSnapshot, &pe32)) if (Process32First(hSnapshot, &pe32))
{ {
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)
if(pe32.th32ProcessID==currpid)continue; 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 str=stolower(buffs);
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()){ auto buffs = std::wstring(buff);
exe_pid.insert({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 (exe_pid.find(buffs) == exe_pid.end())
{
exe_pid.insert({buffs, {}});
} }
exe_pid[buffs].push_back(pe32.th32ProcessID); exe_pid[buffs].push_back(pe32.th32ProcessID);
} while (Process32Next(hSnapshot, &pe32)); } while (Process32Next(hSnapshot, &pe32));
@ -46,64 +48,79 @@ 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); {
_listbox->additem(exe.first,hicon); auto hicon = GetExeIcon(exe.first);
_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(); {
if(str.size()){ auto str = g_hEdit->text();
if (str.size())
{
close(); close();
for(auto _s:strSplit(str,L",")){ for (auto _s : strSplit(str, L","))
DWORD pid=0; {
try{ DWORD pid = 0;
pid=std::stoi(_s); try
}catch(std::exception&){} {
if(pid) pid = std::stoi(_s);
}
catch (std::exception &)
{
}
if (pid)
Host::InjectProcess(pid); Host::InjectProcess(pid);
} }
} }
}; };
g_refreshbutton->onclick=[&](){ g_refreshbutton->onclick = [&]()
g_exe_pid=getprocesslist(); {
PopulateProcessList(g_hListBox,g_exe_pid); g_exe_pid = getprocesslist();
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","; {
_+=std::to_wstring(p); if (_1)
_1=true; _ += L",";
} _ += std::to_wstring(p);
_1 = true;
}
g_hEdit->settext(_); g_hEdit->settext(_);
}; };
settext(WndSelectProcess); settext(WndSelectProcess);
mainlayout=new gridlayout(); mainlayout = new gridlayout();
mainlayout->addcontrol(g_hEdit,0,0,1,2); mainlayout->addcontrol(g_hEdit, 0, 0, 1, 2);
mainlayout->addcontrol(g_hButton,0,2); mainlayout->addcontrol(g_hButton, 0, 2);
mainlayout->addcontrol(g_refreshbutton,0,3); mainlayout->addcontrol(g_refreshbutton, 0, 3);
mainlayout->addcontrol(g_hListBox,1,0,1,4); mainlayout->addcontrol(g_hListBox, 1, 0, 1, 4);
mainlayout->setfixedheigth(0,30); mainlayout->setfixedheigth(0, 30);
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

@ -1,193 +1,225 @@
#include"window.h" #include "window.h"
#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); {
on_size(w,h); MoveWindow(winId, x, y, w, h, TRUE);
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:
{
on_show();
visfont();
break;
}
case WM_SIZE:
{
int width = LOWORD(lParam);
int height = HIWORD(lParam);
on_size(width, height);
break;
}
case WM_NOTIFY:
{
NMHDR *pnmhdr = (NMHDR *)lParam;
for (auto ctl : controls)
{ {
on_show(); if (pnmhdr->hwndFrom == ctl->winId)
visfont();
break;
}
case WM_SIZE:
{
int width = LOWORD(lParam);
int height = HIWORD(lParam);
on_size(width,height);
break;
}
case WM_NOTIFY:
{
NMHDR* pnmhdr = (NMHDR*)lParam;
for(auto ctl:controls)
{ {
if(pnmhdr->hwndFrom==ctl->winId) ctl->dispatch_2(wParam, lParam);
break;
}
}
}
case WM_COMMAND:
{
if (lParam == 0)
{
for (auto ctl : controls)
{
if (lastcontexthwnd == ctl->winId)
{ {
ctl->dispatch_2(wParam,lParam);break; if (ctl->menu)
} ctl->menu.value().dispatch(wParam);
}
}
case WM_COMMAND:
{
if(lParam==0){
for(auto ctl:controls){
if(lastcontexthwnd==ctl->winId){
if(ctl->menu)
ctl->menu.value().dispatch(wParam);
break;
}
}
}
else
for(auto ctl:controls){
if((HWND)lParam==ctl->winId){
ctl->dispatch(wParam);break;
}
}
break;
}
case WM_CONTEXTMENU:
{
bool succ=false;lastcontexthwnd=0;
for(auto ctl:controls){
if((HWND)wParam==ctl->winId){
auto hm=ctl->on_menu();
ctl->menu=hm;
if(hm){
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
TrackPopupMenu(hm.value().load(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
xPos, yPos, 0, winId, NULL);
lastcontexthwnd=ctl->winId;
succ=true;
}
break; break;
} }
} }
if(succ==false)return DefWindowProc(winId, message, wParam, lParam);
break;
} }
case WM_CLOSE: else
{ for (auto ctl : controls)
on_close(); {
if(parent==0)PostQuitMessage(0); if ((HWND)lParam == ctl->winId)
else ShowWindow(winId,SW_HIDE); {
break; ctl->dispatch(wParam);
} break;
default: }
return DefWindowProc(winId, message, wParam, lParam); }
break;
} }
case WM_CONTEXTMENU:
{
bool succ = false;
lastcontexthwnd = 0;
for (auto ctl : controls)
{
if ((HWND)wParam == ctl->winId)
{
auto hm = ctl->on_menu();
ctl->menu = hm;
if (hm)
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
TrackPopupMenu(hm.value().load(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_RIGHTBUTTON,
xPos, yPos, 0, winId, NULL);
lastcontexthwnd = ctl->winId;
succ = true;
}
break;
}
}
if (succ == false)
return DefWindowProc(winId, message, wParam, lParam);
break;
}
case WM_CLOSE:
{
on_close();
if (parent == 0)
PostQuitMessage(0);
else
ShowWindow(winId, SW_HIDE);
break;
}
default:
return DefWindowProc(winId, message, wParam, 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; {
if(parent==0){ int cx, cy;
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(); {
cx=(rect.left+rect.right)/2; auto rect = parent->getgeo();
cy=(rect.top+rect.bottom)/2; cx = (rect.left + rect.right) / 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); {
setgeo(x,y,w,h); auto [x, y] = calculateXY(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; {
const wchar_t CLASS_NAME[] = L"LunaHostWindow"; layout = 0;
const wchar_t CLASS_NAME[] = L"LunaHostWindow";
WNDCLASS wc = {}; WNDCLASS wc = {};
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 _window->wndproc(message,wParam,lParam); return DefWindowProc(hWnd, message, wParam, lParam);
return _window->wndproc(message, wParam, lParam);
}; };
wc.hInstance = GetModuleHandle(0); wc.hInstance = GetModuleHandle(0);
wc.lpszClassName = CLASS_NAME; wc.lpszClassName = CLASS_NAME;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW ); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.hIcon= GetExeIcon(getModuleFilename().value());//LoadIconW(GetModuleHandle(0),L"IDI_ICON1"); wc.hIcon = GetExeIcon(getModuleFilename().value()); // LoadIconW(GetModuleHandle(0),L"IDI_ICON1");
static auto _=RegisterClass(&wc); static auto _ = RegisterClass(&wc);
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))
{ {
@ -196,12 +228,13 @@ 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);
} }
} }
void basewindow::on_size(int w,int h){} void basewindow::on_size(int w, int h) {}

View File

@ -1,37 +1,67 @@
#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);
virtual void on_size(int w,int h); virtual void on_size(int w, int h);
RECT getgeo(); RECT getgeo();
std::wstring text(); std::wstring text();
void settext(const std::wstring&); void settext(const std::wstring &);
operator HWND(){return winId;} operator HWND() { return winId; }
}; };
class mainwindow:public basewindow{
HFONT hfont=0; 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;
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;
mainwindow* parent; mainwindow *parent;
HWND lastcontexthwnd; HWND lastcontexthwnd;
control* layout; control *layout;
virtual void on_show(); virtual void on_show();
virtual void on_close(); virtual void on_close();
void on_size(int w,int h); void on_size(int w, int h);
mainwindow(mainwindow* _parent=0); mainwindow(mainwindow *_parent = 0);
LRESULT wndproc(UINT message, WPARAM wParam, LPARAM lParam); LRESULT wndproc(UINT message, WPARAM wParam, LPARAM lParam);
static void run(); static void run();
void show(); void show();
void close(); void close();
void setcentral(int,int); void setcentral(int, int);
std::pair<int,int>calculateXY(int w,int h); std::pair<int, int> calculateXY(int w, int h);
void setlayout(control*); void setlayout(control *);
}; };
HICON GetExeIcon(const std::wstring& filePath); HICON GetExeIcon(const std::wstring &filePath);
#endif #endif