150 lines
6.2 KiB
C++
150 lines
6.2 KiB
C++
#include "AttachDialog.h"
|
|
#include "ui_AttachDialog.h"
|
|
#include "StdIconSearchListView.h"
|
|
#include "StdTable.h"
|
|
#include <QMenu>
|
|
#include <QMessageBox>
|
|
#include <QFileInfo>
|
|
|
|
AttachDialog::AttachDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AttachDialog)
|
|
{
|
|
ui->setupUi(this);
|
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
|
|
// Setup actions/shortcuts
|
|
//
|
|
// Enter key as shortcut for "Attach"
|
|
mAttachAction = new QAction(DIcon("attach"), tr("Attach"), this);
|
|
mAttachAction->setShortcut(QKeySequence("enter"));
|
|
connect(mAttachAction, SIGNAL(triggered()), this, SLOT(on_btnAttach_clicked()));
|
|
|
|
// F5 as shortcut to refresh view
|
|
mRefreshAction = new QAction(DIcon("arrow-restart"), tr("Refresh"), this);
|
|
mRefreshAction->setShortcut(ConfigShortcut("ActionRefresh"));
|
|
ui->btnRefresh->setText(tr("Refresh") + QString(" (%1)").arg(mRefreshAction->shortcut().toString()));
|
|
connect(mRefreshAction, SIGNAL(triggered()), this, SLOT(refresh()));
|
|
this->addAction(mRefreshAction);
|
|
connect(ui->btnRefresh, SIGNAL(clicked()), this, SLOT(refresh()));
|
|
|
|
// Create search view (regex disabled)
|
|
mSearchListView = new StdIconSearchListView(this, false, false);
|
|
mSearchListView->mSearchStartCol = 0;
|
|
ui->verticalLayout->insertWidget(0, mSearchListView);
|
|
|
|
//setup process list
|
|
int charwidth = mSearchListView->getCharWidth();
|
|
mSearchListView->addColumnAt(charwidth * sizeof(int) * 2 + 8, tr("PID"), true, QString(), ConfigBool("Gui", "PidTidInHex") ? StdTable::SortBy::AsHex : StdTable::SortBy::AsInt);
|
|
mSearchListView->addColumnAt(150, tr("Name"), true);
|
|
mSearchListView->addColumnAt(300, tr("Title"), true);
|
|
mSearchListView->addColumnAt(500, tr("Path"), true);
|
|
mSearchListView->addColumnAt(800, tr("Command Line Arguments"), true);
|
|
mSearchListView->setIconColumn(1); // Name
|
|
mSearchListView->setDrawDebugOnly(false);
|
|
|
|
connect(mSearchListView, SIGNAL(enterPressedSignal()), this, SLOT(on_btnAttach_clicked()));
|
|
connect(mSearchListView, SIGNAL(listContextMenuSignal(QMenu*)), this, SLOT(processListContextMenu(QMenu*)));
|
|
|
|
// Highlight the search box
|
|
mSearchListView->mCurList->setFocus();
|
|
|
|
Config()->setupWindowPos(this);
|
|
|
|
// Populate the process list atleast once
|
|
refresh();
|
|
}
|
|
|
|
AttachDialog::~AttachDialog()
|
|
{
|
|
Config()->saveWindowPos(this);
|
|
delete ui;
|
|
}
|
|
|
|
void AttachDialog::refresh()
|
|
{
|
|
mSearchListView->setRowCount(0);
|
|
DBGPROCESSINFO* entries;
|
|
int count;
|
|
if(!DbgFunctions()->GetProcessList(&entries, &count))
|
|
return;
|
|
mSearchListView->setRowCount(count);
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
QFileInfo fi(entries[i].szExeFile);
|
|
mSearchListView->setCellContent(i, ColPid, QString().sprintf(ConfigBool("Gui", "PidTidInHex") ? "%.8X" : "%u", entries[i].dwProcessId));
|
|
mSearchListView->setCellContent(i, ColName, fi.baseName());
|
|
mSearchListView->setCellContent(i, ColTitle, QString(entries[i].szExeMainWindowTitle));
|
|
mSearchListView->setCellContent(i, ColPath, QString(entries[i].szExeFile));
|
|
mSearchListView->setCellContent(i, ColCommandLine, QString(entries[i].szExeArgs));
|
|
mSearchListView->setRowIcon(i, getFileIcon(QString(entries[i].szExeFile)));
|
|
}
|
|
mSearchListView->reloadData();
|
|
mSearchListView->refreshSearchList();
|
|
}
|
|
|
|
void AttachDialog::on_btnAttach_clicked()
|
|
{
|
|
QString pid = mSearchListView->mCurList->getCellContent(mSearchListView->mCurList->getInitialSelection(), ColPid);
|
|
DbgCmdExec(QString("attach %1%2").arg(ConfigBool("Gui", "PidTidInHex") ? "" : ".").arg(pid));
|
|
accept();
|
|
}
|
|
|
|
void AttachDialog::on_btnFindWindow_clicked()
|
|
{
|
|
QString windowText;
|
|
retryFindWindow:
|
|
if(!SimpleInputBox(this, tr("Find Window"), windowText, windowText, tr("Enter window title or class name here.")))
|
|
return;
|
|
HWND hWndFound = FindWindowW(NULL, reinterpret_cast<LPCWSTR>(windowText.utf16())); //Window Title first
|
|
if(hWndFound == NULL)
|
|
hWndFound = FindWindowW(reinterpret_cast<LPCWSTR>(windowText.utf16()), NULL); //Then try window class name
|
|
if(hWndFound == NULL)
|
|
{
|
|
QMessageBox retryDialog(QMessageBox::Critical, tr("Find Window"), tr("Cannot find window \"%1\". Retry?").arg(windowText), QMessageBox::Cancel | QMessageBox::Retry, this);
|
|
retryDialog.setWindowIcon(DIcon("compile-error"));
|
|
if(retryDialog.exec() == QMessageBox::Retry)
|
|
goto retryFindWindow;
|
|
}
|
|
else
|
|
{
|
|
DWORD pid, tid;
|
|
if(tid = GetWindowThreadProcessId(hWndFound, &pid))
|
|
{
|
|
refresh();
|
|
QString pidText = QString().sprintf(ConfigBool("Gui", "PidTidInHex") ? "%.8X" : "%u", pid);
|
|
bool found = false;
|
|
for(int i = 0; i < mSearchListView->mCurList->getRowCount(); i++)
|
|
{
|
|
if(mSearchListView->mCurList->getCellContent(i, ColPid) == pidText)
|
|
{
|
|
mSearchListView->mCurList->setSingleSelection(i);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if(!found)
|
|
{
|
|
QMessageBox hiddenProcessDialog(QMessageBox::Question, tr("Find Window"),
|
|
tr("The PID of the window \"%1\" is %2, but it's hidden in the process list. Do you want to attach to it immediately?").arg(windowText).arg(pidText),
|
|
QMessageBox::Yes | QMessageBox::No, this);
|
|
if(hiddenProcessDialog.exec() == QMessageBox::Yes)
|
|
{
|
|
DbgCmdExec(QString("attach %1").arg(pid, 0, 16));
|
|
accept();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
SimpleErrorBox(this, tr("Find Window"), tr("GetWindowThreadProcessId() failed. Cannot get the PID of the window."));
|
|
}
|
|
}
|
|
|
|
void AttachDialog::processListContextMenu(QMenu* wMenu)
|
|
{
|
|
// Don't show menu options if nothing is listed
|
|
if(!mSearchListView->mCurList->getRowCount())
|
|
return;
|
|
|
|
wMenu->addAction(mAttachAction);
|
|
wMenu->addAction(mRefreshAction);
|
|
}
|