mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-12-24 04:04:14 +08:00
hookfind
This commit is contained in:
parent
6f3bc497ab
commit
6e011c5780
19
Lang/en.h
19
Lang/en.h
@ -48,6 +48,7 @@
|
||||
#define BtnToClipboard L"Copy To Clipboard"
|
||||
#define BtnReadOnly L"Text box Read only"
|
||||
#define BtnInsertUserHook L"Insert UserHook"
|
||||
#define BtnSearchHook L"Search for hooks"
|
||||
#define BtnPlugin L"Plugins"
|
||||
#define LblFlushDelay L"Flush delay"
|
||||
#define LblFilterRepeat L"Filter repetition"
|
||||
@ -70,4 +71,20 @@
|
||||
#define LblPluginNotify L"Qt Plugins Will be Loaded at Start Only."
|
||||
#define LblPluginRemove L"Remove Plugins Will be Useful after Restart."
|
||||
#define InvalidPlugin L"Invalid Plugin!"
|
||||
#define MsgError L"Error"
|
||||
#define MsgError L"Error"
|
||||
#define SEARCH_CJK L"Search for Chinese/Japanese/Korean"
|
||||
#define HS_SETTINGS L"Settings"
|
||||
#define BtnOk L"OK"
|
||||
#define HS_START_HOOK_SEARCH L"Start hook search"
|
||||
#define HS_SEARCH_PATTERN L"Search pattern (hex byte array)"
|
||||
#define HS_SEARCH_DURATION L"Search duration (ms)"
|
||||
#define HS_SEARCH_MODULE L"Search within module"
|
||||
#define HS_PATTERN_OFFSET L"Offset from pattern start"
|
||||
#define HS_MAX_HOOK_SEARCH_RECORDS L"Search result cap"
|
||||
#define HS_MIN_ADDRESS L"Minimum address (hex)"
|
||||
#define HS_MAX_ADDRESS L"Maximum address (hex)"
|
||||
#define HS_STRING_OFFSET L"String offset (hex)"
|
||||
#define HS_HOOK_SEARCH_FILTER L"Results must match this regex"
|
||||
#define HS_TEXT L"Text"
|
||||
#define HS_CODEPAGE L"Codepage"
|
||||
#define HS_SEARCH_FOR_TEXT L"Search for specific text"
|
19
Lang/zh.h
19
Lang/zh.h
@ -48,6 +48,7 @@
|
||||
#define BtnToClipboard L"复制到剪贴板"
|
||||
#define BtnReadOnly L"文本框只读"
|
||||
#define BtnInsertUserHook L"插入特殊码"
|
||||
#define BtnSearchHook L"搜索钩子"
|
||||
#define BtnPlugin L"插件"
|
||||
#define LblFlushDelay L"刷新延迟"
|
||||
#define LblFilterRepeat L"过滤重复文本"
|
||||
@ -70,4 +71,20 @@
|
||||
#define LblPluginNotify L"依赖于Qt的插件仅会在启动时载入。"
|
||||
#define LblPluginRemove L"移除插件要在重启后生效。"
|
||||
#define InvalidPlugin L"插件无效!"
|
||||
#define MsgError L"错误"
|
||||
#define MsgError L"错误"
|
||||
#define SEARCH_CJK L"搜索中文/日文/韩文"
|
||||
#define HS_SETTINGS L"设置"
|
||||
#define BtnOk L"确定"
|
||||
#define HS_START_HOOK_SEARCH L"开始搜索钩子"
|
||||
#define HS_SEARCH_PATTERN L"搜索匹配特征 (hex byte array)"
|
||||
#define HS_SEARCH_DURATION L"搜索持续时间 (ms)"
|
||||
#define HS_SEARCH_MODULE L"搜索指定模块"
|
||||
#define HS_PATTERN_OFFSET L"相对于特征地址的偏移值"
|
||||
#define HS_MAX_HOOK_SEARCH_RECORDS L"搜索结果达到上限"
|
||||
#define HS_MIN_ADDRESS L"起始地址 (hex)"
|
||||
#define HS_MAX_ADDRESS L"结束地址 (hex)"
|
||||
#define HS_STRING_OFFSET L"字符串偏移值 (hex)"
|
||||
#define HS_HOOK_SEARCH_FILTER L"结果必须匹配的正则表达式"
|
||||
#define HS_TEXT L"文本"
|
||||
#define HS_CODEPAGE L"代码页"
|
||||
#define HS_SEARCH_FOR_TEXT L"搜索指定文本"
|
@ -1,4 +1,4 @@
|
||||
add_executable(LunaHost confighelper.cpp controls.cpp main.cpp processlistwindow.cpp LunaHost.cpp window.cpp luna.rc pluginmanager.cpp Plugin/pluginexample.cpp app.manifest)
|
||||
add_executable(LunaHost WIN32 confighelper.cpp controls.cpp main.cpp processlistwindow.cpp LunaHost.cpp window.cpp luna.rc pluginmanager.cpp Plugin/pluginexample.cpp app.manifest)
|
||||
target_precompile_headers(LunaHost REUSE_FROM pch)
|
||||
set_target_properties(LunaHost PROPERTIES OUTPUT_NAME "LunaHost${bitappendix}")
|
||||
target_link_libraries(LunaHost comctl32 pch host ${YY_Thunks_for_WinXP})
|
||||
|
@ -9,6 +9,13 @@
|
||||
#include"textthread.h"
|
||||
#include"LunaHost.h"
|
||||
#include"Lang/Lang.h"
|
||||
auto gmf=[&](DWORD processId)->std::optional<std::wstring>{
|
||||
//见鬼了,GetModuleFileName找不到标识符
|
||||
std::vector<wchar_t> buffer(MAX_PATH);
|
||||
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
||||
if (GetModuleFileNameExW(process, 0, buffer.data(), MAX_PATH)) return buffer.data();
|
||||
return {};
|
||||
};
|
||||
void LunaHost::toclipboard(std::wstring& sentence){
|
||||
|
||||
for (int loop = 0; loop < 10; loop++) {
|
||||
@ -198,15 +205,6 @@ LunaHost::LunaHost(){
|
||||
case IDM_FORGET_SELECTION:
|
||||
case IDM_REMEMBER_SELECTION:
|
||||
{
|
||||
|
||||
std::vector<wchar_t> buffer(MAX_PATH);
|
||||
auto gmf=[&](DWORD processId)->std::optional<std::wstring>{
|
||||
std::vector<wchar_t> buffer(MAX_PATH);
|
||||
if (AutoHandle<> process = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, processId))
|
||||
if (GetModuleFileNameExW(process, 0, buffer.data(), MAX_PATH)) return buffer.data();
|
||||
return {};
|
||||
};
|
||||
//见鬼了,GetModuleFileName找不到标识符
|
||||
|
||||
if(auto pexe=gmf(tt->tp.processId))
|
||||
{
|
||||
@ -231,7 +229,13 @@ LunaHost::LunaHost(){
|
||||
};
|
||||
g_showtexts = new multilineedit(this);
|
||||
g_showtexts->setreadonly(true);
|
||||
|
||||
|
||||
btnsearchhooks=new button(this,BtnSearchHook);
|
||||
btnsearchhooks->onclick=[&](){
|
||||
if(hooksearchwindow==0) hooksearchwindow=new Hooksearchwindow(this);
|
||||
hooksearchwindow->show();
|
||||
};
|
||||
|
||||
Host::Start(
|
||||
std::bind(&LunaHost::on_proc_connect,this,std::placeholders::_1),
|
||||
[&](DWORD pid) {
|
||||
@ -247,8 +251,9 @@ LunaHost::LunaHost(){
|
||||
mainlayout->addcontrol(btndetachall,0,1);
|
||||
mainlayout->addcontrol(btnshowsettionwindow,0,2);
|
||||
mainlayout->addcontrol(btnplugin,0,3);
|
||||
mainlayout->addcontrol(g_hEdit_userhook,1,0,1,3);
|
||||
mainlayout->addcontrol(g_hButton_insert,1,3);
|
||||
mainlayout->addcontrol(g_hEdit_userhook,1,0,1,2);
|
||||
mainlayout->addcontrol(g_hButton_insert,1,2);
|
||||
mainlayout->addcontrol(btnsearchhooks,1,3);
|
||||
|
||||
mainlayout->addcontrol(g_hListBox_listtext,2,0,1,4);
|
||||
mainlayout->addcontrol(g_showtexts,3,0,1,4);
|
||||
@ -332,28 +337,25 @@ void LunaHost::on_thread_delete(TextThread& thread){
|
||||
Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){
|
||||
int height=30;int curry=10;int space=10;
|
||||
int labelwidth=300;int spinwidth=200;
|
||||
g_timeout = new spinbox(this,std::to_wstring(TextThread::flushDelay)) ;
|
||||
g_timeout = new spinbox(this,TextThread::flushDelay) ;
|
||||
|
||||
|
||||
g_codepage = new spinbox(this,std::to_wstring(Host::defaultCodepage)) ;
|
||||
g_codepage = new spinbox(this,Host::defaultCodepage) ;
|
||||
|
||||
|
||||
spinmaxbuffsize = new spinbox(this,std::to_wstring(TextThread::maxBufferSize)) ;
|
||||
spinmaxbuffsize = new spinbox(this,TextThread::maxBufferSize);
|
||||
;curry+=height+space;
|
||||
|
||||
spinmaxbuffsize->onvaluechange=[=](int v){
|
||||
TextThread::maxBufferSize=v;
|
||||
};
|
||||
spinmaxbuffsize->setminmax(0,0x7fffffff);
|
||||
|
||||
|
||||
spinmaxhistsize = new spinbox(this,std::to_wstring(TextThread::maxHistorySize)) ;
|
||||
spinmaxhistsize = new spinbox(this,TextThread::maxHistorySize) ;
|
||||
;curry+=height+space;
|
||||
|
||||
spinmaxhistsize->onvaluechange=[=](int v){
|
||||
TextThread::maxHistorySize=v;
|
||||
};
|
||||
spinmaxhistsize->setminmax(0,0x7fffffff);
|
||||
|
||||
ckbfilterrepeat=new checkbox(this,LblFilterRepeat);
|
||||
ckbfilterrepeat->onclick=[=](){
|
||||
@ -389,7 +391,7 @@ Settingwindow::Settingwindow(LunaHost* host):mainwindow(host){
|
||||
g_timeout->onvaluechange=[=](int v){
|
||||
TextThread::flushDelay=v;
|
||||
};
|
||||
g_timeout->setminmax(0,9999);
|
||||
|
||||
g_codepage->onvaluechange=[=](int v){
|
||||
if(IsValidCodePage(v)){
|
||||
Host::defaultCodepage= v;
|
||||
@ -496,4 +498,223 @@ Pluginwindow::Pluginwindow(mainwindow*p,Pluginmanager* pl):mainwindow(p){
|
||||
}
|
||||
settext(WndPlugins);
|
||||
setcentral(500,400);
|
||||
}
|
||||
|
||||
void HooksearchText::call(std::set<DWORD>pids){
|
||||
edittext->settext(L"");
|
||||
checkok->onclick=[&,pids](){
|
||||
close();
|
||||
auto cp=codepage->getcurr();
|
||||
if(!IsValidCodePage(cp)) return;
|
||||
SearchParam sp = {};
|
||||
sp.codepage=cp;
|
||||
wcsncpy_s(sp.text, edittext->text().c_str(), PATTERN_SIZE - 1);
|
||||
wprintf(sp.text);
|
||||
for(auto pid:pids)
|
||||
Host::FindHooks(pid, sp);
|
||||
};
|
||||
show();
|
||||
}
|
||||
HooksearchText::HooksearchText(mainwindow* p):mainwindow(p){
|
||||
codepage=new spinbox(this,Host::defaultCodepage);
|
||||
codepage->setminmax(0,CP_UTF8);
|
||||
|
||||
edittext=new lineedit(this);
|
||||
checkok=new button(this,BtnOk);
|
||||
layout=new gridlayout();
|
||||
layout->addcontrol(new label(this,HS_TEXT),0,0);
|
||||
layout->addcontrol(new label(this,HS_CODEPAGE),1,0);
|
||||
layout->addcontrol(edittext,0,1);
|
||||
layout->addcontrol(codepage,1,1);
|
||||
layout->addcontrol(checkok,2,1);
|
||||
|
||||
setlayout(layout);
|
||||
setcentral(500,200);
|
||||
|
||||
}
|
||||
std::wstring tohex(BYTE* bs,int len){
|
||||
std::wstring buffer;
|
||||
for (int i = 0; i < len; i += 1){
|
||||
buffer.append(FormatString(L"%02hX ", bs[i]));
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
std::wstring addr2hex(uintptr_t addr){
|
||||
return FormatString(L"%p",addr);
|
||||
}
|
||||
void realcallsearchhooks(std::set<DWORD>pids,std::wstring filter,SearchParam sp){
|
||||
|
||||
auto hooks = std::make_shared<std::vector<std::wstring>>();
|
||||
|
||||
try
|
||||
{
|
||||
for(auto processId:pids)
|
||||
Host::FindHooks(processId, sp,
|
||||
[hooks, filter](HookParam hp, std::wstring text)
|
||||
{
|
||||
std::wsmatch matches;
|
||||
if (std::regex_search(text, matches, std::wregex(filter))) {
|
||||
hooks->emplace_back(std::wstring(hp.hookcode)+L"=>"+text);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (std::exception &e) {
|
||||
//std::wcout<<e.what();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
std::thread([hooks]
|
||||
{
|
||||
for (int lastSize = 0; hooks->size() == 0 || hooks->size() != lastSize; Sleep(2000)) lastSize = hooks->size();
|
||||
|
||||
std::ofstream of;
|
||||
of.open("savehooks.txt");
|
||||
for (auto line:*hooks) of<<WideStringToString(line)<<"\n";
|
||||
of.close();
|
||||
hooks->clear();
|
||||
}).detach();
|
||||
}
|
||||
Hooksearchsetting::Hooksearchsetting(mainwindow* p):mainwindow(p){
|
||||
layout=new gridlayout();
|
||||
SearchParam sp{};
|
||||
spinduration=new spinbox(this,sp.searchTime);
|
||||
spinoffset=new spinbox(this,sp.offset);
|
||||
spincap=new spinbox(this,sp.maxRecords);
|
||||
spincodepage=new spinbox(this,Host::defaultCodepage);
|
||||
editpattern=new lineedit(this);
|
||||
editpattern->settext(tohex(sp.pattern,sp.length));
|
||||
editmodule=new lineedit(this);
|
||||
editmaxaddr=new lineedit(this);
|
||||
editmaxaddr->settext(addr2hex(sp.maxAddress));
|
||||
editminaddr=new lineedit(this);
|
||||
editminaddr->settext(addr2hex(sp.minAddress));
|
||||
spinpadding=new spinbox(this,0);
|
||||
editregex=new lineedit(this);
|
||||
start=new button(this,HS_START_HOOK_SEARCH);
|
||||
layout->addcontrol(new label(this,HS_SEARCH_PATTERN),0,0);
|
||||
layout->addcontrol(new label(this,HS_SEARCH_DURATION),1,0);
|
||||
layout->addcontrol(new label(this,HS_PATTERN_OFFSET),2,0);
|
||||
layout->addcontrol(new label(this,HS_MAX_HOOK_SEARCH_RECORDS),3,0);
|
||||
layout->addcontrol(new label(this,HS_CODEPAGE),4,0);
|
||||
layout->addcontrol(new label(this,HS_SEARCH_MODULE),5,0);
|
||||
layout->addcontrol(new label(this,HS_MIN_ADDRESS),6,0);
|
||||
layout->addcontrol(new label(this,HS_MAX_ADDRESS),7,0);
|
||||
layout->addcontrol(new label(this,HS_STRING_OFFSET),8,0);
|
||||
layout->addcontrol(new label(this,HS_HOOK_SEARCH_FILTER),9,0);
|
||||
layout->addcontrol(start,10,1);
|
||||
|
||||
layout->addcontrol(editpattern,0,1);
|
||||
layout->addcontrol(spinduration,1,1);
|
||||
layout->addcontrol(spinoffset,2,1);
|
||||
layout->addcontrol(spincap,3,1);
|
||||
layout->addcontrol(spincodepage,4,1);
|
||||
layout->addcontrol(editmodule,5,1);
|
||||
layout->addcontrol(editminaddr,6,1);
|
||||
layout->addcontrol(editmaxaddr,7,1);
|
||||
layout->addcontrol(spinpadding,8,1);
|
||||
layout->addcontrol(editregex,9,1);
|
||||
|
||||
setlayout(layout);
|
||||
setcentral(1000,600);
|
||||
}
|
||||
std::vector<BYTE> hexStringToBytes(const std::wstring& hexString_) {
|
||||
auto hexString=hexString_;
|
||||
strReplace(hexString,L" ",L"");
|
||||
strReplace(hexString,L"??",FormatString(L"%02hX",XX));
|
||||
std::vector<BYTE> bytes;
|
||||
if (hexString.length() % 2 != 0) {
|
||||
return {};
|
||||
}
|
||||
for (int i = 0; i < hexString.size() / 2; i++) {
|
||||
auto byteValue = std::stoi(hexString.substr(i*2,2), nullptr, 16);
|
||||
bytes.push_back(byteValue);
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
void Hooksearchsetting::call(std::set<DWORD>pids,std::wstring reg){
|
||||
if(pids.empty())return;
|
||||
|
||||
if(auto filename=gmf(*pids.begin()))
|
||||
editmodule->settext(std::filesystem::path(filename.value()).filename().wstring());
|
||||
editregex->settext(reg);
|
||||
spincodepage->setcurr(Host::defaultCodepage);
|
||||
|
||||
start->onclick=[&,pids](){
|
||||
close();
|
||||
SearchParam sp{};
|
||||
sp.searchTime=spinduration->getcurr();
|
||||
sp.offset=spinoffset->getcurr();
|
||||
sp.maxRecords=spincap->getcurr();
|
||||
sp.codepage=spincodepage->getcurr();
|
||||
|
||||
if(editpattern->text().find(L".")==std::wstring::npos){
|
||||
auto hex=hexStringToBytes(editpattern->text());
|
||||
memcpy(sp.pattern,hex.data(),hex.size());
|
||||
sp.length=hex.size();
|
||||
}
|
||||
else{
|
||||
wcsncpy_s(sp.exportModule, editpattern->text().c_str(), MAX_MODULE_SIZE - 1);
|
||||
sp.length = 1;
|
||||
}
|
||||
|
||||
wcscpy(sp.boundaryModule,editmodule->text().c_str());
|
||||
sp.minAddress=std::stoll(editminaddr->text(), nullptr, 16);
|
||||
sp.maxAddress=std::stoll(editmaxaddr->text(), nullptr, 16);
|
||||
sp.padding=spinpadding->getcurr();
|
||||
realcallsearchhooks(pids,editregex->text(),sp);
|
||||
};
|
||||
show();
|
||||
}
|
||||
Hooksearchwindow::Hooksearchwindow(LunaHost* host):mainwindow(host){
|
||||
|
||||
cjkcheck=new checkbox(this,SEARCH_CJK);
|
||||
hs_default=new button(this,HS_SEARCH_FOR_TEXT);
|
||||
hs_text=new button(this,HS_SEARCH_FOR_TEXT);
|
||||
hs_user=new button(this,HS_SETTINGS);
|
||||
|
||||
layout=new gridlayout();
|
||||
layout->addcontrol(cjkcheck,0,0,1,3);
|
||||
layout->addcontrol(hs_default,1,0);
|
||||
layout->addcontrol(hs_text,1,1);
|
||||
layout->addcontrol(hs_user,1,2);
|
||||
|
||||
setlayout(layout);
|
||||
|
||||
settext(BtnSearchHook);
|
||||
setcentral(800,200);
|
||||
|
||||
auto dohooksearchdispatch=[&,host](int type)
|
||||
{
|
||||
close();
|
||||
if(type==1)
|
||||
{
|
||||
if(hooksearchText==0) hooksearchText=new HooksearchText(this);
|
||||
hooksearchText->call(host->attachedprocess);
|
||||
return;
|
||||
}
|
||||
|
||||
auto filter=(cjkcheck->ischecked()?L"[\\u3000-\\ua000]{4,}" : L"[\\u0020-\\u1000]{4,}");
|
||||
|
||||
|
||||
if(type==0)
|
||||
{
|
||||
SearchParam sp = {};
|
||||
sp.codepage = Host::defaultCodepage;
|
||||
sp.length = 0;
|
||||
realcallsearchhooks(host->attachedprocess,filter,sp);
|
||||
}
|
||||
else if(type==2)
|
||||
{
|
||||
if(hooksearchsetting==0) hooksearchsetting=new Hooksearchsetting(this);
|
||||
hooksearchsetting->call(host->attachedprocess,filter);
|
||||
return;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
hs_default->onclick=std::bind(dohooksearchdispatch,0);
|
||||
hs_text->onclick=std::bind(dohooksearchdispatch,1);
|
||||
hs_user->onclick=std::bind(dohooksearchdispatch,2);
|
||||
}
|
@ -38,11 +38,45 @@ public:
|
||||
processlistwindow(mainwindow* parent=0);
|
||||
void on_show();
|
||||
};
|
||||
|
||||
class HooksearchText:public mainwindow{
|
||||
gridlayout* layout;
|
||||
lineedit* edittext;
|
||||
button* checkok;
|
||||
spinbox* codepage;
|
||||
public:
|
||||
HooksearchText(mainwindow*);
|
||||
void call(std::set<DWORD>pids);
|
||||
};
|
||||
class Hooksearchsetting:public mainwindow{
|
||||
gridlayout* layout;
|
||||
spinbox* spinduration;
|
||||
spinbox* spinoffset;
|
||||
spinbox* spincap;
|
||||
spinbox* spincodepage;
|
||||
lineedit* editpattern;
|
||||
lineedit* editmodule;
|
||||
lineedit* editmaxaddr;
|
||||
lineedit* editminaddr;
|
||||
spinbox* spinpadding;
|
||||
lineedit* editregex;
|
||||
button* start;
|
||||
public:
|
||||
Hooksearchsetting(mainwindow*);
|
||||
void call(std::set<DWORD>pids,std::wstring);
|
||||
};
|
||||
class Hooksearchwindow:public mainwindow{
|
||||
checkbox* cjkcheck;
|
||||
button* hs_default,*hs_text,*hs_user;
|
||||
gridlayout* layout;
|
||||
Hooksearchsetting* hooksearchsetting=0;
|
||||
HooksearchText* hooksearchText=0;
|
||||
public:
|
||||
Hooksearchwindow(LunaHost* parent);
|
||||
};
|
||||
class LunaHost:public mainwindow{
|
||||
Pluginwindow* pluginwindow=0;
|
||||
std::map<int64_t,std::vector<std::wstring>>savetext;
|
||||
std::set<int>attachedprocess;
|
||||
std::set<DWORD>attachedprocess;
|
||||
std::mutex settextmutex;
|
||||
lineedit* g_hEdit_userhook;
|
||||
gridlayout* mainlayout;
|
||||
@ -52,12 +86,14 @@ class LunaHost:public mainwindow{
|
||||
multilineedit* g_showtexts;
|
||||
button* g_selectprocessbutton;
|
||||
button* btndetachall;
|
||||
button* btnsearchhooks;
|
||||
button* btnshowsettionwindow;
|
||||
//button* btnsavehook;
|
||||
void toclipboard(std::wstring& sentence);
|
||||
processlistwindow *_processlistwindow=0;
|
||||
Settingwindow *settingwindow=0;
|
||||
Pluginmanager* plugins;
|
||||
Hooksearchwindow * hooksearchwindow=0;
|
||||
bool on_text_recv(TextThread& thread, std::wstring& sentence);
|
||||
void on_text_recv_checkissaved(TextThread& thread);
|
||||
void on_thread_create(TextThread& thread);
|
||||
@ -76,7 +112,7 @@ public:
|
||||
void on_close();
|
||||
LunaHost();
|
||||
friend class Settingwindow;
|
||||
friend class processlistwindow;
|
||||
friend class Hooksearchwindow;
|
||||
private:
|
||||
void loadsettings();
|
||||
void savesettings();
|
||||
|
@ -30,8 +30,11 @@ checkbox::checkbox(mainwindow* parent,const std::wstring& text):button(parent)
|
||||
void checkbox::setcheck(bool b){
|
||||
SendMessage(winId, BM_SETCHECK, (WPARAM)BST_CHECKED*b, 0);
|
||||
}
|
||||
spinbox::spinbox(mainwindow* parent,const std::wstring& text):control(parent){
|
||||
winId=CreateWindowEx(0, L"EDIT", text.c_str(), WS_CHILD | WS_VISIBLE | WS_BORDER|ES_NUMBER ,
|
||||
int spinbox::getcurr(){
|
||||
return SendMessage(hUpDown, UDM_GETPOS32, 0, 0);
|
||||
}
|
||||
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);
|
||||
|
||||
hUpDown = CreateWindowEx(0, UPDOWN_CLASS, NULL,
|
||||
@ -39,6 +42,7 @@ spinbox::spinbox(mainwindow* parent,const std::wstring& text):control(parent){
|
||||
0, 0, 0, 0,
|
||||
parent->winId, NULL, NULL, NULL);
|
||||
SendMessage(hUpDown, UDM_SETBUDDY, (WPARAM)winId, 0);
|
||||
setminmax(0,0x7fffffff);
|
||||
std::tie(minv,maxv)= getminmax();
|
||||
}
|
||||
void spinbox::setgeo(int x,int y,int w,int h)
|
||||
|
@ -47,10 +47,11 @@ class spinbox:public control{
|
||||
int minv,maxv;
|
||||
public:
|
||||
void dispatch(WPARAM);
|
||||
spinbox(mainwindow*,const std::wstring&);
|
||||
spinbox(mainwindow*,int);
|
||||
void setminmax(int,int);
|
||||
std::pair<int,int>getminmax();
|
||||
void setcurr(int);
|
||||
int getcurr();
|
||||
std::function<void(int)> onvaluechange=[&](int){};
|
||||
void setgeo(int,int,int,int);
|
||||
};
|
||||
|
@ -177,6 +177,6 @@ std::optional<std::wstring> commonparsestring(void* data,size_t length,void* php
|
||||
auto hp=(HookParam*)php;
|
||||
if (hp->type & CODEC_UTF16) return std::wstring((wchar_t*)data, length / sizeof(wchar_t));
|
||||
else if(hp->type&CODEC_UTF32)return (std::move(utf32_to_utf16(data,length)));
|
||||
else if (auto converted = StringToWideString(std::string((char*)data, length), hp->codepage ? hp->codepage : ((hp->type&CODEC_UTF8)?CP_UTF8:df))) return (converted.value());
|
||||
else if (auto converted = StringToWideString(std::string((char*)data, length), (hp->type&CODEC_UTF8)?CP_UTF8:(hp->codepage ? hp->codepage :df))) return (converted.value());
|
||||
else return {};
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user