diff --git a/GUI/CMakeLists.txt b/GUI/CMakeLists.txt index 25048a7..26a8076 100644 --- a/GUI/CMakeLists.txt +++ b/GUI/CMakeLists.txt @@ -10,6 +10,7 @@ set(gui_SRCS mainwindow.cpp misc.cpp extenwindow.cpp + setdialog.cpp tests.cpp host/host.cc host/textthread.cc diff --git a/GUI/host/host.cc b/GUI/host/host.cc index 27da486..2e20389 100644 --- a/GUI/host/host.cc +++ b/GUI/host/host.cc @@ -5,7 +5,6 @@ #include "host.h" #include "const.h" #include "defs.h" -#include "text.h" #include "../vnrhook/hijack/texthook.h" namespace diff --git a/GUI/host/host.h b/GUI/host/host.h index 27dd65d..43994e8 100644 --- a/GUI/host/host.h +++ b/GUI/host/host.h @@ -6,6 +6,7 @@ #include "common.h" #include "textthread.h" +#include "text.h" typedef std::function ProcessEventCallback; typedef std::function)> ThreadEventCallback; @@ -30,12 +31,19 @@ namespace Host void AddConsoleOutput(std::wstring text); } -inline UINT CURRENT_CODEPAGE = SHIFT_JIS; -inline std::wstring StringToWideString(const std::string& text, UINT encoding = CURRENT_CODEPAGE) +inline std::wstring StringToWideString(const std::string& text, UINT encoding = CP_UTF8) { std::wstring ret(text.size() + 1, 0); - ret.resize(MultiByteToWideChar(encoding, 0, text.c_str(), -1, ret.data(), ret.capacity()) - 1); - return ret; + if (int len = MultiByteToWideChar(encoding, 0, text.c_str(), -1, ret.data(), ret.capacity())) + { + ret.resize(len - 1); + return ret; + } + else + { + Host::AddConsoleOutput(INVALID_CODEPAGE); + return L""; + } } // EOF diff --git a/GUI/host/textthread.cc b/GUI/host/textthread.cc index c235134..c095892 100644 --- a/GUI/host/textthread.cc +++ b/GUI/host/textthread.cc @@ -37,7 +37,7 @@ void TextThread::Push(const BYTE* data, int len) LOCK(threadMutex); buffer += hp.type & USING_UNICODE ? std::wstring((wchar_t*)data, len / 2) - : StringToWideString(std::string((char*)data, len), hp.codepage != 0 ? hp.codepage : CURRENT_CODEPAGE); + : StringToWideString(std::string((char*)data, len), hp.codepage != 0 ? hp.codepage : defaultCodepage); if (std::all_of(buffer.begin(), buffer.end(), [&](wchar_t c) { return repeatingChars.count(c) > 0; })) buffer.clear(); lastPushTime = GetTickCount(); } diff --git a/GUI/host/textthread.h b/GUI/host/textthread.h index 67e18ae..dcfb86d 100644 --- a/GUI/host/textthread.h +++ b/GUI/host/textthread.h @@ -16,6 +16,7 @@ public: inline static int flushDelay = 400; // flush every 400ms by default inline static int maxBufferSize = 1000; + inline static int defaultCodepage = SHIFT_JIS; inline static int threadCounter = 0; TextThread(ThreadParam tp, HookParam hp, std::wstring name); diff --git a/GUI/mainwindow.cpp b/GUI/mainwindow.cpp index a352158..dcdff4c 100644 --- a/GUI/mainwindow.cpp +++ b/GUI/mainwindow.cpp @@ -2,6 +2,7 @@ #include "ui_mainwindow.h" #include "text.h" #include "extenwindow.h" +#include "setdialog.h" #include "misc.h" #include @@ -16,11 +17,10 @@ MainWindow::MainWindow(QWidget *parent) : ttCombo = findChild("ttCombo"); textOutput = findChild("textOutput"); - if (settings.contains(WINDOW)) this->setGeometry(settings.value(WINDOW).toRect()); - // TODO: add GUI for changing these - if (settings.contains(DEFAULT_CODEPAGE)) CURRENT_CODEPAGE = settings.value(DEFAULT_CODEPAGE).toInt(); + if (settings.contains(WINDOW)) setGeometry(settings.value(WINDOW).toRect()); if (settings.contains(FLUSH_DELAY)) TextThread::flushDelay = settings.value(FLUSH_DELAY).toInt(); if (settings.contains(MAX_BUFFER_SIZE)) TextThread::maxBufferSize = settings.value(MAX_BUFFER_SIZE).toInt(); + if (settings.contains(DEFAULT_CODEPAGE)) TextThread::defaultCodepage = settings.value(DEFAULT_CODEPAGE).toInt(); qRegisterMetaType>(); @@ -42,13 +42,9 @@ MainWindow::MainWindow(QWidget *parent) : MainWindow::~MainWindow() { - settings.setValue(WINDOW, this->geometry()); - settings.setValue(DEFAULT_CODEPAGE, CURRENT_CODEPAGE); - settings.setValue(FLUSH_DELAY, TextThread::flushDelay); - settings.setValue(MAX_BUFFER_SIZE, TextThread::maxBufferSize); + settings.setValue(WINDOW, geometry()); settings.sync(); delete ui; - Host::Close(); } @@ -228,6 +224,11 @@ void MainWindow::on_saveButton_clicked() file.write((hookList + "\r\n").toUtf8()); } +void MainWindow::on_setButton_clicked() +{ + SetDialog(this).exec(); +} + void MainWindow::on_extenButton_clicked() { extenWindow->activateWindow(); diff --git a/GUI/mainwindow.h b/GUI/mainwindow.h index 2b02158..7d60633 100644 --- a/GUI/mainwindow.h +++ b/GUI/mainwindow.h @@ -41,6 +41,7 @@ private slots: void on_unhookButton_clicked(); void on_hookButton_clicked(); void on_saveButton_clicked(); + void on_setButton_clicked(); void on_extenButton_clicked(); void on_ttCombo_activated(int index); diff --git a/GUI/mainwindow.ui b/GUI/mainwindow.ui index 6aee2a2..3fcfbe1 100644 --- a/GUI/mainwindow.ui +++ b/GUI/mainwindow.ui @@ -101,6 +101,13 @@ + + + + Settings + + + diff --git a/GUI/qtcommon.h b/GUI/qtcommon.h index cdc2efe..4aa443b 100644 --- a/GUI/qtcommon.h +++ b/GUI/qtcommon.h @@ -5,5 +5,6 @@ #include #include #include +#include #include #include diff --git a/GUI/setdialog.cpp b/GUI/setdialog.cpp new file mode 100644 index 0000000..d86ae14 --- /dev/null +++ b/GUI/setdialog.cpp @@ -0,0 +1,40 @@ +#include "setdialog.h" +#include "ui_setdialog.h" +#include "defs.h" +#include "host/host.h" +#include + +SetDialog::SetDialog(QWidget* parent) : + QDialog(parent, Qt::WindowCloseButtonHint), + ui(new Ui::SetDialog) +{ + ui->setupUi(this); + + QFormLayout* layout = findChild("layout"); + + auto addSpinBox = [&](QString label, int value) + { + auto spinbox = new QSpinBox(this); + spinbox->setMaximum(INT_MAX); + spinbox->setValue(value); + layout->insertRow(0, label, spinbox); + return spinbox; + }; + flushDelay = addSpinBox(FLUSH_DELAY, TextThread::flushDelay); + maxBufferSize = addSpinBox(MAX_BUFFER_SIZE, TextThread::maxBufferSize); + defaultCodepage = addSpinBox(DEFAULT_CODEPAGE, TextThread::defaultCodepage); +} + +SetDialog::~SetDialog() +{ + delete ui; +} + +void SetDialog::on_buttonBox_accepted() +{ + QSettings settings(CONFIG_FILE, QSettings::IniFormat); + settings.setValue(FLUSH_DELAY, TextThread::flushDelay = flushDelay->value()); + settings.setValue(MAX_BUFFER_SIZE, TextThread::maxBufferSize = maxBufferSize->value()); + settings.setValue(DEFAULT_CODEPAGE, TextThread::defaultCodepage = defaultCodepage->value()); + settings.sync(); +} \ No newline at end of file diff --git a/GUI/setdialog.h b/GUI/setdialog.h new file mode 100644 index 0000000..ae7937c --- /dev/null +++ b/GUI/setdialog.h @@ -0,0 +1,30 @@ +#ifndef SETDIALOG_H +#define SETDIALOG_H + +#include "qtcommon.h" +#include + +namespace Ui +{ + class SetDialog; +} + +class SetDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SetDialog(QWidget* parent = nullptr); + ~SetDialog(); + +private slots: + void on_buttonBox_accepted(); + +private: + Ui::SetDialog* ui; + QSpinBox* flushDelay; + QSpinBox* maxBufferSize; + QSpinBox* defaultCodepage; +}; + +#endif // SETDIALOG_H diff --git a/GUI/setdialog.ui b/GUI/setdialog.ui new file mode 100644 index 0000000..f7cd03f --- /dev/null +++ b/GUI/setdialog.ui @@ -0,0 +1,44 @@ + + + SetDialog + + + + 0 + 0 + 300 + 120 + + + + Settings + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + SetDialog + accept() + + + buttonBox + rejected() + SetDialog + reject() + + + diff --git a/include/defs.h b/include/defs.h index 193d9c2..fe34324 100644 --- a/include/defs.h +++ b/include/defs.h @@ -27,8 +27,8 @@ constexpr auto EXTEN_SAVE_FILE = u8"Extensions.txt"; // Settings constexpr auto WINDOW = u8"Window"; -constexpr auto DEFAULT_CODEPAGE = u8"Default_Codepage"; -constexpr auto FLUSH_DELAY = u8"Flush_Delay"; -constexpr auto MAX_BUFFER_SIZE = u8"Max_Buffer_Size"; +constexpr auto DEFAULT_CODEPAGE = u8"Default Codepage"; +constexpr auto FLUSH_DELAY = u8"Flush Delay"; +constexpr auto MAX_BUFFER_SIZE = u8"Max Buffer Size"; // EOF diff --git a/include/text.h b/include/text.h index ef4f00d..ac9afe1 100644 --- a/include/text.h +++ b/include/text.h @@ -28,3 +28,4 @@ constexpr auto ARCHITECTURE_MISMATCH = L"Textractor: ERROR: architecture mismatc constexpr auto INJECT_FAILED = L"Textractor: ERROR: couldn't inject"; constexpr auto INVALID_CODE = L"Textractor: invalid code"; constexpr auto NO_HOOKS = L"Textractor: no hooks detected"; +constexpr auto INVALID_CODEPAGE = L"Textractor: ERROR: couldn't convert text (invalid codepage?)";