Cleanup Windows helpers (#4820)

* fix: clipboard exception

* chore: cleanup windows helpers
This commit is contained in:
nerix 2023-09-17 12:20:26 +02:00 committed by GitHub
parent d752ce86fd
commit f13a3b9685
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,28 +1,27 @@
#include "WindowsHelper.hpp" #include "util/WindowsHelper.hpp"
#include <QCoreApplication> #include "common/Literals.hpp"
#include <QApplication>
#include <QClipboard>
#include <QFileInfo> #include <QFileInfo>
#include <QSettings> #include <QSettings>
#ifdef USEWINSDK #ifdef USEWINSDK
# include <Ole2.h>
# include <ShellScalingApi.h>
# include <Shlwapi.h> # include <Shlwapi.h>
# include <VersionHelpers.h> # include <VersionHelpers.h>
namespace chatterino { namespace chatterino {
typedef enum MONITOR_DPI_TYPE { using namespace literals;
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
typedef HRESULT(CALLBACK *GetDpiForMonitor_)(HMONITOR, MONITOR_DPI_TYPE, UINT *, using GetDpiForMonitor_ = HRESULT(CALLBACK *)(HMONITOR, MONITOR_DPI_TYPE,
UINT *); UINT *, UINT *);
typedef HRESULT(CALLBACK *AssocQueryString_)(ASSOCF, ASSOCSTR, LPCWSTR, LPCWSTR,
LPWSTR, DWORD *);
// TODO: This should be changed to `GetDpiForWindow`.
boost::optional<UINT> getWindowDpi(HWND hwnd) boost::optional<UINT> getWindowDpi(HWND hwnd)
{ {
static HINSTANCE shcore = LoadLibrary(L"Shcore.dll"); static HINSTANCE shcore = LoadLibrary(L"Shcore.dll");
@ -34,8 +33,8 @@ boost::optional<UINT> getWindowDpi(HWND hwnd)
HMONITOR monitor = HMONITOR monitor =
MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
UINT xScale, yScale; UINT xScale = 96;
UINT yScale = 96;
getDpiForMonitor(monitor, MDT_DEFAULT, &xScale, &yScale); getDpiForMonitor(monitor, MDT_DEFAULT, &xScale, &yScale);
return xScale; return xScale;
@ -45,34 +44,27 @@ boost::optional<UINT> getWindowDpi(HWND hwnd)
return boost::none; return boost::none;
} }
typedef HRESULT(CALLBACK *OleFlushClipboard_)();
void flushClipboard() void flushClipboard()
{ {
static HINSTANCE ole32 = LoadLibrary(L"Ole32.dll"); if (QApplication::clipboard()->ownsClipboard())
if (ole32 != nullptr)
{ {
if (auto oleFlushClipboard = OleFlushClipboard();
OleFlushClipboard_(GetProcAddress(ole32, "OleFlushClipboard")))
{
oleFlushClipboard();
}
} }
} }
constexpr const char *runKey = const QString RUN_KEY =
"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"; uR"(HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run)"_s;
bool isRegisteredForStartup() bool isRegisteredForStartup()
{ {
QSettings settings(runKey, QSettings::NativeFormat); QSettings settings(RUN_KEY, QSettings::NativeFormat);
return !settings.value("Chatterino").toString().isEmpty(); return !settings.value("Chatterino").toString().isEmpty();
} }
void setRegisteredForStartup(bool isRegistered) void setRegisteredForStartup(bool isRegistered)
{ {
QSettings settings(runKey, QSettings::NativeFormat); QSettings settings(RUN_KEY, QSettings::NativeFormat);
if (isRegistered) if (isRegistered)
{ {
@ -90,19 +82,6 @@ void setRegisteredForStartup(bool isRegistered)
QString getAssociatedExecutable(AssociationQueryType queryType, LPCWSTR query) QString getAssociatedExecutable(AssociationQueryType queryType, LPCWSTR query)
{ {
static HINSTANCE shlwapi = LoadLibrary(L"shlwapi");
if (shlwapi == nullptr)
{
return QString();
}
static auto assocQueryString =
AssocQueryString_(GetProcAddress(shlwapi, "AssocQueryStringW"));
if (assocQueryString == nullptr)
{
return QString();
}
// always error out instead of returning a truncated string when the // always error out instead of returning a truncated string when the
// buffer is too small - avoids race condition when the user changes their // buffer is too small - avoids race condition when the user changes their
// default browser between calls to AssocQueryString // default browser between calls to AssocQueryString
@ -117,28 +96,28 @@ QString getAssociatedExecutable(AssociationQueryType queryType, LPCWSTR query)
} }
else else
{ {
return QString(); return {};
} }
} }
DWORD resultSize = 0; DWORD resultSize = 0;
if (FAILED(assocQueryString(flags, ASSOCSTR_EXECUTABLE, query, nullptr, if (FAILED(AssocQueryStringW(flags, ASSOCSTR_EXECUTABLE, query, nullptr,
nullptr, &resultSize))) nullptr, &resultSize)))
{ {
return QString(); return {};
} }
if (resultSize <= 1) if (resultSize <= 1)
{ {
// resultSize includes the null terminator. if resultSize is 1, the // resultSize includes the null terminator. if resultSize is 1, the
// returned value would be the empty string. // returned value would be the empty string.
return QString(); return {};
} }
QString result; QString result;
auto buf = new wchar_t[resultSize]; auto *buf = new wchar_t[resultSize];
if (SUCCEEDED(assocQueryString(flags, ASSOCSTR_EXECUTABLE, query, nullptr, if (SUCCEEDED(AssocQueryStringW(flags, ASSOCSTR_EXECUTABLE, query, nullptr,
buf, &resultSize))) buf, &resultSize)))
{ {
// QString::fromWCharArray expects the length in characters *not // QString::fromWCharArray expects the length in characters *not
// including* the null terminator, but AssocQueryStringW calculates // including* the null terminator, but AssocQueryStringW calculates