ThemeHelper.cpp
1 #include "pch.h" 2 #include "ThemeHelper.h" 3 #include <logger/logger.h> 4 5 // Controls changing the themes. 6 7 static void ResetColorPrevalence() 8 { 9 HKEY hKey; 10 if (RegOpenKeyEx(HKEY_CURRENT_USER, 11 PERSONALIZATION_REGISTRY_PATH, 12 0, 13 KEY_SET_VALUE, 14 &hKey) == ERROR_SUCCESS) 15 { 16 DWORD value = 0; // back to default value 17 RegSetValueEx(hKey, L"ColorPrevalence", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(value)); 18 RegCloseKey(hKey); 19 20 SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, reinterpret_cast<LPARAM>(L"ImmersiveColorSet"), SMTO_ABORTIFHUNG, 5000, nullptr); 21 22 SendMessageTimeout(HWND_BROADCAST, WM_THEMECHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); 23 24 SendMessageTimeout(HWND_BROADCAST, WM_DWMCOLORIZATIONCOLORCHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); 25 } 26 } 27 28 void SetAppsTheme(bool mode) 29 { 30 HKEY hKey; 31 if (RegOpenKeyEx(HKEY_CURRENT_USER, 32 PERSONALIZATION_REGISTRY_PATH, 33 0, 34 KEY_SET_VALUE, 35 &hKey) == ERROR_SUCCESS) 36 { 37 DWORD value = mode; 38 RegSetValueEx(hKey, L"AppsUseLightTheme", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(value)); 39 RegCloseKey(hKey); 40 41 SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, reinterpret_cast<LPARAM>(L"ImmersiveColorSet"), SMTO_ABORTIFHUNG, 5000, nullptr); 42 43 SendMessageTimeout(HWND_BROADCAST, WM_THEMECHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); 44 } 45 } 46 47 void SetSystemTheme(bool mode) 48 { 49 HKEY hKey; 50 if (RegOpenKeyEx(HKEY_CURRENT_USER, 51 PERSONALIZATION_REGISTRY_PATH, 52 0, 53 KEY_SET_VALUE, 54 &hKey) == ERROR_SUCCESS) 55 { 56 DWORD value = mode; 57 RegSetValueEx(hKey, L"SystemUsesLightTheme", 0, REG_DWORD, reinterpret_cast<const BYTE*>(&value), sizeof(value)); 58 RegCloseKey(hKey); 59 60 if (mode) // if are changing to light mode 61 { 62 ResetColorPrevalence(); 63 Logger::info(L"[LightSwitchLib] Reset ColorPrevalence to default when switching to light mode."); 64 } 65 66 SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, reinterpret_cast<LPARAM>(L"ImmersiveColorSet"), SMTO_ABORTIFHUNG, 5000, nullptr); 67 68 SendMessageTimeout(HWND_BROADCAST, WM_THEMECHANGED, 0, 0, SMTO_ABORTIFHUNG, 5000, nullptr); 69 } 70 } 71 72 // Can think of this as "is the current theme light?" 73 bool GetCurrentSystemTheme() 74 { 75 HKEY hKey; 76 DWORD value = 1; // default = light 77 DWORD size = sizeof(value); 78 79 if (RegOpenKeyEx(HKEY_CURRENT_USER, 80 PERSONALIZATION_REGISTRY_PATH, 81 0, 82 KEY_READ, 83 &hKey) == ERROR_SUCCESS) 84 { 85 RegQueryValueEx(hKey, L"SystemUsesLightTheme", nullptr, nullptr, reinterpret_cast<LPBYTE>(&value), &size); 86 RegCloseKey(hKey); 87 } 88 89 return value == 1; // true = light, false = dark 90 } 91 92 bool GetCurrentAppsTheme() 93 { 94 HKEY hKey; 95 DWORD value = 1; 96 DWORD size = sizeof(value); 97 98 if (RegOpenKeyEx(HKEY_CURRENT_USER, 99 PERSONALIZATION_REGISTRY_PATH, 100 0, 101 KEY_READ, 102 &hKey) == ERROR_SUCCESS) 103 { 104 RegQueryValueEx(hKey, L"AppsUseLightTheme", nullptr, nullptr, reinterpret_cast<LPBYTE>(&value), &size); 105 RegCloseKey(hKey); 106 } 107 108 return value == 1; // true = light, false = dark 109 } 110 111 bool IsNightLightEnabled() 112 { 113 HKEY hKey; 114 const wchar_t* path = NIGHT_LIGHT_REGISTRY_PATH; 115 116 if (RegOpenKeyExW(HKEY_CURRENT_USER, path, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 117 return false; 118 119 // 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) 120 DWORD size = 0; 121 if (RegGetValueW(hKey, nullptr, L"Data", RRF_RT_REG_BINARY, nullptr, nullptr, &size) != ERROR_SUCCESS || size < 25) 122 { 123 RegCloseKey(hKey); 124 return false; 125 } 126 127 std::vector<BYTE> data(size); 128 if (RegGetValueW(hKey, nullptr, L"Data", RRF_RT_REG_BINARY, nullptr, data.data(), &size) != ERROR_SUCCESS) 129 { 130 RegCloseKey(hKey); 131 return false; 132 } 133 134 RegCloseKey(hKey); 135 return data[23] == 0x10 && data[24] == 0x00; 136 }