MacroBinds/WindowFinder/windowfinder.cpp
2024-09-17 04:05:32 -04:00

201 lines
6.1 KiB
C++

#include "windowfinder.h"
#include "QtImprovements/qsettingsplus.h"
#include <QFileInfo>
#include <QImage>
#include <QKeySequence>
#ifdef Q_OS_WIN
#include <Windows.h>
#include <processthreadsapi.h>
#include <Psapi.h>
#endif
WindowFinder::WindowFinder() {}
WindowData WindowFinder::getFrontmostWindowProcess()
{
#ifdef Q_OS_WIN
return WindowFinder::getWin32FrontmostWindowProcess();
#else
return WindowData();
#endif
}
void WindowFinder::sendInputToFrontmostWindow(const QKeySequence &keys, const KeyEventType &type)
{
#ifdef Q_OS_WIN
WindowFinder::sendWin32InputToFrontmostWindow(keys, type);
#else
return;
#endif
}
void WindowData::importDataFromSetting(const QString &value)
{
QStringList values = value.split(QSettingsPlus::keyDataSeparator());
this->processName = values[0];
this->processPath = values[1];
values.removeAt(1);
values.removeAt(0);
this->processWindowTitle = values.join(QSettingsPlus::keyDataSeparator());
}
#ifdef Q_OS_WIN
WindowData WindowFinder::getWin32FrontmostWindowProcess()
{
WindowData data;
HWND focusWindow = GetForegroundWindow();
DWORD processId;
GetWindowThreadProcessId(focusWindow, &processId);
HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
false,
processId);
TCHAR processPath[MAX_PATH];
DWORD pathLength = GetModuleFileNameExW(processHandle, NULL, processPath, MAX_PATH);
assert(pathLength != ERROR_INSUFFICIENT_BUFFER);
data.processPath = QString::fromWCharArray(processPath, pathLength);
data.processName = QFileInfo(data.processPath).fileName();
/* Extract icon */
// HICON processIcon;
// ExtractIconExW(processPath, 0, &processIcon, nullptr, 1);
// QByteArray pixelBuffer;
// WindowFinder::getWin32IconData(processIcon, 32, pixelBuffer);
/* End extract icon */
WCHAR processTitle[512];
DWORD titleLength = GetWindowTextW(focusWindow, &processTitle[0], 512);
assert(titleLength != ERROR_INSUFFICIENT_BUFFER);
data.processWindowTitle = QString::fromWCharArray(processTitle, titleLength);
CloseHandle(processHandle);
return data;
}
// bool WindowFinder::getWin32IconData(HICON hIcon, int nColorBits, QByteArray &buffer)
// {
// HDC dc = CreateCompatibleDC(NULL);
// const char iconHeader[6] = {0, 0, 1, 0, 1, 0};
// buffer.append(iconHeader);
// ICONINFO iconInfo;
// GetIconInfo(hIcon, &iconInfo);
// BITMAPINFO bmInfo = {{0}};
// bmInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// bmInfo.bmiHeader.biBitCount = 0;
// if (!GetDIBits(dc, iconInfo.hbmColor, 0, 0, NULL, &bmInfo, DIB_RGB_COLORS))
// return false;
// int nBmInfoSize = sizeof(BITMAPINFOHEADER);
// if (nColorBits < 24)
// nBmInfoSize += sizeof(RGBQUAD) * (int) (static_cast<unsigned long long>(1) << nColorBits);
// QVector<quint8> bitmapInfo;
// bitmapInfo.resize(nBmInfoSize);
// BITMAPINFO *pBmInfo = (BITMAPINFO *) bitmapInfo.data();
// memcpy(pBmInfo, &bmInfo, sizeof(BITMAPINFOHEADER));
// if (!bmInfo.bmiHeader.biSizeImage)
// return false;
// QVector<quint8> bits;
// bits.resize(bmInfo.bmiHeader.biSizeImage);
// pBmInfo->bmiHeader.biBitCount = nColorBits;
// pBmInfo->bmiHeader.biCompression = BI_RGB;
// if (!GetDIBits(dc,
// iconInfo.hbmColor,
// 0,
// bmInfo.bmiHeader.biHeight,
// bits.data(),
// pBmInfo,
// DIB_RGB_COLORS))
// return false;
// BITMAPINFO maskInfo = {{0}};
// maskInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
// maskInfo.bmiHeader.biBitCount = 0;
// if (!GetDIBits(dc, iconInfo.hbmMask, 0, 0, NULL, &maskInfo, DIB_RGB_COLORS)
// || maskInfo.bmiHeader.biBitCount != 1)
// return false;
// QVector<quint8> maskBits;
// maskBits.resize(maskInfo.bmiHeader.biSizeImage);
// QVector<quint8> maskInfoBytes;
// maskInfoBytes.resize(sizeof(BITMAPINFO) + 2 * sizeof(RGBQUAD));
// BITMAPINFO *pMaskInfo = (BITMAPINFO *) maskInfoBytes.data();
// memcpy(pMaskInfo, &maskInfo, sizeof(maskInfo));
// if (!GetDIBits(dc,
// iconInfo.hbmMask,
// 0,
// maskInfo.bmiHeader.biHeight,
// maskBits.data(),
// pMaskInfo,
// DIB_RGB_COLORS)) {
// return false;
// }
// IconDirEntry dir;
// dir.nWidth = (quint8) pBmInfo->bmiHeader.biWidth;
// dir.nHeight = (quint8) pBmInfo->bmiHeader.biHeight;
// dir.nNumColorsInPalette = (nColorBits == 4 ? 16 : 0);
// dir.nReserved = 0;
// dir.nNumColorPlanes = 0;
// dir.nBitsPerPixel = pBmInfo->bmiHeader.biBitCount;
// dir.nDataLength = pBmInfo->bmiHeader.biSizeImage + pMaskInfo->bmiHeader.biSizeImage
// + nBmInfoSize;
// dir.nOffset = sizeof(dir) + sizeof(iconHeader);
// const char *dirBuffer = reinterpret_cast<const char *>(&dir);
// buffer.append(dirBuffer);
// pBmInfo->bmiHeader.biHeight *= 2;
// pBmInfo->bmiHeader.biCompression = 0;
// pBmInfo->bmiHeader.biSizeImage += pMaskInfo->bmiHeader.biSizeImage;
// const char *bmiHeaderData = reinterpret_cast<const char *>(&pBmInfo->bmiHeader);
// buffer.append(bmiHeaderData);
// const char *bitData = reinterpret_cast<const char *>(bits.data());
// buffer.append(bitData);
// const char *maskBitData = reinterpret_cast<const char *>(maskBits.data());
// buffer.append(maskBitData);
// DeleteObject(iconInfo.hbmMask);
// DeleteObject(iconInfo.hbmColor);
// DeleteDC(dc);
// return true;
// }
void WindowFinder::sendWin32InputToFrontmostWindow(const QKeySequence &keys, const KeyEventType &type)
{
const QString &keyStrings = keys.toString();
const QStringList &keyStringsList = keyStrings.split(",");
for (const QString &keyString : keyStringsList) {
const QStringList &keys = keyString.split("+");
for (const QString &key : keys) {
INPUT input[1] = {};
ZeroMemory(input, sizeof(input));
input[0].type = INPUT_KEYBOARD;
if (key.compare("Shift", Qt::CaseInsensitive) == 0) {
input[0].ki.wVk = VK_LSHIFT;
} else if (key.compare("X", Qt::CaseInsensitive) == 0) {
input[0].ki.wVk = 'X';
} else if (key.compare("Y", Qt::CaseInsensitive) == 0) {
input[0].ki.wVk = 'Y';
} else if (key.compare("Z", Qt::CaseInsensitive) == 0) {
input[0].ki.wVk = 'Z';
}
input[0].ki.dwFlags = type == KeyEventType::RELEASE ? KEYEVENTF_KEYUP : 0;
SendInput(ARRAYSIZE(input), input, sizeof(INPUT));
}
}
}
#endif // Q_OS_WIN