refactor and perf improvements
This commit is contained in:
parent
6bac544c89
commit
f1d46e9f73
@ -70,6 +70,14 @@ bool DispatchSentenceToExtensions(std::wstring& sentence, const InfoForExtension
|
||||
return !sentence.empty();
|
||||
}
|
||||
|
||||
void CleanupExtensions()
|
||||
{
|
||||
std::scoped_lock writeLock(extenMutex);
|
||||
for (auto extension : extensions)
|
||||
FreeLibrary(GetModuleHandleW(extension.name.c_str()));
|
||||
extensions.clear();
|
||||
}
|
||||
|
||||
ExtenWindow::ExtenWindow(QWidget* parent) :
|
||||
QMainWindow(parent, Qt::WindowCloseButtonHint),
|
||||
ui(new Ui::ExtenWindow)
|
||||
|
@ -14,6 +14,7 @@ struct InfoForExtension
|
||||
};
|
||||
|
||||
bool DispatchSentenceToExtensions(std::wstring& sentence, const InfoForExtension* miscInfo);
|
||||
void CleanupExtensions(); // must call this before exiting the program, only way to uphold guarantee that DllMain and OnNewSentence won't be called concurrently
|
||||
|
||||
class ExtenWindow : public QMainWindow
|
||||
{
|
||||
|
@ -134,6 +134,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
QSettings(CONFIG_FILE, QSettings::IniFormat).setValue(WINDOW, geometry());
|
||||
CleanupExtensions();
|
||||
SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
||||
ExitProcess(0);
|
||||
}
|
||||
@ -177,7 +178,7 @@ void MainWindow::ThreadAdded(TextThread& thread)
|
||||
{
|
||||
std::wstring threadCode = Util::GenerateCode(thread.hp, thread.tp.processId);
|
||||
QString ttString = TextThreadString(thread) + S(thread.name) + " (" + S(threadCode) + ")";
|
||||
bool savedMatch = savedThreadCtx.first == thread.tp.ctx && savedThreadCtx.second == thread.tp.ctx2 && savedThreadCode == threadCode;
|
||||
bool savedMatch = savedThreadCtx == std::pair(thread.tp.ctx, thread.tp.ctx2) && savedThreadCode == threadCode;
|
||||
if (savedMatch) savedThreadCtx.first = savedThreadCtx.second = savedThreadCode[0] = 0;
|
||||
QMetaObject::invokeMethod(this, [this, ttString, savedMatch]
|
||||
{
|
||||
@ -236,9 +237,9 @@ std::array<InfoForExtension, 10> MainWindow::GetMiscInfo(TextThread& thread)
|
||||
{
|
||||
void(*AddSentence)(MainWindow*, int64_t, const wchar_t*) = [](MainWindow* This, int64_t number, const wchar_t* sentence)
|
||||
{
|
||||
std::wstring sentenceStr = sentence;
|
||||
std::wstring copy = sentence;
|
||||
// pointer from Host::GetThread may not stay valid unless on main thread
|
||||
QMetaObject::invokeMethod(This, [=]() mutable { if (TextThread* thread = Host::GetThread(number)) thread->AddSentence(std::move(sentenceStr)); });
|
||||
QMetaObject::invokeMethod(This, [=]() mutable { if (TextThread* thread = Host::GetThread(number)) thread->AddSentence(std::move(copy)); });
|
||||
};
|
||||
|
||||
return
|
||||
@ -394,7 +395,7 @@ void MainWindow::FindHooks()
|
||||
connect(&confirm, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
|
||||
connect(&confirm, &QDialogButtonBox::helpRequested, &dialog, &QDialog::accept);
|
||||
dialog.setWindowTitle(SEARCH_FOR_HOOKS);
|
||||
if (dialog.exec() == QDialog::Rejected) return;
|
||||
if (!dialog.exec()) return;
|
||||
|
||||
if (customSettings)
|
||||
{
|
||||
@ -432,7 +433,7 @@ void MainWindow::FindHooks()
|
||||
QPushButton startButton(START_HOOK_SEARCH, &dialog);
|
||||
layout.addWidget(&startButton);
|
||||
connect(&startButton, &QPushButton::clicked, &dialog, &QDialog::accept);
|
||||
if (dialog.exec() == QDialog::Rejected) return;
|
||||
if (!dialog.exec()) return;
|
||||
QByteArray pattern = QByteArray::fromHex(patternInput.text().replace("??", QString::number(XX, 16)).toUtf8());
|
||||
memcpy(sp.pattern, pattern.data(), sp.length = min(pattern.size(), 25));
|
||||
try { filter = std::wregex(S(filterInput.text())); } catch (std::regex_error) {};
|
||||
|
@ -1,12 +1,10 @@
|
||||
#include "extension.h"
|
||||
#include "ui_extrawindow.h"
|
||||
#include "defs.h"
|
||||
#include <QDialog>
|
||||
#include <QInputDialog>
|
||||
#include <QColorDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QMenu>
|
||||
#include <QLayout>
|
||||
#include <QLabel>
|
||||
#include <QFormLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
@ -14,7 +12,6 @@
|
||||
#include <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include <QSettings>
|
||||
#include <QTimer>
|
||||
|
||||
extern const char* EXTRA_WINDOW_INFO;
|
||||
extern const char* TOPMOST;
|
||||
@ -29,117 +26,117 @@ extern const char* FONT_FAMILY;
|
||||
extern const char* FONT_WEIGHT;
|
||||
extern const char* SAVE_SETTINGS;
|
||||
|
||||
std::mutex m;
|
||||
|
||||
struct : QDialog
|
||||
struct Window : QDialog
|
||||
{
|
||||
public:
|
||||
void launch()
|
||||
Window()
|
||||
{
|
||||
settings->beginGroup("Extra Window");
|
||||
(new QHBoxLayout(this))->addWidget(display = new QLabel(EXTRA_WINDOW_INFO, this));
|
||||
display->setTextFormat(Qt::PlainText);
|
||||
display->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
||||
display->setAlignment(Qt::AlignTop);
|
||||
display->setWordWrap(true);
|
||||
display->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
|
||||
ui.setupUi(this);
|
||||
|
||||
settings.beginGroup("Extra Window");
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
setSizeGripEnabled(true);
|
||||
resize(400, 300);
|
||||
show();
|
||||
QMetaObject::invokeMethod(this, [this]
|
||||
{
|
||||
show();
|
||||
|
||||
auto setBackgroundColor = [=](QColor color)
|
||||
{
|
||||
if (!color.isValid()) return;
|
||||
if (color.alpha() == 0) color.setAlpha(1);
|
||||
bgColor = color;
|
||||
repaint();
|
||||
settings->setValue(BG_COLOR, color);
|
||||
};
|
||||
auto setTextColor = [=](QColor color)
|
||||
{
|
||||
if (!color.isValid()) return;
|
||||
auto newPalette = display->palette();
|
||||
newPalette.setColor(QPalette::WindowText, color);
|
||||
display->setPalette(newPalette);
|
||||
settings->setValue(TEXT_COLOR, color);
|
||||
};
|
||||
auto requestFont = [=]
|
||||
{
|
||||
QFont font = display->font();
|
||||
auto fontDialog = new QDialog(this, Qt::WindowCloseButtonHint);
|
||||
fontDialog->setAttribute(Qt::WA_DeleteOnClose);
|
||||
fontDialog->setWindowTitle(FONT);
|
||||
auto layout = new QFormLayout(fontDialog);
|
||||
fontDialog->setLayout(layout);
|
||||
auto fontFamily = new QLineEdit(font.family(), fontDialog);
|
||||
layout->addRow(FONT_FAMILY, fontFamily);
|
||||
auto fontSize = new QSpinBox(fontDialog);
|
||||
fontSize->setValue(font.pointSize());
|
||||
layout->addRow(FONT_SIZE, fontSize);
|
||||
auto fontWeight = new QSpinBox(fontDialog);
|
||||
fontWeight->setValue(font.weight());
|
||||
layout->addRow(FONT_WEIGHT, fontWeight);
|
||||
auto save = new QPushButton(SAVE_SETTINGS, fontDialog);
|
||||
layout->addWidget(save);
|
||||
connect(save, &QPushButton::clicked, fontDialog, &QDialog::accept);
|
||||
fontDialog->open();
|
||||
connect(fontDialog, &QDialog::accepted, [=]
|
||||
QFont font = ui.display->font();
|
||||
if (font.fromString(settings.value(FONT, font.toString()).toString())) ui.display->setFont(font);
|
||||
setBackgroundColor(settings.value(BG_COLOR, palette().window().color()).value<QColor>());
|
||||
setTextColor(settings.value(TEXT_COLOR, ui.display->palette().windowText().color()).value<QColor>());
|
||||
setLock(settings.value(SIZE_LOCK, false).toBool());
|
||||
setTopmost(settings.value(TOPMOST, false).toBool());
|
||||
setGeometry(settings.value(WINDOW, geometry()).toRect());
|
||||
|
||||
menu.addAction(FONT, this, &Window::RequestFont);
|
||||
menu.addAction(BG_COLOR, [this] { setBackgroundColor(QColorDialog::getColor(bgColor, this, BG_COLOR, QColorDialog::ShowAlphaChannel)); });
|
||||
menu.addAction(TEXT_COLOR, [this] { setTextColor(QColorDialog::getColor(ui.display->palette().windowText().color(), this, TEXT_COLOR, QColorDialog::ShowAlphaChannel)); });
|
||||
for (auto [name, default, slot] : Array<std::tuple<const char*, bool, void(Window::*)(bool)>>{
|
||||
{ TOPMOST, false, &Window::setTopmost },
|
||||
{ SIZE_LOCK, false, &Window::setLock },
|
||||
{ SHOW_ORIGINAL, true, &Window::setShowOriginal }
|
||||
})
|
||||
{
|
||||
QFont font(fontFamily->text(), fontSize->value(), fontWeight->value());
|
||||
settings->setValue(FONT, font.toString());
|
||||
display->setFont(font);
|
||||
});
|
||||
};
|
||||
auto setTopmost = [=](bool topmost)
|
||||
{
|
||||
SetWindowPos((HWND)winId(), topmost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
settings->setValue(TOPMOST, topmost);
|
||||
};
|
||||
auto setLock = [=](bool lock)
|
||||
{
|
||||
locked = lock;
|
||||
setSizeGripEnabled(!lock);
|
||||
settings->setValue(SIZE_LOCK, lock);
|
||||
};
|
||||
auto setShowOriginal = [=](bool showOriginal)
|
||||
{
|
||||
if (!showOriginal) QMessageBox::information(this, SHOW_ORIGINAL, SHOW_ORIGINAL_INFO);
|
||||
settings->setValue(SHOW_ORIGINAL, showOriginal);
|
||||
};
|
||||
setGeometry(settings->value(WINDOW, geometry()).toRect());
|
||||
setLock(settings->value(SIZE_LOCK, false).toBool());
|
||||
setTopmost(settings->value(TOPMOST, false).toBool());
|
||||
QFont font = display->font();
|
||||
font.setPointSize(16);
|
||||
font.fromString(settings->value(FONT, font.toString()).toString());
|
||||
display->setFont(font);
|
||||
setBackgroundColor(settings->value(BG_COLOR, palette().window().color()).value<QColor>());
|
||||
setTextColor(settings->value(TEXT_COLOR, display->palette().windowText().color()).value<QColor>());
|
||||
auto action = menu.addAction(name, this, slot);
|
||||
action->setCheckable(true);
|
||||
action->setChecked(settings.value(name, default).toBool());
|
||||
}
|
||||
connect(ui.display, &QLabel::customContextMenuRequested, [this](QPoint point) { menu.exec(mapToGlobal(point)); });
|
||||
|
||||
auto menu = new QMenu(display);
|
||||
auto topmost = menu->addAction(TOPMOST, setTopmost);
|
||||
topmost->setCheckable(true);
|
||||
topmost->setChecked(settings->value(TOPMOST, false).toBool());
|
||||
auto lock = menu->addAction(SIZE_LOCK, setLock);
|
||||
lock->setCheckable(true);
|
||||
lock->setChecked(settings->value(SIZE_LOCK, false).toBool());
|
||||
auto showOriginal = menu->addAction(SHOW_ORIGINAL, setShowOriginal);
|
||||
showOriginal->setCheckable(true);
|
||||
showOriginal->setChecked(settings->value(SHOW_ORIGINAL, true).toBool());
|
||||
menu->addAction(BG_COLOR, [=] { setBackgroundColor(QColorDialog::getColor(bgColor, this, BG_COLOR, QColorDialog::ShowAlphaChannel)); });
|
||||
menu->addAction(TEXT_COLOR, [=] { setTextColor(QColorDialog::getColor(display->palette().windowText().color(), this, TEXT_COLOR, QColorDialog::ShowAlphaChannel)); });
|
||||
menu->addAction(FONT, requestFont);
|
||||
display->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(display, &QLabel::customContextMenuRequested, [=](QPoint point) { menu->exec(mapToGlobal(point)); });
|
||||
connect(this, &QDialog::destroyed, [=] { settings->setValue(WINDOW, geometry()); });
|
||||
QMetaObject::invokeMethod(this, [this] { ui.display->setText(EXTRA_WINDOW_INFO); }, Qt::QueuedConnection);
|
||||
}, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
QSettings* settings = new QSettings(CONFIG_FILE, QSettings::IniFormat, this);
|
||||
QLabel* display;
|
||||
~Window()
|
||||
{
|
||||
settings.setValue(WINDOW, geometry());
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
Ui::ExtraWindow ui;
|
||||
QSettings settings{ CONFIG_FILE, QSettings::IniFormat, this };
|
||||
|
||||
private:
|
||||
void RequestFont()
|
||||
{
|
||||
QFont font = ui.display->font();
|
||||
QDialog fontDialog(this, Qt::WindowCloseButtonHint);
|
||||
fontDialog.setWindowTitle(FONT);
|
||||
QFormLayout layout(&fontDialog);
|
||||
QLineEdit fontFamily(font.family(), &fontDialog);
|
||||
layout.addRow(FONT_FAMILY, &fontFamily);
|
||||
QSpinBox fontSize(&fontDialog);
|
||||
fontSize.setValue(font.pointSize());
|
||||
layout.addRow(FONT_SIZE, &fontSize);
|
||||
QSpinBox fontWeight(&fontDialog);
|
||||
fontWeight.setValue(font.weight());
|
||||
layout.addRow(FONT_WEIGHT, &fontWeight);
|
||||
QPushButton save(SAVE_SETTINGS, &fontDialog);
|
||||
layout.addWidget(&save);
|
||||
connect(&save, &QPushButton::clicked, &fontDialog, &QDialog::accept);
|
||||
if (!fontDialog.exec()) return;
|
||||
font = QFont(fontFamily.text(), fontSize.value(), fontWeight.value());
|
||||
settings.setValue(FONT, font.toString());
|
||||
ui.display->setFont(font);
|
||||
};
|
||||
|
||||
void setBackgroundColor(QColor color)
|
||||
{
|
||||
if (!color.isValid()) return;
|
||||
if (color.alpha() == 0) color.setAlpha(1);
|
||||
bgColor = color;
|
||||
repaint();
|
||||
settings.setValue(BG_COLOR, color);
|
||||
};
|
||||
|
||||
void setTextColor(QColor color)
|
||||
{
|
||||
if (!color.isValid()) return;
|
||||
auto newPalette = ui.display->palette();
|
||||
newPalette.setColor(QPalette::WindowText, color);
|
||||
ui.display->setPalette(newPalette);
|
||||
settings.setValue(TEXT_COLOR, color);
|
||||
};
|
||||
|
||||
void setTopmost(bool topmost)
|
||||
{
|
||||
SetWindowPos((HWND)winId(), topmost ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
settings.setValue(TOPMOST, topmost);
|
||||
};
|
||||
|
||||
void setLock(bool lock)
|
||||
{
|
||||
locked = lock;
|
||||
setSizeGripEnabled(!lock);
|
||||
settings.setValue(SIZE_LOCK, lock);
|
||||
};
|
||||
|
||||
void setShowOriginal(bool showOriginal)
|
||||
{
|
||||
if (!showOriginal) QMessageBox::information(this, SHOW_ORIGINAL, SHOW_ORIGINAL_INFO);
|
||||
settings.setValue(SHOW_ORIGINAL, showOriginal);
|
||||
};
|
||||
|
||||
void paintEvent(QPaintEvent*) override
|
||||
{
|
||||
QPainter(this).fillRect(rect(), bgColor);
|
||||
@ -157,51 +154,19 @@ private:
|
||||
oldPos = event->globalPos();
|
||||
}
|
||||
|
||||
bool locked;
|
||||
QMenu menu{ ui.display };
|
||||
bool locked = true;
|
||||
QColor bgColor;
|
||||
QPoint oldPos;
|
||||
}*window = nullptr;
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
QTimer::singleShot(0, []
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
(window = new std::remove_pointer_t<decltype(window)>)->launch();
|
||||
});
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
if (window)
|
||||
{
|
||||
window->settings->setValue(WINDOW, window->geometry());
|
||||
window->settings->sync();
|
||||
}
|
||||
if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683
|
||||
{
|
||||
delete window;
|
||||
window = nullptr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
} window;
|
||||
|
||||
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
if (window == nullptr || !sentenceInfo["current select"]) return false;
|
||||
if (!sentenceInfo["current select"]) return false;
|
||||
|
||||
QString qSentence = QString::fromStdWString(sentence);
|
||||
if (!window->settings->value(SHOW_ORIGINAL).toBool()) qSentence = qSentence.section('\n', qSentence.count('\n') / 2 + 1);
|
||||
if (!window.settings.value(SHOW_ORIGINAL).toBool()) qSentence = qSentence.section('\n', qSentence.count('\n') / 2 + 1);
|
||||
|
||||
QMetaObject::invokeMethod(window, [=] { window->display->setText(qSentence); });
|
||||
QMetaObject::invokeMethod(&window, [=] { window.ui.display->setText(qSentence); });
|
||||
return false;
|
||||
}
|
||||
|
48
extensions/extrawindow.ui
Normal file
48
extensions/extrawindow.ui
Normal file
@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ExtraWindow</class>
|
||||
<widget class="QDialog" name="ExtraWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizeGripEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<layout class="QHBoxLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="display">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>16</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="contextMenuPolicy">
|
||||
<enum>Qt::CustomContextMenu</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignTop</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -5,7 +5,6 @@
|
||||
#include <QLayout>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QTimer>
|
||||
|
||||
extern const char* LUA_INTRO;
|
||||
extern const char* LOAD_LUA_SCRIPT;
|
||||
@ -45,61 +44,47 @@ bool logErrors = true;
|
||||
Synchronized<std::string> script;
|
||||
std::atomic<int> revCount = 0;
|
||||
|
||||
struct : QMainWindow
|
||||
class Window : public QMainWindow
|
||||
{
|
||||
void launch()
|
||||
public:
|
||||
Window()
|
||||
{
|
||||
auto centralWidget = new QWidget(this);
|
||||
auto layout = new QHBoxLayout(centralWidget);
|
||||
auto scriptEditor = new QPlainTextEdit(std::string(std::istreambuf_iterator<char>(std::ifstream(LUA_SAVE_FILE, std::ios::in)), {}).c_str(), centralWidget);
|
||||
auto loadButton = new QPushButton(LOAD_LUA_SCRIPT, centralWidget);
|
||||
if (scriptEditor->toPlainText().isEmpty()) scriptEditor->setPlainText(LUA_INTRO);
|
||||
layout->addWidget(scriptEditor);
|
||||
layout->addWidget(loadButton);
|
||||
save = [=]
|
||||
{
|
||||
auto script = scriptEditor->toPlainText().toUtf8();
|
||||
std::ofstream(LUA_SAVE_FILE, std::ios::out | std::ios::trunc).write(script, strlen(script));
|
||||
};
|
||||
connect(loadButton, &QPushButton::clicked, [=](bool)
|
||||
{
|
||||
revCount += 1;
|
||||
script->assign(scriptEditor->toPlainText().toUtf8());
|
||||
save();
|
||||
});
|
||||
connect(&loadButton, &QPushButton::clicked, this, &Window::LoadScript);
|
||||
|
||||
if (scriptEditor.toPlainText().isEmpty()) scriptEditor.setPlainText(LUA_INTRO);
|
||||
layout.addWidget(&scriptEditor);
|
||||
layout.addWidget(&loadButton);
|
||||
|
||||
resize(800, 600);
|
||||
setCentralWidget(centralWidget);
|
||||
setCentralWidget(¢ralWidget);
|
||||
setWindowTitle("Lua");
|
||||
show();
|
||||
QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
std::function<void()> save;
|
||||
}*window = nullptr;
|
||||
~Window()
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
private:
|
||||
void LoadScript()
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
revCount += 1;
|
||||
script->assign(scriptEditor.toPlainText().toUtf8());
|
||||
Save();
|
||||
}
|
||||
|
||||
void Save()
|
||||
{
|
||||
QTimer::singleShot(0, []
|
||||
{
|
||||
(window = new std::remove_pointer_t<decltype(window)>)->launch();
|
||||
});
|
||||
auto script = scriptEditor.toPlainText().toUtf8();
|
||||
std::ofstream(LUA_SAVE_FILE, std::ios::out | std::ios::trunc).write(script, script.size());
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
if (window) window->save();
|
||||
if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683
|
||||
{
|
||||
delete window;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
QWidget centralWidget{ this };
|
||||
QHBoxLayout layout{ ¢ralWidget };
|
||||
QPlainTextEdit scriptEditor{ std::string(std::istreambuf_iterator<char>(std::ifstream(LUA_SAVE_FILE, std::ios::in)), {}).c_str(), ¢ralWidget };
|
||||
QPushButton loadButton{ LOAD_LUA_SCRIPT, ¢ralWidget };
|
||||
} window;
|
||||
|
||||
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
|
||||
{
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "extension.h"
|
||||
#include "ui_regexfilter.h"
|
||||
#include <QTimer>
|
||||
|
||||
extern const char* REGEX_FILTER;
|
||||
extern const char* INVALID_REGEX;
|
||||
@ -9,56 +8,35 @@ extern const char* CURRENT_FILTER;
|
||||
std::wregex regex;
|
||||
std::shared_mutex m;
|
||||
|
||||
struct : QMainWindow
|
||||
class Window : public QMainWindow
|
||||
{
|
||||
void launch()
|
||||
public:
|
||||
Window()
|
||||
{
|
||||
ui.setupUi(this);
|
||||
connect(ui.input, &QLineEdit::textEdited, [=](QString newRegex)
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
try { regex = newRegex.toStdWString(); }
|
||||
catch (std::regex_error) { return ui.output->setText(INVALID_REGEX); }
|
||||
ui.output->setText(QString(CURRENT_FILTER).arg(newRegex));
|
||||
});
|
||||
|
||||
connect(ui.input, &QLineEdit::textEdited, this, &Window::setRegex);
|
||||
|
||||
setWindowTitle(REGEX_FILTER);
|
||||
show();
|
||||
QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
private:
|
||||
void setRegex(QString newRegex)
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
try { regex = newRegex.toStdWString(); }
|
||||
catch (std::regex_error) { return ui.output->setText(INVALID_REGEX); }
|
||||
ui.output->setText(QString(CURRENT_FILTER).arg(newRegex));
|
||||
}
|
||||
|
||||
Ui::FilterWindow ui;
|
||||
}*window = nullptr;
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
QTimer::singleShot(0, []
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
(window = new std::remove_pointer_t<decltype(window)>)->launch();
|
||||
});
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
delete window;
|
||||
window = nullptr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
} window;
|
||||
|
||||
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
|
||||
{
|
||||
std::shared_lock l(m);
|
||||
if (sentenceInfo["text number"] == 0) return false;
|
||||
std::shared_lock l(m);
|
||||
sentence = std::regex_replace(sentence, regex, L"");
|
||||
return true;
|
||||
}
|
||||
|
@ -93,12 +93,12 @@ bool Replace(std::wstring& sentence)
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
static HANDLE replacementFile; // not actually used to read/write, just to ensure it exists
|
||||
// not actually used to read/write, just to ensure it exists
|
||||
static AutoHandle<> replacementFile = CreateFileA(REPLACE_SAVE_FILE, FILE_GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
replacementFile = CreateFileA(REPLACE_SAVE_FILE, FILE_GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
std::vector<BYTE> file(std::istreambuf_iterator<char>(std::ifstream(REPLACE_SAVE_FILE, std::ios::in | std::ios::binary)), {});
|
||||
if (Parse(std::wstring((wchar_t*)file.data(), file.size() / sizeof(wchar_t))) == 0)
|
||||
{
|
||||
@ -110,7 +110,6 @@ BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
CloseHandle(replacementFile);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <QListWidget>
|
||||
#include <QInputDialog>
|
||||
#include <QKeyEvent>
|
||||
#include <QTimer>
|
||||
|
||||
extern const char* THREAD_LINKER;
|
||||
extern const char* LINK;
|
||||
@ -13,86 +12,58 @@ extern const char* THREAD_LINK_FROM;
|
||||
extern const char* THREAD_LINK_TO;
|
||||
extern const char* HEXADECIMAL;
|
||||
|
||||
std::mutex m;
|
||||
std::unordered_map<int64_t, std::unordered_multiset<int64_t>> linkedTextHandles;
|
||||
std::shared_mutex m;
|
||||
|
||||
struct : QMainWindow
|
||||
class Window : public QMainWindow
|
||||
{
|
||||
void launch()
|
||||
public:
|
||||
Window()
|
||||
{
|
||||
auto centralWidget = new QWidget(this);
|
||||
auto layout = new QHBoxLayout(centralWidget);
|
||||
auto linkList = new QListWidget(centralWidget);
|
||||
auto addLink = new QPushButton(LINK, centralWidget);
|
||||
layout->addWidget(linkList);
|
||||
layout->addWidget(addLink);
|
||||
connect(&linkButton, &QPushButton::clicked, this, &Window::Link);
|
||||
|
||||
connect(addLink, &QPushButton::clicked, [=]
|
||||
{
|
||||
bool ok1, ok2, ok3, ok4;
|
||||
int from = QInputDialog::getText(this, THREAD_LINK_FROM, HEXADECIMAL, QLineEdit::Normal, "", &ok1, Qt::WindowCloseButtonHint).toInt(&ok2, 16);
|
||||
int to = QInputDialog::getText(this, THREAD_LINK_TO, HEXADECIMAL, QLineEdit::Normal, "", &ok3, Qt::WindowCloseButtonHint).toInt(&ok4, 16);
|
||||
if (ok1 && ok2 && ok3 && ok4)
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
linkedTextHandles[from].insert(to);
|
||||
linkList->addItem(QString::number(from, 16) + "->" + QString::number(to, 16));
|
||||
}
|
||||
});
|
||||
Unlink = [=]
|
||||
{
|
||||
if (linkList->currentItem())
|
||||
{
|
||||
QStringList link = linkList->currentItem()->text().split("->");
|
||||
linkList->takeItem(linkList->currentRow());
|
||||
std::lock_guard l(m);
|
||||
linkedTextHandles[link[0].toInt(nullptr, 16)].erase(link[1].toInt(nullptr, 16));
|
||||
}
|
||||
};
|
||||
layout.addWidget(&linkList);
|
||||
layout.addWidget(&linkButton);
|
||||
|
||||
setCentralWidget(centralWidget);
|
||||
setCentralWidget(¢ralWidget);
|
||||
setWindowTitle(THREAD_LINKER);
|
||||
show();
|
||||
QMetaObject::invokeMethod(this, &QWidget::show, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
private:
|
||||
void Link()
|
||||
{
|
||||
bool ok1, ok2, ok3, ok4;
|
||||
int from = QInputDialog::getText(this, THREAD_LINK_FROM, HEXADECIMAL, QLineEdit::Normal, "", &ok1, Qt::WindowCloseButtonHint).toInt(&ok2, 16);
|
||||
int to = QInputDialog::getText(this, THREAD_LINK_TO, HEXADECIMAL, QLineEdit::Normal, "", &ok3, Qt::WindowCloseButtonHint).toInt(&ok4, 16);
|
||||
if (ok1 && ok2 && ok3 && ok4)
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
linkedTextHandles[from].insert(to);
|
||||
linkList.addItem(QString::number(from, 16) + "->" + QString::number(to, 16));
|
||||
}
|
||||
}
|
||||
|
||||
void keyPressEvent(QKeyEvent* event) override
|
||||
{
|
||||
if (event->key() == Qt::Key_Delete) Unlink();
|
||||
}
|
||||
|
||||
std::function<void()> Unlink;
|
||||
}*window = nullptr;
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
QTimer::singleShot(0, []
|
||||
if (event->key() == Qt::Key_Delete && linkList.currentItem())
|
||||
{
|
||||
QStringList link = linkList.currentItem()->text().split("->");
|
||||
linkList.takeItem(linkList.currentRow());
|
||||
std::lock_guard l(m);
|
||||
(window = new std::remove_pointer_t<decltype(window)>)->launch();
|
||||
});
|
||||
}
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
if (lpReserved == NULL) // https://blogs.msdn.microsoft.com/oldnewthing/20120105-00/?p=8683
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
delete window;
|
||||
window = nullptr;
|
||||
linkedTextHandles[link[0].toInt(nullptr, 16)].erase(link[1].toInt(nullptr, 16));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
QWidget centralWidget{ this };
|
||||
QHBoxLayout layout{ ¢ralWidget };
|
||||
QListWidget linkList{ ¢ralWidget };
|
||||
QPushButton linkButton{ LINK, ¢ralWidget };
|
||||
} window;
|
||||
|
||||
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
|
||||
{
|
||||
std::lock_guard l(m);
|
||||
std::shared_lock l(m);
|
||||
int64_t textHandle = sentenceInfo["text number"];
|
||||
|
||||
for (auto linkedHandle : linkedTextHandles[textHandle])
|
||||
|
Loading…
Reference in New Issue
Block a user