forked from Public-Mirror/Textractor
Create a new attach dialog window
New dialog window that shows processes with icons in QListView instead of ComboBox.
This commit is contained in:
parent
dd4b8cfbb5
commit
a1d3abb080
@ -10,6 +10,7 @@ add_executable(Textractor WIN32
|
|||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
extenwindow.cpp
|
extenwindow.cpp
|
||||||
|
attachtoprocessdialog.cpp
|
||||||
host/exception.cpp
|
host/exception.cpp
|
||||||
host/host.cpp
|
host/host.cpp
|
||||||
host/textthread.cpp
|
host/textthread.cpp
|
||||||
|
92
GUI/attachtoprocessdialog.cpp
Normal file
92
GUI/attachtoprocessdialog.cpp
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
#include "attachtoprocessdialog.h"
|
||||||
|
#include "ui_attachtoprocessdialog.h"
|
||||||
|
#include "utils/windowshelpers.h"
|
||||||
|
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
QString GetNameProcessFromIndex(const QModelIndex &index, const QVector<QPair<QString, HICON>>& data)
|
||||||
|
{
|
||||||
|
const int row = index.row();
|
||||||
|
return data[row].first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachToProcessDialog::AttachToProcessDialog(QWidget *parent) :
|
||||||
|
QDialog(parent, Qt::WindowCloseButtonHint),
|
||||||
|
ui(new Ui::AttachToProcessDialog),
|
||||||
|
model(new QStandardItemModel(this))
|
||||||
|
{
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
const QIntValidator* validator = new QIntValidator(0, INT_MAX, this);
|
||||||
|
ui->lineEdit->setValidator(validator);
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachToProcessDialog::~AttachToProcessDialog()
|
||||||
|
{
|
||||||
|
delete ui;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::setLabelText(const QString& text)
|
||||||
|
{
|
||||||
|
ui->label->setText(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::setData(QVector<QPair<QString, HICON>>&& newData)
|
||||||
|
{
|
||||||
|
data = std::move(newData);
|
||||||
|
selectedProcess.clear();
|
||||||
|
std::sort(data.begin(), data.end(), [](const auto& left, const auto& right) {
|
||||||
|
return left.first < right.first;
|
||||||
|
});
|
||||||
|
model->clear();
|
||||||
|
for (const auto& [process, hIcon] : data)
|
||||||
|
{
|
||||||
|
QIcon icon = WindowsHepers::CreateQIconFromHIcon(hIcon);
|
||||||
|
auto* item = new QStandardItem(icon, process);
|
||||||
|
item->setEditable(false);
|
||||||
|
model->appendRow(item);
|
||||||
|
}
|
||||||
|
ui->listView->setModel(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AttachToProcessDialog::getSelectedData()
|
||||||
|
{
|
||||||
|
return selectedProcess.isEmpty() ? ui->lineEdit->text() : selectedProcess;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::on_buttonBox_accepted()
|
||||||
|
{
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::on_buttonBox_rejected()
|
||||||
|
{
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::on_listView_doubleClicked(const QModelIndex& index)
|
||||||
|
{
|
||||||
|
selectedProcess = GetNameProcessFromIndex(index, data);
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::on_lineEdit_returnPressed()
|
||||||
|
{
|
||||||
|
selectedProcess = ui->lineEdit->text();
|
||||||
|
accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::on_listView_clicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
selectedProcess = GetNameProcessFromIndex(index, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AttachToProcessDialog::on_lineEdit_editingFinished()
|
||||||
|
{
|
||||||
|
selectedProcess = ui->lineEdit->text();
|
||||||
|
}
|
51
GUI/attachtoprocessdialog.h
Normal file
51
GUI/attachtoprocessdialog.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#ifndef ATTACHTOPROCESSDIALOG_H
|
||||||
|
#define ATTACHTOPROCESSDIALOG_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QString>
|
||||||
|
#include <QPair>
|
||||||
|
#include <QStyledItemDelegate>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QtWinExtras/QtWin>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
namespace Ui {
|
||||||
|
class AttachToProcessDialog;
|
||||||
|
}
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
class QStandardItemModel;
|
||||||
|
class QModelIndex;
|
||||||
|
|
||||||
|
class AttachToProcessDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AttachToProcessDialog(QWidget *parent = nullptr);
|
||||||
|
void setData(QVector<QPair<QString, HICON>>&& newData);
|
||||||
|
void setLabelText(const QString& text);
|
||||||
|
QString getSelectedData();
|
||||||
|
~AttachToProcessDialog();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void on_buttonBox_accepted();
|
||||||
|
|
||||||
|
void on_buttonBox_rejected();
|
||||||
|
|
||||||
|
void on_listView_doubleClicked(const QModelIndex &index);
|
||||||
|
|
||||||
|
void on_lineEdit_returnPressed();
|
||||||
|
|
||||||
|
void on_listView_clicked(const QModelIndex &index);
|
||||||
|
|
||||||
|
void on_lineEdit_editingFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::AttachToProcessDialog* ui;
|
||||||
|
QStandardItemModel* model;
|
||||||
|
QString selectedProcess;
|
||||||
|
QVector<QPair<QString, HICON>> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ATTACHTOPROCESSDIALOG_H
|
52
GUI/attachtoprocessdialog.ui
Normal file
52
GUI/attachtoprocessdialog.ui
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AttachToProcessDialog</class>
|
||||||
|
<widget class="QWidget" name="AttachToProcessDialog">
|
||||||
|
<property name="windowModality">
|
||||||
|
<enum>Qt::WindowModal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>813</width>
|
||||||
|
<height>426</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Form</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>TextLabel</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="lineEdit">
|
||||||
|
<property name="placeholderText">
|
||||||
|
<string>PID</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QListView" name="listView"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
@ -5,6 +5,9 @@
|
|||||||
#include "extenwindow.h"
|
#include "extenwindow.h"
|
||||||
#include "host/host.h"
|
#include "host/host.h"
|
||||||
#include "host/hookcode.h"
|
#include "host/hookcode.h"
|
||||||
|
#include "attachtoprocessdialog.h"
|
||||||
|
#include "utils/windowshelpers.h"
|
||||||
|
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
@ -14,6 +17,7 @@
|
|||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QFontDialog>
|
#include <QFontDialog>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
extern const char* ATTACH;
|
extern const char* ATTACH;
|
||||||
extern const char* LAUNCH;
|
extern const char* LAUNCH;
|
||||||
@ -79,6 +83,7 @@ namespace
|
|||||||
Ui::MainWindow ui;
|
Ui::MainWindow ui;
|
||||||
std::atomic<DWORD> selectedProcessId = 0;
|
std::atomic<DWORD> selectedProcessId = 0;
|
||||||
ExtenWindow* extenWindow = nullptr;
|
ExtenWindow* extenWindow = nullptr;
|
||||||
|
AttachToProcessDialog* attachDialog = nullptr;
|
||||||
std::unordered_set<DWORD> alreadyAttached;
|
std::unordered_set<DWORD> alreadyAttached;
|
||||||
bool autoAttach = false, autoAttachSavedOnly = true;
|
bool autoAttach = false, autoAttachSavedOnly = true;
|
||||||
bool showSystemProcesses = false;
|
bool showSystemProcesses = false;
|
||||||
@ -153,16 +158,50 @@ namespace
|
|||||||
|
|
||||||
void AttachProcess()
|
void AttachProcess()
|
||||||
{
|
{
|
||||||
QMultiHash<QString, DWORD> allProcesses;
|
auto processes = GetAllProcesses();
|
||||||
for (auto [processId, processName] : GetAllProcesses())
|
QMultiHash<QString, DWORD> processesMap;
|
||||||
|
QVector<QPair<QString, HICON>> dialogData;
|
||||||
|
dialogData.reserve(processes.size());
|
||||||
|
for (auto [processId, processName] : processes)
|
||||||
|
{
|
||||||
if (processName && (showSystemProcesses || processName->find(L":\\Windows\\") == std::string::npos))
|
if (processName && (showSystemProcesses || processName->find(L":\\Windows\\") == std::string::npos))
|
||||||
allProcesses.insert(QFileInfo(S(processName.value())).fileName(), processId);
|
{
|
||||||
|
const auto& value = processName.value();
|
||||||
|
const QFileInfo& fileInfo = QFileInfo(S(value));
|
||||||
|
const QString& fileName = fileInfo.fileName();
|
||||||
|
if (!processesMap.contains(fileName))
|
||||||
|
{
|
||||||
|
const auto icon = WindowsHepers::GetIconHandlerFromExe(value.c_str());
|
||||||
|
dialogData.push_back({fileName, icon});
|
||||||
|
}
|
||||||
|
processesMap.insert(fileName, processId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dialogData.shrink_to_fit();
|
||||||
|
processes.clear();
|
||||||
|
|
||||||
QStringList processList(allProcesses.uniqueKeys());
|
attachDialog->setWindowTitle(SELECT_PROCESS);
|
||||||
processList.sort(Qt::CaseInsensitive);
|
attachDialog->setLabelText(ATTACH_INFO);
|
||||||
if (QString process = QInputDialog::getItem(This, SELECT_PROCESS, ATTACH_INFO, processList, 0, true, &ok, Qt::WindowCloseButtonHint); ok)
|
|
||||||
if (process.toInt(nullptr, 0)) Host::InjectProcess(process.toInt(nullptr, 0));
|
attachDialog->setData(std::move(dialogData));
|
||||||
else for (auto processId : allProcesses.values(process)) Host::InjectProcess(processId);
|
const bool hasChosenData = attachDialog->exec() != 0;
|
||||||
|
|
||||||
|
if (hasChosenData)
|
||||||
|
{
|
||||||
|
const QString& process = attachDialog->getSelectedData();
|
||||||
|
const int pid = process.toInt(nullptr, 0);
|
||||||
|
if (pid)
|
||||||
|
{
|
||||||
|
Host::InjectProcess(pid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& processId : processesMap.values(process))
|
||||||
|
{
|
||||||
|
Host::InjectProcess(processId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LaunchProcess()
|
void LaunchProcess()
|
||||||
@ -597,6 +636,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
|
|||||||
This = this;
|
This = this;
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
extenWindow = new ExtenWindow(this);
|
extenWindow = new ExtenWindow(this);
|
||||||
|
attachDialog = new AttachToProcessDialog(this);
|
||||||
for (auto [text, slot] : Array<const char*, void(&)()>{
|
for (auto [text, slot] : Array<const char*, void(&)()>{
|
||||||
{ ATTACH, AttachProcess },
|
{ ATTACH, AttachProcess },
|
||||||
{ LAUNCH, LaunchProcess },
|
{ LAUNCH, LaunchProcess },
|
||||||
|
Loading…
x
Reference in New Issue
Block a user