Mercurial > minori
diff src/sys/win32/dark_theme.cc @ 178:bc8d2ccff09c
win32/dark: use existing STL classes for dwmapi
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Mon, 04 Dec 2023 11:51:30 -0500 |
parents | c8c72278f6fd |
children | f0ff06a45c42 |
line wrap: on
line diff
--- a/src/sys/win32/dark_theme.cc Fri Dec 01 13:32:29 2023 -0500 +++ b/src/sys/win32/dark_theme.cc Mon Dec 04 11:51:30 2023 -0500 @@ -1,84 +1,62 @@ #include "sys/win32/dark_theme.h" + #include <QApplication> -#include <QDebug> #include <QOperatingSystemVersion> #include <QSettings> #include <QWidget> + #include <iostream> +#include <memory> + #include <dwmapi.h> -/* let's make a class wrapper around HINSTANCE, - so we don't fuck anything up :). */ -class Library { - public: - Library() {} - ~Library() { - Unload(); - } - void Unload() { - if (hInstance) { - FreeLibrary(hInstance); - hInstance = nullptr; - } - loaded = false; - } - void Load(LPCWSTR name) { - if (loaded) - Unload(); - hInstance = LoadLibraryW(name); - if (hInstance) - loaded = true; - } - HINSTANCE GetInstance() { - return hInstance; - } - bool IsLoaded() { - return loaded; - } - private: - HINSTANCE hInstance = nullptr; - bool loaded = false; +struct LibraryDeconstructor { + using pointer = HINSTANCE; + void operator()(pointer t) const { ::FreeLibrary(t); }; }; -Library dwmapi; +using Library = std::unique_ptr<HINSTANCE, LibraryDeconstructor>; + +class Dwmapi { + public: + Dwmapi() { library.reset( ::LoadLibraryW(L"dwmapi.dll")); } + + HRESULT SetWindowAttribute(HWND hWnd, DWORD key, LPCVOID data, DWORD sz_data) { + if (!library.get()) + return E_POINTER; + + /* GCC throws a fit here because C/C++ lacks a "generic" function pointer type. + Ignore. */ + auto set_wind_attrib = reinterpret_cast<decltype(::DwmSetWindowAttribute)*>(GetProcAddress(library.get(), "DwmSetWindowAttribute")); + if (!set_wind_attrib) + return E_POINTER; + + return set_wind_attrib(hWnd, key, data, sz_data); + } + + protected: + Library library = nullptr; +}; + +Dwmapi dwmapi; namespace win32 { -#define GET_FUNCTION(f, i) \ - reinterpret_cast<decltype(::f)*>(GetProcAddress(i, #f)) - -static HRESULT SetWindowAttribute(HWND hWnd, DWORD key, LPCVOID data, DWORD sz_data) { - if (!dwmapi.IsLoaded()) { - dwmapi.Load(L"dwmapi.dll"); - if (!dwmapi.IsLoaded()) - return false; - } - - HINSTANCE hInstance = dwmapi.GetInstance(); - if (!hInstance) - return false; - - auto set_wind_attrib = GET_FUNCTION(DwmSetWindowAttribute, hInstance); - if (!set_wind_attrib) - return false; - - return set_wind_attrib(hWnd, key, data, sz_data); -} - +/* NOTE: explicit conversion from builtin `bool` and win32 `BOOL` IS allowed. */ bool SetTitleBarToBlack(QWidget* win, bool enabled) { BOOL b = enabled; /* MAGIC NUMBERS: 19 and 20 are both DWMWA_USE_IMMERSIVE_DARK_MODE. - clarification: it's 20 on newer versions of windows (i.e. win11 and late win10), - but it's 19 on very old versions of win10 nobody ought to be using. */ + For clarification: it's 20 on newer versions of windows (i.e. win11 and late win10), + but it's 19 on very old versions of win10 nobody ought to be using anymore. */ { - HRESULT result = SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 20, &b, sizeof(b)); + HRESULT result = dwmapi.SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 20, &b, sizeof(b)); if (result == S_OK) return b; } { - HRESULT result = SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 19, &b, sizeof(b)); + HRESULT result = dwmapi.SetWindowAttribute(reinterpret_cast<HWND>(win->winId()), 19, &b, sizeof(b)); if (result == S_OK) return b; }