#include #include #include #include #include "ThemeHelper.h" #include // Controls changing the themes. static void ResetColorPrevalence() { HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, PERSONALIZATION_REGISTRY_PATH, 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { DWORD value = 0; // back to default value RegSetValueEx(hKey, L"ColorPrevalence", 0, REG_DWORD, reinterpret_cast(&value), sizeof(value)); RegCloseKey(hKey); SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, reinterpret_cast(L"ImmersiveColorSet"), SMTO_ABORTIFHUNG, 5000, nullptr); SendMessageTimeout(HWND_BROADCAST, WM_THEMECHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); SendMessageTimeout(HWND_BROADCAST, WM_DWMCOLORIZATIONCOLORCHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); } } void SetAppsTheme(bool mode) { HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, PERSONALIZATION_REGISTRY_PATH, 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { DWORD value = mode; RegSetValueEx(hKey, L"AppsUseLightTheme", 0, REG_DWORD, reinterpret_cast(&value), sizeof(value)); RegCloseKey(hKey); SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, reinterpret_cast(L"ImmersiveColorSet"), SMTO_ABORTIFHUNG, 5000, nullptr); SendMessageTimeout(HWND_BROADCAST, WM_THEMECHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); } } void SetSystemTheme(bool mode) { HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, PERSONALIZATION_REGISTRY_PATH, 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { DWORD value = mode; RegSetValueEx(hKey, L"SystemUsesLightTheme", 0, REG_DWORD, reinterpret_cast(&value), sizeof(value)); RegCloseKey(hKey); if (mode) // if are changing to light mode { ResetColorPrevalence(); Logger::info(L"[LightSwitchService] Reset ColorPrevalence to default when switching to light mode."); } SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, reinterpret_cast(L"ImmersiveColorSet"), SMTO_ABORTIFHUNG, 5000, nullptr); SendMessageTimeout(HWND_BROADCAST, WM_THEMECHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); } } // Can think of this as "is the current theme light?" bool GetCurrentSystemTheme() { HKEY hKey; DWORD value = 1; // default = light DWORD size = sizeof(value); if (RegOpenKeyEx(HKEY_CURRENT_USER, PERSONALIZATION_REGISTRY_PATH, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { RegQueryValueEx(hKey, L"SystemUsesLightTheme", nullptr, nullptr, reinterpret_cast(&value), &size); RegCloseKey(hKey); } return value == 1; // true = light, false = dark } bool GetCurrentAppsTheme() { HKEY hKey; DWORD value = 1; DWORD size = sizeof(value); if (RegOpenKeyEx(HKEY_CURRENT_USER, PERSONALIZATION_REGISTRY_PATH, 0, KEY_READ, &hKey) == ERROR_SUCCESS) { RegQueryValueEx(hKey, L"AppsUseLightTheme", nullptr, nullptr, reinterpret_cast(&value), &size); RegCloseKey(hKey); } return value == 1; // true = light, false = dark } bool IsNightLightEnabled() { HKEY hKey; const wchar_t* path = NIGHT_LIGHT_REGISTRY_PATH; if (RegOpenKeyExW(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKey) != ERROR_SUCCESS) return false; // RegGetValueW will set size to the size of the data and we expect that to be at least 25 bytes (we need to access bytes 23 and 24) DWORD size = 0; if (RegGetValueW(hKey, nullptr, L"Data", RRF_RT_REG_BINARY, nullptr, nullptr, &size) != ERROR_SUCCESS || size < 25) { RegCloseKey(hKey); return false; } std::vector data(size); if (RegGetValueW(hKey, nullptr, L"Data", RRF_RT_REG_BINARY, nullptr, data.data(), &size) != ERROR_SUCCESS) { RegCloseKey(hKey); return false; } RegCloseKey(hKey); return data[23] == 0x10 && data[24] == 0x00; }