106 lines
2.8 KiB
C++
106 lines
2.8 KiB
C++
#include "extension.h"
|
|
#include <QMainWindow>
|
|
#include <QLayout>
|
|
#include <QPushButton>
|
|
#include <QListWidget>
|
|
#include <QInputDialog>
|
|
#include <QKeyEvent>
|
|
#include <QTimer>
|
|
|
|
extern const char* THREAD_LINKER;
|
|
extern const char* LINK;
|
|
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;
|
|
|
|
struct : QMainWindow
|
|
{
|
|
void launch()
|
|
{
|
|
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(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));
|
|
}
|
|
};
|
|
|
|
setCentralWidget(centralWidget);
|
|
setWindowTitle(THREAD_LINKER);
|
|
show();
|
|
}
|
|
|
|
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, []
|
|
{
|
|
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;
|
|
}
|
|
|
|
bool ProcessSentence(std::wstring& sentence, SentenceInfo sentenceInfo)
|
|
{
|
|
std::lock_guard l(m);
|
|
static std::unordered_map<int64_t, std::wstring> queuedWritesByHandle;
|
|
int64_t textHandle = sentenceInfo["text handle"];
|
|
|
|
for (auto linkedHandle : linkedTextHandles[textHandle]) queuedWritesByHandle[linkedHandle] += L"\n" + sentence;
|
|
|
|
if (queuedWritesByHandle[textHandle].empty()) return false;
|
|
sentence += queuedWritesByHandle[textHandle];
|
|
queuedWritesByHandle[textHandle].clear();
|
|
return true;
|
|
}
|