├── .gitignore ├── .gitmodules ├── Images └── Screenshot.png ├── LICENSE ├── README.md ├── Rectify11CPL ├── CControlPanelNavLink.cpp ├── CControlPanelNavLink.h ├── CControlPanelNavLinkCommand.h ├── CControlPanelNavLinks.cpp ├── CControlPanelNavLinks.h ├── CRectifyUtil.cpp ├── CRectifyUtil.h ├── ClassFactory.cpp ├── ClassFactory.h ├── ElementProvider.cpp ├── ElementProvider.h ├── ElevationManager.cpp ├── ElevationManager.h ├── FolderViewImpl.vcxproj.filters ├── Guid.h ├── IRectifyUtil.idl ├── IRectifyUtil_c.c ├── IRectifyUtil_h.h ├── IRectifyUtil_i.c ├── IRectifyUtil_p.c ├── IRectifyUtil_s.c ├── Rectify11CPL.def ├── Rectify11CPL.h ├── Rectify11CPL.rc ├── Rectify11CPL.vcxproj ├── Rectify11CPL.vcxproj.filters ├── RectifyMainPage.cpp ├── RectifyMainPage.h ├── RectifyMainPage.xml ├── RectifyThemeCfgPage.cpp ├── RectifyThemeCfgPage.h ├── RectifyThemeCfgPage.xml ├── Templetes.h ├── dlldata.c ├── dllmain.cpp ├── dllmain.h ├── icon.ico ├── pages.xml ├── preview_dark.bmp ├── preview_light.bmp ├── proxy.c ├── resource.h ├── taskslist.xml ├── theme.cpp ├── theme.h └── undoc.h ├── logo.png └── rectify11cpl.sln /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | *.user 3 | DirectUIx64/x64/ 4 | DirectUIx64/debug/ 5 | 6 | FolderViewImpl_Sample_folderview/x64/ 7 | FolderViewImpl_Sample_folderview/debug/ 8 | x64/ 9 | Rectify11Installer/ 10 | *.aps 11 | *.user -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dui70"] 2 | path = dui70 3 | url = https://github.com/MishaProductions/dui70 4 | -------------------------------------------------------------------------------- /Images/Screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Rectify11/RectifyControlPanel2/0007d9b37f0c529fb86428de30c5d528d8ff9b29/Images/Screenshot.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | --- 6 | 7 |
8 | 9 | [![Source Code](https://img.shields.io/badge/source_code-blue)](https://github.com/Rectify11/RectifyControlPanel2/tree/master/Rectify11CPL) 10 | [![Discord](https://img.shields.io/discord/1077324213142175744?style=flat-square)](https://discord.gg/gsgu9GCtsk) 11 | 12 | 13 |
14 | 15 | The first control panel applet not made by Microsoft to use Microsoft's DirectUI library 16 | 17 |
18 | 19 | 20 | ## Usage 21 | Build the Rectify11CPL project, and then register it using regsrv32 inside of admin command prompt. Make sure to restart explorer. 22 | 23 | ## Libaries used 24 | - https://github.com/seven-mile/dui70 - DirectUI library 25 | - https://github.com/namazso/SecureUxTheme - UxTheme patcher & theme changer 26 | 27 | -------------------------------------------------------------------------------- /Rectify11CPL/CControlPanelNavLink.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectify11CPL.h" 2 | #include "CControlPanelNavLinkCommand.h" 3 | #include "CControlPanelNavLink.h" 4 | 5 | HRESULT __cdecl CControlPanelNavLink::Create(CPNAV_LIST list, CControlPanelNavLink** result) 6 | { 7 | CControlPanelNavLink* navLink = new CControlPanelNavLink(); 8 | if (navLink != NULL) 9 | { 10 | navLink->m_Icon = NULL; 11 | navLink->m_Name = NULL; 12 | navLink->m_ExecType.m_ExecType = CPNAVTYPE_None; 13 | navLink->m_Type = list; 14 | *result = navLink; 15 | return S_OK; 16 | } 17 | else 18 | { 19 | return E_OUTOFMEMORY; 20 | } 21 | } 22 | 23 | void CControlPanelNavLink::SetName(LPCWSTR name) 24 | { 25 | SHStrDupW(name, &this->m_Name); 26 | } -------------------------------------------------------------------------------- /Rectify11CPL/CControlPanelNavLink.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class CControlPanelNavLink 3 | { 4 | public: 5 | static HRESULT Create(CPNAV_LIST list, CControlPanelNavLink** result); 6 | void SetName(LPCWSTR name); 7 | CPNAV_LIST m_Type; //0x00 8 | DWORD m_Unknown; //0x04 9 | WCHAR* m_Name; //0x08 10 | WCHAR* m_args; //0x18 11 | HICON m_Icon; //0x20 12 | CControlPanelNavLinkCommand m_ExecType; 13 | char unknown_bytes[0x33]; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /Rectify11CPL/CControlPanelNavLinkCommand.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class CControlPanelNavLinkCommand 3 | { 4 | public: 5 | CPNAVTYPE m_ExecType; 6 | DWORD m_space; 7 | LPWSTR m_AppletOrCommand; 8 | LPWSTR m_Arguments; 9 | }; 10 | 11 | -------------------------------------------------------------------------------- /Rectify11CPL/CControlPanelNavLinks.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectify11CPL.h" 2 | #include "CControlPanelNavLinks.h" 3 | #include "CControlPanelNavLink.h" 4 | #include "CControlPanelNavLinkCommand.h" 5 | 6 | CControlPanelNavLinks::CControlPanelNavLinks() 7 | { 8 | m_dpaList = NULL; 9 | m_refCount = 1; 10 | } 11 | 12 | void NavLinksDPA_DeleteCB(CControlPanelNavLink* p, void* pData) 13 | { 14 | delete p; 15 | } 16 | 17 | CControlPanelNavLinks::~CControlPanelNavLinks() 18 | { 19 | if (this->m_dpaList != NULL) { 20 | DPA_DestroyCallback(this->m_dpaList, (PFNDAENUMCALLBACKCONST)NavLinksDPA_DeleteCB, NULL); 21 | this->m_dpaList = NULL; 22 | } 23 | } 24 | 25 | IFACEMETHODIMP CControlPanelNavLinks::QueryInterface(REFIID riid, __out void** ppv) 26 | { 27 | *ppv = NULL; 28 | if (riid == IID_IUnknown) 29 | { 30 | *ppv = (IUnknown*)this; 31 | return S_OK; 32 | } 33 | return E_NOINTERFACE; 34 | } 35 | IFACEMETHODIMP_(ULONG) CControlPanelNavLinks::AddRef() 36 | { 37 | return InterlockedIncrement(&m_refCount); 38 | } 39 | IFACEMETHODIMP_(ULONG) CControlPanelNavLinks::Release() 40 | { 41 | ULONG ref = InterlockedDecrement(&m_refCount); 42 | if (ref == 0) 43 | { 44 | delete this; 45 | } 46 | return ref; 47 | } 48 | HRESULT CControlPanelNavLinks::AddLinkShellEx(LPCWSTR name, LPCWSTR file, LPCWSTR arguments, CPNAV_LIST DisplayType, HICON icon) 49 | { 50 | CControlPanelNavLink* link = NULL; 51 | HRESULT hr = CControlPanelNavLink::Create(DisplayType, &link); 52 | if (SUCCEEDED(hr)) 53 | { 54 | link->SetName(name); 55 | 56 | if (icon != NULL) 57 | { 58 | link->m_Icon = icon; 59 | } 60 | 61 | link->m_ExecType.m_ExecType = CPNAVTYPE_ShellExec; 62 | SHStrDupW(file, &link->m_ExecType.m_AppletOrCommand); 63 | SHStrDupW(arguments, &link->m_ExecType.m_Arguments); 64 | return Add(link); 65 | } 66 | else 67 | { 68 | return hr; 69 | } 70 | } 71 | HRESULT CControlPanelNavLinks::AddLinkControlPanel(LPCWSTR name, LPCWSTR path, LPCWSTR arguments, CPNAV_LIST DisplayType, HICON icon) 72 | { 73 | CControlPanelNavLink* link = NULL; 74 | HRESULT hr = CControlPanelNavLink::Create(DisplayType, &link); 75 | if (SUCCEEDED(hr)) 76 | { 77 | link->SetName(name); 78 | 79 | if (icon != NULL) 80 | { 81 | link->m_Icon = icon; 82 | } 83 | 84 | link->m_ExecType.m_ExecType = CPNAVTYPE_Navigate; 85 | SHStrDupW(path, &link->m_ExecType.m_AppletOrCommand); 86 | SHStrDupW(arguments, &link->m_ExecType.m_Arguments); 87 | return Add(link); 88 | } 89 | else 90 | { 91 | return hr; 92 | } 93 | } 94 | 95 | HRESULT CControlPanelNavLinks::Add(CControlPanelNavLink* link) 96 | { 97 | if (m_dpaList == NULL) 98 | { 99 | m_dpaList = DPA_Create(10); 100 | if (m_dpaList == NULL) 101 | { 102 | return E_OUTOFMEMORY; 103 | } 104 | } 105 | if (DPA_InsertPtr(m_dpaList, 0x7fffffff, link) != -1) 106 | { 107 | return S_OK; 108 | } 109 | else 110 | { 111 | return E_OUTOFMEMORY; 112 | } 113 | } -------------------------------------------------------------------------------- /Rectify11CPL/CControlPanelNavLinks.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class CControlPanelNavLinks : public IUnknown 3 | { 4 | public: 5 | CControlPanelNavLinks(); 6 | 7 | IFACEMETHODIMP QueryInterface(REFIID riid, __out void** ppv); 8 | IFACEMETHODIMP_(ULONG) AddRef(); 9 | IFACEMETHODIMP_(ULONG) Release(); 10 | 11 | HRESULT AddLinkControlPanel(LPCWSTR name, LPCWSTR path, LPCWSTR arguments, CPNAV_LIST DisplayType, HICON icon); 12 | HRESULT AddLinkShellEx(LPCWSTR name, LPCWSTR file, LPCWSTR arguments, CPNAV_LIST DisplayType, HICON icon); 13 | HRESULT Add(CControlPanelNavLink* link); 14 | virtual ~CControlPanelNavLinks(); 15 | private: 16 | HDPA m_dpaList; 17 | long m_refCount; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /Rectify11CPL/CRectifyUtil.cpp: -------------------------------------------------------------------------------- 1 | // This class implements the IRectifyUtil interface. This class is registered as a COM object to allow the code 2 | // to be ran as administrator, without elevating explorer.exe or starting another process 3 | 4 | #include "Rectify11CPL.h" 5 | #include "CRectifyUtil.h" 6 | #include "psapi.h" 7 | #include 8 | #include 9 | #include 10 | #include "Guid.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma comment(lib, "taskschd.lib") 17 | #pragma comment(lib, "comsupp.lib") 18 | #pragma comment(lib, "comsuppw.lib") 19 | 20 | WCHAR Rectify11PrefsKey[] = L"SOFTWARE\\Rectify11Prefs"; 21 | 22 | CRectifyUtil::CRectifyUtil() : m_ref(1) 23 | { 24 | DllAddRef(); 25 | } 26 | 27 | CRectifyUtil::~CRectifyUtil() 28 | { 29 | DllRelease(); 30 | } 31 | 32 | DWORD FindProcessId(const WCHAR* procname) 33 | { 34 | HANDLE hSnapshot; 35 | PROCESSENTRY32 pe; 36 | int pid = 0; 37 | BOOL hResult; 38 | 39 | memset(&pe, 0, sizeof(pe)); 40 | 41 | // snapshot of all processes in the system 42 | hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 43 | if (INVALID_HANDLE_VALUE == hSnapshot) return 0; 44 | 45 | // initializing size: needed for using Process32First 46 | pe.dwSize = sizeof(PROCESSENTRY32); 47 | 48 | // info about first process encountered in a system snapshot 49 | hResult = Process32First(hSnapshot, &pe); 50 | 51 | // retrieve information about the processes 52 | // and exit if unsuccessful 53 | while (hResult) { 54 | // if we find the process: return process ID 55 | if (wcscmp(procname, pe.szExeFile) == 0) { 56 | pid = pe.th32ProcessID; 57 | break; 58 | } 59 | hResult = Process32Next(hSnapshot, &pe); 60 | } 61 | 62 | // closes an open handle (CreateToolhelp32Snapshot) 63 | CloseHandle(hSnapshot); 64 | return pid; 65 | } 66 | 67 | HRESULT deleteTask(std::wstring taskName) 68 | { 69 | HRESULT hr = S_OK; 70 | 71 | ITaskService* pITS = NULL; 72 | hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pITS); 73 | if (FAILED(hr)) { 74 | return hr; 75 | } 76 | 77 | hr = pITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); 78 | if (FAILED(hr)) { 79 | pITS->Release(); 80 | return hr; 81 | } 82 | 83 | ITaskFolder* pITF; 84 | hr = pITS->GetFolder(_bstr_t(L"\\"), &pITF); 85 | if (FAILED(hr)) { 86 | pITS->Release(); 87 | return hr; 88 | } 89 | 90 | pITS->Release(); 91 | 92 | hr = pITF->DeleteTask(_bstr_t(taskName.c_str()), 0); 93 | if (FAILED(hr)) { 94 | pITF->Release(); 95 | return hr; 96 | } 97 | 98 | pITF->Release(); 99 | 100 | return hr; 101 | } 102 | 103 | HRESULT taskExists(wstring taskName, BOOL* taskExists) 104 | { 105 | HRESULT hr = S_OK; 106 | *taskExists = FALSE; 107 | ITaskService* pITS = NULL; 108 | hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pITS); 109 | if (FAILED(hr)) { 110 | return hr; 111 | } 112 | 113 | hr = pITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); 114 | if (FAILED(hr)) { 115 | pITS->Release(); 116 | return hr; 117 | } 118 | 119 | ITaskFolder* pITF; 120 | hr = pITS->GetFolder(_bstr_t(L"\\"), &pITF); 121 | if (FAILED(hr)) { 122 | pITS->Release(); 123 | return hr; 124 | } 125 | 126 | pITS->Release(); 127 | 128 | IRegisteredTask* task = NULL; 129 | hr = pITF->GetTask(_bstr_t(taskName.c_str()), &task); 130 | if (FAILED(hr)) { 131 | pITF->Release(); 132 | return hr; 133 | } 134 | else 135 | { 136 | *taskExists = TRUE; 137 | } 138 | 139 | pITF->Release(); 140 | 141 | return hr; 142 | } 143 | 144 | HRESULT createTask(std::wstring taskName, std::wstring taskExe) 145 | { 146 | HRESULT hr = S_OK; 147 | 148 | ITaskService* pITS = NULL; 149 | hr = CoCreateInstance(CLSID_TaskScheduler, nullptr, CLSCTX_INPROC_SERVER, IID_ITaskService, (void**)&pITS); 150 | if (FAILED(hr)) { 151 | return hr; 152 | } 153 | 154 | hr = pITS->Connect(_variant_t(), _variant_t(), _variant_t(), _variant_t()); 155 | if (FAILED(hr)) { 156 | pITS->Release(); 157 | return hr; 158 | } 159 | 160 | ITaskFolder* pITF; 161 | hr = pITS->GetFolder(_bstr_t(L"\\"), &pITF); 162 | if (FAILED(hr)) { 163 | pITS->Release(); 164 | return hr; 165 | } 166 | 167 | wstring taskxml = wstring(L""); 168 | taskxml += L"\\"; 169 | taskxml += taskName; 170 | taskxml += L"trueS-1-5-32-545HighestAvailableIgnoreNewfalsefalsetruefalsefalsetruefalsetruetruefalsefalsefalsePT0S5"; 171 | taskxml += taskExe; 172 | taskxml += L""; 173 | 174 | pITS->Release(); 175 | IRegisteredTask* task; 176 | hr = pITF->RegisterTask(_bstr_t(taskName.c_str()), _bstr_t(taskxml.c_str()), TASK_CREATE_OR_UPDATE, variant_t(), variant_t(), TASK_LOGON_INTERACTIVE_TOKEN, variant_t(), &task); 177 | if (FAILED(hr)) { 178 | pITF->Release(); 179 | return hr; 180 | } 181 | 182 | pITF->Release(); 183 | 184 | return hr; 185 | } 186 | 187 | int DeleteDirectory(const std::string& refcstrRootDirectory, 188 | bool bDeleteSubdirectories = true) 189 | { 190 | bool bSubdirectory = false; // Flag, indicating whether 191 | // subdirectories have been found 192 | HANDLE hFile; // Handle to directory 193 | std::string strFilePath; // Filepath 194 | std::string strPattern; // Pattern 195 | WIN32_FIND_DATAA FileInformation; // File information 196 | 197 | 198 | strPattern = refcstrRootDirectory + "\\*.*"; 199 | hFile = ::FindFirstFileA(strPattern.c_str(), &FileInformation); 200 | if (hFile != INVALID_HANDLE_VALUE) 201 | { 202 | do 203 | { 204 | if (FileInformation.cFileName[0] != '.') 205 | { 206 | strFilePath.erase(); 207 | strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName; 208 | 209 | if (FileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) 210 | { 211 | if (bDeleteSubdirectories) 212 | { 213 | // Delete subdirectory 214 | int iRC = DeleteDirectory(strFilePath, bDeleteSubdirectories); 215 | if (iRC) 216 | return iRC; 217 | } 218 | else 219 | bSubdirectory = true; 220 | } 221 | else 222 | { 223 | // Set file attributes 224 | if (::SetFileAttributesA(strFilePath.c_str(), 225 | FILE_ATTRIBUTE_NORMAL) == FALSE) 226 | return ::GetLastError(); 227 | 228 | // Delete file 229 | if (::DeleteFileA(strFilePath.c_str()) == FALSE) 230 | return ::GetLastError(); 231 | } 232 | } 233 | } while (::FindNextFileA(hFile, &FileInformation) == TRUE); 234 | 235 | // Close handle 236 | ::FindClose(hFile); 237 | 238 | DWORD dwError = ::GetLastError(); 239 | if (dwError != ERROR_NO_MORE_FILES) 240 | return dwError; 241 | else 242 | { 243 | if (!bSubdirectory) 244 | { 245 | // Set directory attributes 246 | if (::SetFileAttributesA(refcstrRootDirectory.c_str(), 247 | FILE_ATTRIBUTE_NORMAL) == FALSE) 248 | return ::GetLastError(); 249 | 250 | // Delete directory 251 | if (::RemoveDirectoryA(refcstrRootDirectory.c_str()) == FALSE) 252 | return ::GetLastError(); 253 | } 254 | } 255 | } 256 | 257 | return 0; 258 | } 259 | 260 | BOOL CRectifyUtil::KillTask(wstring proc) 261 | { 262 | while (1) 263 | { 264 | DWORD pid = FindProcessId(proc.c_str()); 265 | if (pid == 0) 266 | { 267 | return FALSE; 268 | } 269 | 270 | const auto proc = OpenProcess(PROCESS_TERMINATE, false, pid); 271 | BOOL result = TerminateProcess(proc, 1); 272 | CloseHandle(proc); 273 | } 274 | return TRUE; 275 | } 276 | 277 | 278 | HRESULT startProc(LPCWSTR proc, wstring args = L"", bool waitForExit = false) 279 | { 280 | STARTUPINFOW si; 281 | PROCESS_INFORMATION pi; 282 | ZeroMemory(&si, sizeof(si)); 283 | si.cb = sizeof(si); 284 | ZeroMemory(&pi, sizeof(pi)); 285 | 286 | WCHAR proc_buffer[1000]; 287 | if (proc) 288 | { 289 | ExpandEnvironmentStringsW(proc, proc_buffer, 999); 290 | } 291 | 292 | WCHAR args_buffer[1000] = { 0 }; 293 | if (!args.empty()) 294 | { 295 | wcsncpy_s(args_buffer, 999, args.c_str(), args.size()); 296 | } 297 | BOOL hr = CreateProcessW(proc ? proc_buffer : NULL, 298 | args_buffer, // Command line 299 | NULL, // Process handle not inheritable 300 | NULL, // Thread handle not inheritable 301 | FALSE, // Set handle inheritance to FALSE 302 | CREATE_NO_WINDOW, // No creation flags 303 | NULL, // Use parent's environment block 304 | NULL, // Use parent's starting directory 305 | &si, // Pointer to STARTUPINFO structure 306 | &pi // Pointer to PROCESS_INFORMATION structure 307 | ); 308 | 309 | if (!hr) 310 | { 311 | WCHAR error_buffer[1000]; 312 | 313 | DWORD err = GetLastError(); 314 | std::string message = std::system_category().message(err); 315 | 316 | std::wstring_convert> converter; 317 | 318 | std::wstring messageUnicode = converter.from_bytes(message); 319 | 320 | swprintf_s(error_buffer, L"Error while starting process %s with arguments %s: %s (%ld)", proc, args.c_str(), messageUnicode.c_str(), err); 321 | MessageBox(NULL, error_buffer, TEXT("Starting process failed"), MB_ICONERROR); 322 | } 323 | else 324 | { 325 | if (waitForExit) 326 | { 327 | // Successfully created the process. Wait for it to finish. 328 | WaitForSingleObject(pi.hProcess, INFINITE); 329 | DWORD exitCode; 330 | // Get the exit code. 331 | hr = GetExitCodeProcess(pi.hProcess, &exitCode); 332 | } 333 | } 334 | 335 | CloseHandle(pi.hProcess); 336 | CloseHandle(pi.hThread); 337 | return hr ? S_OK : S_FALSE; 338 | } 339 | 340 | bool check_if_file_exists(std::wstring path) 341 | { 342 | std::ifstream ff(path.c_str()); 343 | return ff.is_open(); 344 | } 345 | size_t GetSizeOfFile(const std::wstring& path) 346 | { 347 | struct _stat fileinfo; 348 | _wstat(path.c_str(), &fileinfo); 349 | return fileinfo.st_size; 350 | } 351 | 352 | std::wstring LoadUtf8FileToString(const std::wstring& filename) 353 | { 354 | std::wstring buffer; // stores file contents 355 | FILE* f = NULL; 356 | _wfopen_s(&f, filename.c_str(), L"rtS, ccs=UTF-8"); 357 | 358 | // Failed to open file 359 | if (f == NULL) 360 | { 361 | // ...handle some error... 362 | return buffer; 363 | } 364 | 365 | size_t filesize = GetSizeOfFile(filename); 366 | 367 | // Read entire file contents in to memory 368 | if (filesize > 0) 369 | { 370 | buffer.resize(filesize); 371 | size_t wchars_read = fread(&(buffer.front()), sizeof(wchar_t), filesize, f); 372 | buffer.resize(wchars_read); 373 | buffer.shrink_to_fit(); 374 | } 375 | 376 | fclose(f); 377 | 378 | return buffer; 379 | } 380 | 381 | void CRectifyUtil::RestartExplorer() 382 | { 383 | HWND hwnd = FindWindow(L"Shell_TrayWnd", NULL); 384 | DWORD pid = {}; 385 | GetWindowThreadProcessId(hwnd, &pid); 386 | 387 | HANDLE h_explorer; 388 | h_explorer = OpenProcess(PROCESS_TERMINATE, false, pid); 389 | TerminateProcess(h_explorer, 2); 390 | CloseHandle(h_explorer); 391 | 392 | startProc(L"C:\\windows\\explorer.exe"); 393 | } 394 | 395 | HRESULT CreateLink(LPCWSTR lpszTarget, LPCWSTR lpszDesc, LPCWSTR lpszWorkingDir, LPCSTR lpszShortcutPath) 396 | { 397 | HRESULT hres; 398 | IShellLink* psl = NULL; 399 | 400 | // Get a pointer to the IShellLink interface. It is assumed that CoInitialize 401 | // has already been called. 402 | hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl); 403 | if (SUCCEEDED(hres)) 404 | { 405 | IPersistFile* ppf = NULL; 406 | 407 | // Set the path to the shortcut target and add the description. 408 | psl->SetPath(lpszTarget); 409 | psl->SetDescription(lpszDesc); 410 | psl->SetWorkingDirectory(lpszWorkingDir); 411 | 412 | // Query IShellLink for the IPersistFile interface, used for saving the 413 | // shortcut in persistent storage. 414 | hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); 415 | 416 | if (SUCCEEDED(hres)) 417 | { 418 | WCHAR wsz[MAX_PATH]; 419 | 420 | // Ensure that the string is Unicode. 421 | MultiByteToWideChar(CP_ACP, 0, lpszShortcutPath, -1, wsz, MAX_PATH); 422 | 423 | // Save the link by calling IPersistFile::Save. 424 | hres = ppf->Save(wsz, TRUE); 425 | ppf->Release(); 426 | } 427 | psl->Release(); 428 | } 429 | return hres; 430 | } 431 | /// 432 | /// Check if mica for everyone is enabled 433 | /// 434 | /// Returns if Mica for everyone is enabled 435 | HRESULT CRectifyUtil::GetMicaSettings(BOOL* pEnabled, BOOL* pTabbed) 436 | { 437 | *pEnabled = FALSE; 438 | *pTabbed = FALSE; 439 | 440 | taskExists(L"mfe", pEnabled); 441 | 442 | // read mfe config file 443 | struct stat sb; 444 | wstring config_file = wstring(L"c:\\windows\\micaforeveryone\\MicaForEveryone.conf"); 445 | if (stat("c:\\windows\\micaforeveryone\\MicaForEveryone.conf", &sb) == 0) 446 | { 447 | wstring config = LoadUtf8FileToString(config_file); 448 | if (config.compare(L"Tabbed")) 449 | { 450 | *pTabbed = TRUE; 451 | } 452 | } 453 | 454 | 455 | return S_OK; 456 | } 457 | 458 | HRESULT CRectifyUtil::_EnableClassicTransparent() 459 | { 460 | CHAR path[MAX_PATH]; 461 | HRESULT hr = SHGetFolderPathA(NULL, CSIDL_COMMON_STARTMENU, NULL, 0, path); 462 | if (SUCCEEDED(hr)) 463 | { 464 | WCHAR workingdir_buffer[MAX_PATH]; 465 | ExpandEnvironmentStringsW(L"%windir%\\nilesoft\\AcrylicMenus", workingdir_buffer, MAX_PATH); 466 | 467 | WCHAR target_buffer[MAX_PATH] = { 0 }; 468 | ExpandEnvironmentStringsW(L"%windir%\\nilesoft\\AcrylicMenus\\AcrylicMenusLoader.exe", target_buffer, MAX_PATH); 469 | 470 | string shortcut_path = string(path); 471 | shortcut_path += +"\\programs\\startup\\acrylmenu.lnk"; 472 | startProc(target_buffer); 473 | return CreateLink(target_buffer, L"Launch classic transparent menu hook", workingdir_buffer, shortcut_path.c_str()); 474 | } 475 | else 476 | { 477 | return hr; 478 | } 479 | } 480 | 481 | HRESULT CRectifyUtil::_DeleteClassicTransparent() 482 | { 483 | CHAR path[MAX_PATH]; 484 | HRESULT hr = SHGetFolderPathA(NULL, CSIDL_COMMON_STARTMENU, NULL, 0, path); 485 | KillTask(L"AcrylicMenusLoader.exe"); 486 | if (SUCCEEDED(hr)) 487 | { 488 | string file = string(path); 489 | file += +"\\programs\\startup\\acrylmenu.lnk"; 490 | return DeleteFileA(file.c_str()) ? S_OK : E_ACTIVATIONDENIED_SHELLNOTREADY; 491 | } 492 | else 493 | { 494 | return hr; 495 | } 496 | } 497 | HRESULT CRectifyUtil::_EnableClassicMenu() 498 | { 499 | HKEY result; 500 | HRESULT status = RegCreateKey(HKEY_CURRENT_USER, TEXT("Software\\Classes\\CLSID\\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}"), &result); 501 | if (SUCCEEDED(status)) 502 | { 503 | HKEY inprocServer; 504 | HRESULT status = RegCreateKey(result, TEXT("InprocServer32"), &inprocServer); 505 | if (SUCCEEDED(status)) 506 | { 507 | RegSetValueExW(inprocServer, NULL, 0, REG_SZ, (const BYTE*)L"", 2); 508 | RegCloseKey(inprocServer); 509 | return S_OK; 510 | } 511 | RegCloseKey(result); 512 | return status; 513 | } 514 | return status; 515 | } 516 | 517 | HRESULT CRectifyUtil::_DeleteNilesoftIfExists() 518 | { 519 | struct stat sb; 520 | if (stat("c:\\windows\\nilesoft\\shell.nss", &sb) == 0) 521 | { 522 | // delete configuration file 523 | BOOL h = DeleteFile(TEXT("c:\\windows\\nilesoft\\shell.nss")); 524 | if (!h) 525 | { 526 | WCHAR buffer[200]; 527 | 528 | swprintf(buffer, 199, L"Failed to uninstall nilesoft. failed to delete config file. hresult is %d\n", GetLastError()); 529 | MessageBox(NULL, buffer, TEXT("_DeleteNilesoftIfExists"), MB_ICONERROR); 530 | } 531 | 532 | startProc(NULL, L"c:\\windows\\nilesoft\\shell.exe -unregister", true); 533 | return S_OK; 534 | } 535 | return S_OK; 536 | } 537 | 538 | /// 539 | /// Enable/disable micaforeveryone tool 540 | /// 541 | /// 542 | HRESULT CRectifyUtil::SetMicaForEveryoneEnabled(BOOL micaEnabled, BOOL tabbed) 543 | { 544 | HRESULT hr = S_OK; 545 | WCHAR value[255] = { 0 }; 546 | PVOID pvData = value; 547 | DWORD size = sizeof(value); 548 | RegGetValue(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager", L"DllName", RRF_RT_REG_SZ, 0, pvData, &size); 549 | std::wstring msstylePath = std::wstring((LPCWSTR)pvData); 550 | 551 | std::wstring currentThemeName = msstylePath; 552 | 553 | const size_t last_slash_idx = currentThemeName.find_last_of(L"\\/"); 554 | if (std::string::npos != last_slash_idx) 555 | { 556 | currentThemeName.erase(0, last_slash_idx + 1); 557 | } 558 | 559 | // Remove extension if present. 560 | const size_t period_idx = currentThemeName.rfind('.'); 561 | if (std::string::npos != period_idx) 562 | { 563 | currentThemeName.erase(period_idx); 564 | } 565 | 566 | WCHAR buffer[1024]; 567 | if (micaEnabled) 568 | { 569 | struct stat sb; 570 | if (stat("c:/windows/MicaForEveryone", &sb) == 0) 571 | { 572 | // kill micaforeveryone and explorerframe if already running 573 | KillTask(L"MicaForEveryone.exe"); 574 | KillTask(L"ExplorerFrame.exe"); 575 | 576 | char* localappdata = nullptr; 577 | size_t sz = 0; 578 | if (_dupenv_s(&localappdata, &sz, "localappdata") == 0 && localappdata != nullptr) 579 | { 580 | string appdata = string(localappdata); 581 | string micaFolder = appdata + "/Mica For Everyone/"; 582 | if (stat(micaFolder.c_str(), &sb) != 0) 583 | { 584 | if (DeleteDirectory(micaFolder.c_str())) 585 | { 586 | MessageBox(NULL, L"Failed to delete local micaforeveryone folder.", L"Failed to create MFE task", MB_ICONERROR); 587 | } 588 | } 589 | HRESULT hr = createTask(TEXT("mfe"), TEXT("%systemroot%\\MicaForEveryone\\MicaForEveryone.exe")); 590 | if (FAILED(hr)) 591 | { 592 | swprintf(buffer, 1024, L"Failed create MFE task: %x", hr); 593 | MessageBox(NULL, buffer, L"Failed to create MFE task", MB_ICONERROR); 594 | } 595 | 596 | wstring config_file_src = wstring(L"c:\\windows\\micaforeveryone\\CONF\\"); 597 | if (tabbed) 598 | config_file_src += L"T"; 599 | config_file_src += currentThemeName; 600 | config_file_src += L".conf"; 601 | 602 | if (!check_if_file_exists(config_file_src)) 603 | { 604 | swprintf(buffer, 1024, L"Warning: Micaforeveryone configuration file is missing! File name is %ws. Try reinstalling themes option in Rectify11 Installer", config_file_src.c_str()); 605 | MessageBox(NULL, buffer, L"Rectify11 control panel applet", MB_ICONWARNING); 606 | } 607 | else 608 | { 609 | if (!CopyFileExW(config_file_src.c_str(), L"c:\\windows\\micaforeveryone\\MicaForEveryone.conf", NULL, NULL, NULL, 0)) 610 | { 611 | swprintf(buffer, 1024, L"Warning: Failed to copy micaforeveryone configuration file with result %x", GetLastError()); 612 | MessageBox(NULL, buffer, L"Warning", MB_ICONWARNING); 613 | } 614 | } 615 | 616 | // Enable micafix if black theme 617 | if (currentThemeName.compare(L"black")) 618 | { 619 | createTask(L"mfefix", L"%systemroot%\\MicaForEveryone\\EFamd64\\ExplorerFrame.exe"); 620 | startProc(L"%systemroot%\\MicaForEveryone\\EFamd64\\ExplorerFrame.exe"); 621 | } 622 | else 623 | { 624 | deleteTask(L"mfefix"); 625 | KillTask(L"ExplorerFrame.exe"); 626 | } 627 | 628 | // Start mica for everyone 629 | startProc(L"%systemroot%\\MicaForEveryone\\MicaForEveryone.exe"); 630 | } 631 | else 632 | { 633 | MessageBox(NULL, L"Appdata env variable not found", L"Failed to create MFE task", MB_ICONERROR); 634 | } 635 | } 636 | else 637 | { 638 | MessageBox(NULL, L"Micaforeveryone is not correctly installed. Please rerun the rectify11 installed.", L"Failed to create MFE task", MB_ICONERROR); 639 | } 640 | } 641 | else 642 | { 643 | BOOL mfeExists; 644 | taskExists(L"mfe", &mfeExists); 645 | if (FAILED(deleteTask(L"mfe")) && mfeExists) 646 | { 647 | MessageBox(NULL, L"Failed to delete MFE task", L"Failed to delete MFE task", MB_ICONERROR); 648 | } 649 | deleteTask(L"mfefix"); 650 | KillTask(L"MicaForEveryone.exe"); 651 | KillTask(L"ExplorerFrame.exe"); 652 | } 653 | return hr; 654 | } 655 | 656 | HRESULT CRectifyUtil::GetCurrentMenuIndex(DWORD* menuIndex) 657 | { 658 | *menuIndex = Normal; 659 | struct stat sb; 660 | if (stat("c:\\windows\\nilesoft\\shell.nss", &sb) != 0) 661 | { 662 | HKEY key = HKEY_CURRENT_USER; 663 | HKEY result; 664 | LONG hr = RegOpenKeyEx(key, L"Software\\Classes\\CLSID\\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}", 0, KEY_READ, &result); 665 | 666 | 667 | if (hr == 0) 668 | { 669 | *menuIndex = Classic; 670 | RegCloseKey(result); 671 | } 672 | 673 | CHAR path[MAX_PATH]; 674 | 675 | hr = SHGetFolderPathA(NULL, CSIDL_COMMON_STARTMENU, NULL, 0, path); 676 | 677 | string file = string(path); 678 | file += +"\\programs\\startup\\acrylmenu.lnk"; 679 | if (stat(file.c_str(), &sb) == 0) 680 | { 681 | *menuIndex = ClassicTransparent; 682 | } 683 | } 684 | else 685 | { 686 | wstring config = LoadUtf8FileToString(L"c:\\windows\\nilesoft\\shell.nss"); 687 | if (config.compare(L"modify(where=this.title.length > 15 menu=title.more_options)")) 688 | { 689 | *menuIndex = NilesoftSmall; 690 | } 691 | else 692 | { 693 | *menuIndex = NilesoftFull; 694 | } 695 | } 696 | return S_OK; 697 | } 698 | 699 | HRESULT CRectifyUtil::SetCurrentMenuByIndex(DWORD menuIndex) 700 | { 701 | HRESULT hr = S_OK; 702 | if (menuIndex == Normal) 703 | { 704 | // Restore default Windows 11 menus 705 | hr = RegDeleteTree(HKEY_CURRENT_USER, TEXT("Software\\Classes\\CLSID\\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}")); 706 | _DeleteClassicTransparent(); 707 | _DeleteNilesoftIfExists(); 708 | } 709 | else if (menuIndex == NilesoftSmall) 710 | { 711 | std::wofstream f(L"c:\\windows\\nilesoft\\shell.nss"); 712 | f.clear(); 713 | f << "settings\r\n{\r\n priority=1\r\n exclude.where = !process.is_explorer\r\n showdelay = 100\r\n // Options to allow modification of system items\r\n modify.remove.duplicate=1\r\n tip\r\n {\r\n enabled=1\r\n opacity=100\r\n width=400\r\n radius=1\r\n time=1.25\r\n padding=[10,10]\r\n }\r\n}\r\ntheme\r\n{\r\n name=\"modern\"\r\n}\r\nimport 'imports/theme.nss'\r\nimport 'imports/images.nss'\r\n\r\nimport 'imports/modify.nss'\r\nmodify(where=this.title.length > 15 menu=title.more_options)\r\n\r\nmenu(mode=\"multiple\" title=\"Pin/Unpin\" image=icon.pin) {}\r\nmenu(mode=\"multiple\" title=title.more_options image=icon.more_options) {}\r\nimport 'imports/taskbar.nss'"; 714 | f.close(); 715 | 716 | startProc(NULL, L"c:\\windows\\nilesoft\\shell.exe -register", true); 717 | 718 | 719 | } 720 | else if (menuIndex == NilesoftFull) 721 | { 722 | std::wofstream f(L"c:\\windows\\nilesoft\\shell.nss"); 723 | f.clear(); 724 | f << "settings\r\n{\r\n priority=1\r\n exclude.where = !process.is_explorer\r\n showdelay = 100\r\n // Options to allow modification of system items\r\n modify.remove.duplicate=1\r\n tip\r\n {\r\n enabled=1\r\n opacity=100\r\n width=400\r\n radius=1\r\n time=1.25\r\n padding=[10,10]\r\n }\r\n}\r\ntheme\r\n{\r\n name=\"modern\"\r\n}\r\nimport 'imports/theme.nss'\r\nimport 'imports/images.nss'\r\n\r\nimport 'imports/modify.nss'\r\nmenu(mode=\"multiple\" title=\"Pin/Unpin\" image=icon.pin) {}\r\nmenu(mode=\"multiple\" title=title.more_options image=icon.more_options) {}\r\nimport 'imports/taskbar.nss'"; 725 | f.close(); 726 | 727 | startProc(NULL, L"c:\\windows\\nilesoft\\shell.exe -register", true); 728 | } 729 | else if (menuIndex == Classic) 730 | { 731 | _DeleteClassicTransparent(); 732 | _DeleteNilesoftIfExists(); 733 | hr = _EnableClassicMenu(); 734 | } 735 | else if (menuIndex == ClassicTransparent) 736 | { 737 | _DeleteNilesoftIfExists(); 738 | hr = _EnableClassicMenu(); 739 | if (SUCCEEDED(hr)) 740 | { 741 | hr = _EnableClassicTransparent(); 742 | } 743 | } 744 | else 745 | { 746 | WCHAR buffer[200]; 747 | 748 | swprintf(buffer, 199, L"Failed to update menu settings. Unknown enum index %d", menuIndex); 749 | MessageBox(NULL, buffer, TEXT("SetCurrentMenuByIndex"), MB_ICONERROR); 750 | hr = E_NOTIMPL; 751 | } 752 | 753 | return hr; 754 | } 755 | 756 | static bool themetool_loaded = false; 757 | HRESULT CRectifyUtil::ApplyTheme(LPCWSTR pThemeName) 758 | { 759 | HRESULT hr = S_OK; 760 | if (!themetool_loaded) 761 | { 762 | hr = themetool_init(); 763 | } 764 | 765 | if (FAILED(hr)) 766 | { 767 | return hr; 768 | } 769 | else { 770 | themetool_loaded = true; 771 | } 772 | ULONG apply_flags = 0; 773 | 774 | // load appy flags 775 | HKEY Rectify11; 776 | if (RegCreateKey(HKEY_CURRENT_USER, Rectify11PrefsKey, &Rectify11)) 777 | { 778 | SHOW_ERROR("Failed to create Rectify11Prefs key"); 779 | } 780 | 781 | DWORD size = 4; 782 | 783 | DWORD IgnoreBgVal = 0; 784 | DWORD IgnoreCursorsVal = 0; 785 | DWORD IgnoreIconsVal = 0; 786 | DWORD IgnoreColorsVal = 0; 787 | DWORD IgnoreSoundsVal = 0; 788 | DWORD IgnoreScreensaversVal = 0; 789 | 790 | RegQueryValueExW(Rectify11, L"IgnoreBg", 0, NULL, (LPBYTE)&IgnoreBgVal, &size); 791 | RegQueryValueExW(Rectify11, L"IgnoreCursors", 0, NULL, (LPBYTE)&IgnoreCursorsVal, &size); 792 | RegQueryValueExW(Rectify11, L"IgnoreIcons", 0, NULL, (LPBYTE)&IgnoreIconsVal, &size); 793 | RegQueryValueExW(Rectify11, L"IgnoreColors", 0, NULL, (LPBYTE)&IgnoreColorsVal, &size); 794 | RegQueryValueExW(Rectify11, L"IgnoreSounds", 0, NULL, (LPBYTE)&IgnoreSoundsVal, &size); 795 | RegQueryValueExW(Rectify11, L"IgnoreScreensavers", 0, NULL, (LPBYTE)&IgnoreScreensaversVal, &size); 796 | RegCloseKey(Rectify11); 797 | 798 | if (IgnoreBgVal) 799 | { 800 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_BACKGROUND; 801 | } 802 | if (IgnoreCursorsVal) 803 | { 804 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_CURSOR; 805 | } 806 | if (IgnoreIconsVal) 807 | { 808 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_DESKTOP_ICONS; 809 | } 810 | if (IgnoreColorsVal) 811 | { 812 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_COLOR; 813 | } 814 | if (IgnoreSoundsVal) 815 | { 816 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_SOUND; 817 | } 818 | if (IgnoreSoundsVal) 819 | { 820 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_SCREENSAVER; 821 | } 822 | 823 | 824 | ULONG themeCount = 0; 825 | themetool_get_theme_count(&themeCount); 826 | if (FAILED(hr)) 827 | { 828 | return hr; 829 | } 830 | std::wstring targetTheme(pThemeName); 831 | std::transform(targetTheme.begin(), targetTheme.end(), targetTheme.begin(), ::tolower); 832 | 833 | for (ULONG i = 0; i < themeCount; i++) 834 | { 835 | ITheme* theme = NULL; 836 | themetool_get_theme(i, &theme); 837 | 838 | WCHAR buffer[512]; 839 | themetool_theme_get_display_name(theme, buffer, 256); 840 | 841 | std::wstring displayName(buffer); 842 | std::transform(displayName.begin(), displayName.end(), displayName.begin(), ::tolower); 843 | 844 | if (displayName == targetTheme) 845 | { 846 | hr = themetool_set_active(NULL, i, TRUE, 0, 0); 847 | 848 | themetool_theme_release(theme); 849 | break; 850 | } 851 | 852 | themetool_theme_release(theme); 853 | } 854 | return hr; 855 | } 856 | HRESULT CRectifyUtil::InstallThemeTool() 857 | { 858 | HRESULT hr = S_OK; 859 | if (!themetool_loaded) 860 | { 861 | hr = themetool_init(); 862 | } 863 | 864 | if (hr != S_OK) 865 | { 866 | return hr; 867 | } 868 | else { 869 | themetool_loaded = true; 870 | } 871 | 872 | hr = secureuxtheme_install(SECUREUXTHEME_INSTALL_HOOK_LOGONUI | SECUREUXTHEME_INSTALL_RENAME_DEFAULTCOLORS); 873 | return hr; 874 | } 875 | HRESULT CRectifyUtil::UninstallThemeTool() 876 | { 877 | HRESULT hr = S_OK; 878 | if (!themetool_loaded) 879 | { 880 | hr = themetool_init(); 881 | } 882 | 883 | if (FAILED(hr)) 884 | { 885 | return hr; 886 | } 887 | else { 888 | themetool_loaded = true; 889 | } 890 | 891 | hr = secureuxtheme_uninstall(); 892 | return hr; 893 | } 894 | 895 | BOOL IsDarkTheme() 896 | { 897 | WCHAR value[255] = { 0 }; 898 | PVOID pvData = value; 899 | DWORD size = sizeof(value); 900 | RegGetValueW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager", L"DllName", RRF_RT_REG_SZ, 0, pvData, &size); 901 | std::wstring msstylePath = std::wstring((LPCWSTR)pvData); 902 | 903 | size_t result = msstylePath.find(L"Dark"); 904 | return result > 0 ? TRUE : FALSE; 905 | } 906 | 907 | HRESULT CRectifyUtil::QueryInterface( 908 | REFIID riid, 909 | _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppv) 910 | { 911 | static const QITAB qit[] = { 912 | QITABENT(CRectifyUtil, IRectifyUtil), 913 | QITABENT(CRectifyUtil, IUnknown), 914 | { 0 }, 915 | }; 916 | HRESULT x = QISearch(this, qit, riid, ppv); 917 | return x; 918 | } 919 | 920 | ULONG CRectifyUtil::AddRef(void) 921 | { 922 | return m_ref++; 923 | } 924 | 925 | ULONG CRectifyUtil::Release(void) 926 | { 927 | ULONG cRef = InterlockedDecrement(&m_ref); 928 | if (0 == cRef) 929 | { 930 | delete this; 931 | } 932 | return cRef; 933 | } -------------------------------------------------------------------------------- /Rectify11CPL/CRectifyUtil.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "IRectifyUtil_h.h" 4 | using namespace std; 5 | 6 | extern WCHAR Rectify11PrefsKey[]; 7 | 8 | class CRectifyUtil : IRectifyUtil 9 | { 10 | public: 11 | CRectifyUtil(); 12 | ~CRectifyUtil(); 13 | virtual HRESULT QueryInterface( 14 | REFIID riid, 15 | _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject); 16 | virtual ULONG AddRef(void); 17 | virtual ULONG Release(void); 18 | 19 | virtual HRESULT GetMicaSettings(BOOL* pEnabled, BOOL* pTabbed); 20 | virtual HRESULT SetMicaForEveryoneEnabled(BOOL micaEnabled, BOOL tabbed); 21 | 22 | virtual HRESULT GetCurrentMenuIndex(DWORD* menuIndex); 23 | virtual HRESULT SetCurrentMenuByIndex(DWORD pIndex); 24 | 25 | virtual HRESULT ApplyTheme(LPCWSTR pThemeName); 26 | virtual HRESULT InstallThemeTool(); 27 | virtual HRESULT UninstallThemeTool(); 28 | 29 | static BOOL KillTask(wstring proc); 30 | static void RestartExplorer(); 31 | 32 | private: 33 | LONG m_ref; 34 | HRESULT _EnableClassicTransparent(); 35 | HRESULT _DeleteClassicTransparent(); 36 | HRESULT _EnableClassicMenu(); 37 | HRESULT _DeleteNilesoftIfExists(); 38 | }; 39 | 40 | BOOL IsDarkTheme(); -------------------------------------------------------------------------------- /Rectify11CPL/ClassFactory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "Rectify11CPL.h" 4 | #include "ElementProvider.h" 5 | #include "ClassFactory.h" 6 | #include "Guid.h" 7 | #include "Templetes.h" 8 | #include "RectifyMainPage.h" 9 | #include "RectifyThemeCfgPage.h" 10 | 11 | CFolderViewImplClassFactory::CFolderViewImplClassFactory(REFCLSID rclsid) : m_cRef(1), m_rclsid(rclsid) 12 | { 13 | DllAddRef(); 14 | } 15 | 16 | CFolderViewImplClassFactory::~CFolderViewImplClassFactory() 17 | { 18 | DllRelease(); 19 | } 20 | 21 | HRESULT CFolderViewImplClassFactory::QueryInterface(__in REFIID riid, __deref_out void **ppv) 22 | { 23 | static const QITAB qit[] = { 24 | QITABENT (CFolderViewImplClassFactory, IClassFactory), 25 | { 0 }, 26 | }; 27 | return QISearch(this, qit, riid, ppv); 28 | } 29 | 30 | DWORD CFolderViewImplClassFactory::AddRef() 31 | { 32 | return InterlockedIncrement(&m_cRef); 33 | } 34 | 35 | DWORD CFolderViewImplClassFactory::Release() 36 | { 37 | ULONG cRef = InterlockedDecrement(&m_cRef); 38 | if (0 == cRef) 39 | { 40 | delete this; 41 | } 42 | return cRef; 43 | } 44 | 45 | HRESULT CElementProvider_CreateInstance(__in REFIID riid, __deref_out void** ppv) 46 | { 47 | HRESULT hr = S_ALLTHRESHOLD; 48 | CElementProvider* pElementProvider = new CElementProvider(); 49 | hr = pElementProvider ? S_OK : E_OUTOFMEMORY; 50 | if (SUCCEEDED(hr)) 51 | { 52 | hr = pElementProvider->QueryInterface(riid, ppv); 53 | 54 | DirectUI::ClassInfo>::Register(); 55 | DirectUI::ClassInfo>::Register(); 56 | pElementProvider->Release(); 57 | } 58 | return hr; 59 | } 60 | 61 | HRESULT CRectifyUtil_CreateInstance(__in REFIID riid, __deref_out void** ppv) 62 | { 63 | HRESULT hr = S_ALLTHRESHOLD; 64 | CRectifyUtil* pUtility = new CRectifyUtil(); 65 | hr = pUtility ? S_OK : E_OUTOFMEMORY; 66 | if (SUCCEEDED(hr)) 67 | { 68 | hr = pUtility->QueryInterface(riid, ppv); 69 | pUtility->Release(); 70 | } 71 | return hr; 72 | } 73 | 74 | HRESULT CFolderViewImplClassFactory::CreateInstance(__in_opt IUnknown* punkOuter, 75 | __in REFIID riid, 76 | __deref_out void **ppv) 77 | { 78 | *ppv = NULL; 79 | 80 | HRESULT hr = !punkOuter ? S_OK : CLASS_E_NOAGGREGATION; 81 | if (SUCCEEDED(hr)) 82 | { 83 | if (m_rclsid == CLSID_FolderViewImplElement) 84 | { 85 | hr = CElementProvider_CreateInstance(riid, ppv); 86 | } 87 | else if (m_rclsid == CLSID_CRectifyUtil) 88 | { 89 | hr = CRectifyUtil_CreateInstance(riid, ppv); 90 | } 91 | else if (riid == IID_IUnknown) 92 | { 93 | // TODO: is this correct? Not sure why this is being called with IUnknown instead of CRectifyUtil 94 | // in Windows 11 23H2 95 | // for some reason m_rclsid is DCC67965-7FFB-0000-1400 .... 96 | hr = CRectifyUtil_CreateInstance(riid, ppv); 97 | } 98 | else 99 | { 100 | hr = E_NOINTERFACE; 101 | 102 | WCHAR szGuid[400] = { 0 }; 103 | 104 | swprintf(szGuid, 400, L"RIID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}\nRCLSID: {%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", 105 | riid.Data1, riid.Data2, riid.Data3, riid.Data4[0], riid.Data4[1], riid.Data4[2], riid.Data4[3], riid.Data4[4], riid.Data4[5], riid.Data4[6], riid.Data4[7], 106 | m_rclsid.Data1, m_rclsid.Data2, m_rclsid.Data3, m_rclsid.Data4[0], m_rclsid.Data4[1], m_rclsid.Data4[2], m_rclsid.Data4[3], m_rclsid.Data4[4], m_rclsid.Data4[5], m_rclsid.Data4[6], m_rclsid.Data4[7]); 107 | 108 | MessageBox(NULL, szGuid, TEXT("Unknown interface in CFolderViewImplClassFactory::CreateInstance()"), MB_ICONERROR); 109 | } 110 | } 111 | return hr; 112 | } 113 | 114 | HRESULT CFolderViewImplClassFactory::LockServer(BOOL fLock) 115 | { 116 | if (fLock) 117 | { 118 | DllAddRef(); 119 | } 120 | else 121 | { 122 | DllRelease(); 123 | } 124 | return S_OK; 125 | } 126 | -------------------------------------------------------------------------------- /Rectify11CPL/ClassFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class CFolderViewImplClassFactory : public IClassFactory 4 | { 5 | public: 6 | CFolderViewImplClassFactory(REFCLSID rclsid); 7 | 8 | // IUnknown methods 9 | IFACEMETHODIMP QueryInterface(__in REFIID riid, __deref_out void **ppv); 10 | IFACEMETHODIMP_(ULONG) AddRef(); 11 | IFACEMETHODIMP_(ULONG) Release(); 12 | 13 | // IClassFactory methods 14 | IFACEMETHODIMP CreateInstance(__in_opt IUnknown *pUnknown, __in REFIID riid, __deref_out void **ppv); 15 | IFACEMETHODIMP LockServer(BOOL fLock); 16 | 17 | private: 18 | ~CFolderViewImplClassFactory(); 19 | REFCLSID m_rclsid; 20 | LONG m_cRef; 21 | }; 22 | -------------------------------------------------------------------------------- /Rectify11CPL/ElementProvider.cpp: -------------------------------------------------------------------------------- 1 | // This class is created by Shell32 CLayoutFolder class. This class "provides" the Element for DirectUI to render in explorer. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include "Rectify11CPL.h" 11 | #include "ElevationManager.h" 12 | #include "ElementProvider.h" 13 | #include "resource.h" 14 | #include "RectifyMainPage.h" 15 | #include "RectifyThemeCfgPage.h" 16 | #include 17 | 18 | CElementProvider::CElementProvider() : Site(NULL) 19 | { 20 | if (FAILED(InitProcessPriv(14, (unsigned short*)g_hInst, 1, true))) 21 | { 22 | SHOW_ERROR("Failed to initialize DirectUI\n"); 23 | } 24 | if (FAILED(InitThread(2))) 25 | { 26 | SHOW_ERROR("Failed to initialize DirectUI for thread\n"); 27 | } 28 | 29 | // Prevent unloading DLL when this class has not been properly destroyed 30 | DllAddRef(); 31 | } 32 | 33 | CElementProvider::~CElementProvider() 34 | { 35 | UnInitThread(); 36 | UnInitProcessPriv((unsigned short*)g_hInst); 37 | 38 | DllRelease(); 39 | } 40 | 41 | // IUnknown Implementation 42 | HRESULT CElementProvider::QueryInterface(REFIID riid, __out void** ppv) 43 | { 44 | static const QITAB qit[] = { 45 | QITABENT(CElementProvider, IDUIElementProviderInit), 46 | QITABENT(CElementProvider, IFrameNotificationClient), 47 | QITABENT(CElementProvider, IFrameShellViewClient), 48 | QITABENT(CElementProvider, IObjectWithSite), 49 | QITABENT(CElementProvider, IServiceProvider), 50 | { 0 }, 51 | }; 52 | HRESULT hr = QISearch(this, qit, riid, ppv); 53 | if (hr != S_OK) 54 | { 55 | hr = DirectUI::XProvider::QueryInterface(riid, ppv); 56 | } 57 | return hr; 58 | } 59 | 60 | ULONG CElementProvider::AddRef() 61 | { 62 | return DirectUI::XProvider::AddRef(); 63 | } 64 | 65 | ULONG CElementProvider::Release() 66 | { 67 | ULONG ret = refCount--; 68 | ULONG newRefCount = refCount; 69 | if (ret == 1) 70 | { 71 | delete this; 72 | } 73 | 74 | return newRefCount; 75 | } 76 | 77 | // XProvider implementation 78 | HRESULT CElementProvider::CreateDUI(DirectUI::IXElementCP* a, HWND* result_handle) 79 | { 80 | int hr = XProvider::CreateDUI(a, result_handle); 81 | if (SUCCEEDED(hr)) 82 | { 83 | DirectUI::XProvider::SetHandleEnterKey(true); 84 | } 85 | else 86 | { 87 | WCHAR buffer[200]; 88 | if (hr == 0x800403ED) 89 | { 90 | swprintf(buffer, 200, L"Failed to create DirectUI parser: Bad markup."); 91 | } 92 | else if (hr == 0x800403EF) 93 | { 94 | swprintf(buffer, 200, L"Failed to create DirectUI parser: A required property is missing. (are you sure that resid=main exists?)"); 95 | } 96 | else if (hr == 0x800403F1) 97 | { 98 | swprintf(buffer, 200, L"Failed to create DirectUI parser: Invaild property value"); 99 | } 100 | else if (hr == 0x8004005A) 101 | { 102 | swprintf(buffer, 200, L"Failed to create DirectUI parser: Probaby can't find the UIFILE?"); 103 | } 104 | else if (hr == 0x800403EE) 105 | { 106 | swprintf(buffer, 200, L"Failed to create DirectUI parser: Unregistered element"); 107 | } 108 | else if (hr == 0x800403F0) 109 | { 110 | swprintf(buffer, 200, L"Failed to create DirectUI parser: Something is not found"); 111 | } 112 | else if (hr == 0x800403F0) 113 | { 114 | swprintf(buffer, 200, L"Failed to create DirectUI parser: Something is not found"); 115 | } 116 | else if (hr == E_FAIL) 117 | { 118 | if (this->XProviderCP) 119 | { 120 | swprintf(buffer, 200, L"Failed to create DirectUI parser: E_FAIL. This is most likely caused by duires.dll missing in System32. Rerun the latest version of the Rectify11 installer."); 121 | } 122 | else 123 | { 124 | swprintf(buffer, 200, L"Failed to create DirectUI parser: E_FAIL as XProviderCP is 0."); 125 | } 126 | } 127 | else 128 | { 129 | swprintf(buffer, 200, L"Failed to create DirectUI parser: Error %X", hr); 130 | } 131 | 132 | MessageBox(NULL, buffer, TEXT("CElementProvider::CreateDUI failed"), MB_ICONERROR); 133 | } 134 | return 0; 135 | } 136 | 137 | // IDUIElementProviderInit implementation 138 | #pragma warning( push ) 139 | #pragma warning( disable : 4312 ) // disable warning about compiler complaining about casting ID to pointer 140 | HRESULT STDMETHODCALLTYPE CElementProvider::SetResourceID(UINT id) 141 | { 142 | IFrameShellViewClient* client = this; 143 | 144 | WCHAR buffer[264]; 145 | StringCchCopyW(buffer, 260, L"main"); 146 | 147 | //First parmeter: hinstance of module 148 | //2nd: Resource ID of uifile 149 | //3rd param: The main resid value 150 | int hr = DirectUI::XResourceProvider::Create(g_hInst, (UCString)id, (UCString)buffer, 0, (XResourceProvider**)&this->XProviderCP); 151 | if (SUCCEEDED(hr)) 152 | { 153 | hr = DirectUI::XProvider::Initialize(NULL, (IXProviderCP*)this->XProviderCP); 154 | if (!SUCCEEDED(hr)) 155 | { 156 | WCHAR szResource[40] = { 0 }; 157 | swprintf(szResource, 40, L"%d", id); 158 | 159 | MessageBox(NULL, szResource, TEXT("CElementProvider::SetResourceId - failed to initialize XProvider class"), MB_ICONERROR); 160 | } 161 | } 162 | else 163 | { 164 | WCHAR szResource[40] = { 0 }; 165 | swprintf(szResource, 40, L"%d", id); 166 | 167 | MessageBox(NULL, szResource, TEXT("CElementProvider::SetResourceId - failed to create xprovider"), MB_ICONERROR); 168 | } 169 | return hr; 170 | } 171 | #pragma warning( pop ) 172 | 173 | HRESULT STDMETHODCALLTYPE CElementProvider::OptionallyTakeInitialFocus(BOOL* result) 174 | { 175 | *result = FALSE; 176 | return S_OK; 177 | } 178 | 179 | // IFrameNotificationClient implementation 180 | HRESULT STDMETHODCALLTYPE CElementProvider::LayoutInitialized() 181 | { 182 | HRESULT hr = themetool_init(); 183 | if (hr != S_OK && hr != HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED)) 184 | { 185 | MessageBox(NULL, TEXT("Failed to initialize SecureUXTheme ThemeTool. Theme information will not be loaded. This may be due to the lack of the ThemeDll.dll in C:\\Windows\\Rectify11\\RectifyControlPanel"), TEXT("CElementProvider::LayoutInitialized"), MB_ICONERROR); 186 | } 187 | 188 | Element* root = XProvider::GetRoot(); 189 | 190 | // Call initialization function as DirectUI does not provide an "OnLoad" method, unlike WPF/Winforms 191 | // This is a bit hacky as Microsoft treats elements as COM objects, and instead iterates through each element, calling 192 | // the appropriate method. 193 | if (root->FindDescendent(StrToID((UCString)L"MainPageElem")) != NULL) 194 | { 195 | RectifyMainPage* page = (RectifyMainPage*)root->FindDescendent(StrToID((UCString)L"MainPageElem")); 196 | page->SetSite(Site); 197 | page->OnInit(); 198 | } 199 | else if (root->FindDescendent(StrToID((UCString)L"ThemePageElem")) != NULL) 200 | { 201 | RectifyThemeCfgPage* page = (RectifyThemeCfgPage*)root->FindDescendent(StrToID((UCString)L"ThemePageElem")); 202 | page->SetSite(Site); 203 | page->OnInit(); 204 | } 205 | 206 | return S_OK; 207 | } 208 | HRESULT STDMETHODCALLTYPE CElementProvider::Notify(WORD* param) 209 | { 210 | // NOTE: param is LPCWSTR 211 | 212 | if (!StrCmpCW((LPCWSTR)param, L"SettingsChanged")) 213 | { 214 | //This is invoked when the UI is refreshed! 215 | } 216 | 217 | if (!StrCmpCW((LPCWSTR)param, L"SearchText")) 218 | { 219 | //Sent when search text modified/added 220 | WCHAR value[264] = { 0 }; 221 | WCHAR path[48]; 222 | GUID IID_IFrameManager = {}; 223 | GUID SID_STopLevelBrowser = {}; 224 | HRESULT hr = CLSIDFromString(L"{4c96be40-915c-11cf-99d3-00aa004ae837}", (LPCLSID)&SID_STopLevelBrowser); 225 | if (SUCCEEDED(hr)) 226 | { 227 | hr = CLSIDFromString(L"{31e4fa78-02b4-419f-9430-7b7585237c77}", (LPCLSID)&IID_IFrameManager); 228 | if (SUCCEEDED(hr)) 229 | { 230 | // find explorer property bag 231 | IPropertyBag* bag = NULL; 232 | HRESULT hr = IUnknown_QueryService(Site, IID_IFrameManager, IID_IPropertyBag, (LPVOID*)&bag); 233 | if (SUCCEEDED(hr)) 234 | { 235 | // read search text 236 | if (SUCCEEDED(PSPropertyBag_ReadStr(bag, L"SearchText", value, 260)) && value[0]) 237 | { 238 | if (SUCCEEDED(StringCchPrintfW(path, 41, L"::%s", L"{26ee0668-a00a-44d7-9371-beb064c98683}"))) 239 | { 240 | LPITEMIDLIST pidlist; 241 | if (SUCCEEDED(SHParseDisplayName(path, NULL, &pidlist, 0, NULL))) 242 | { 243 | IShellBrowser* browser = NULL; 244 | if (SUCCEEDED(IUnknown_QueryService(Site, SID_STopLevelBrowser, IID_IShellBrowser, (LPVOID*)&browser))) 245 | { 246 | // navigate to search text 247 | hr = browser->BrowseObject(pidlist, SBSP_ACTIVATE_NOFOCUS | SBSP_SAMEBROWSER | SBSP_CREATENOHISTORY); 248 | browser->Release(); 249 | } 250 | } 251 | ILFree(pidlist); 252 | } 253 | } 254 | } 255 | } 256 | } 257 | } 258 | return 0; 259 | } 260 | 261 | HRESULT STDMETHODCALLTYPE CElementProvider::OnNavigateAway() 262 | { 263 | SetHandleEnterKey(FALSE); 264 | SetDefaultButtonTracking(FALSE); 265 | 266 | // for whatever reason, OnNavigateAway is called twice. Instead of someone 267 | // at microsoft properly fixing the issue, they just null out some fields in XProvider 268 | // to prevent destroying a random memory address. 269 | 270 | XProviderCP = NULL; 271 | _RandomElement = NULL; 272 | _RootElement = NULL; 273 | 274 | return 0; 275 | } 276 | HRESULT STDMETHODCALLTYPE CElementProvider::OnInnerElementDestroyed() 277 | { 278 | //if (XProviderCP) 279 | //{ 280 | XProviderCP = NULL; 281 | _RootElement = NULL; 282 | _RandomElement = NULL; 283 | //} 284 | return 0; 285 | } 286 | // IFrameShellViewClient implementation 287 | HRESULT STDMETHODCALLTYPE CElementProvider::OnSelectedItemChanged() 288 | { 289 | return 0; 290 | } 291 | HRESULT STDMETHODCALLTYPE CElementProvider::OnSelectionChanged() 292 | { 293 | return 0; 294 | } 295 | HRESULT STDMETHODCALLTYPE CElementProvider::OnContentsChanged() 296 | { 297 | return 0; 298 | } 299 | HRESULT STDMETHODCALLTYPE CElementProvider::OnFolderChanged() 300 | { 301 | return 0; 302 | } 303 | 304 | // IServiceProvider implementation 305 | HRESULT STDMETHODCALLTYPE CElementProvider::QueryService( 306 | REFGUID guidService, 307 | REFIID riid, 308 | void** ppvObject) 309 | { 310 | *ppvObject = 0; 311 | return E_NOTIMPL; 312 | } 313 | 314 | // IObjectWithSite implementation 315 | HRESULT CElementProvider::SetSite(IUnknown* punkSite) 316 | { 317 | IUnknown_Set((IUnknown**)&this->Site, punkSite); 318 | return S_OK; 319 | } 320 | 321 | HRESULT CElementProvider::GetSite(REFIID riid, void** ppvSite) 322 | { 323 | if (Site == NULL) 324 | { 325 | return E_FAIL; 326 | } 327 | 328 | return Site->QueryInterface(riid, ppvSite); 329 | } 330 | -------------------------------------------------------------------------------- /Rectify11CPL/ElementProvider.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "Rectify11CPL.h" 8 | #include "CRectifyUtil.h" 9 | 10 | class CElementProvider : public DirectUI::XProvider, public IDUIElementProviderInit, public IFrameNotificationClient, public IFrameShellViewClient, public IObjectWithSite, public IServiceProvider 11 | { 12 | public: 13 | CElementProvider(); 14 | virtual ~CElementProvider(); 15 | 16 | // IUnknown 17 | IFACEMETHODIMP QueryInterface(REFIID riid, __out void** ppv); 18 | IFACEMETHODIMP_(ULONG) AddRef(); 19 | IFACEMETHODIMP_(ULONG) Release(); 20 | 21 | // XProvider 22 | virtual long CreateDUI(DirectUI::IXElementCP* a, HWND* hwnd) override; 23 | 24 | // IDUIElementProviderInit 25 | virtual HRESULT STDMETHODCALLTYPE SetResourceID(UINT id); 26 | virtual HRESULT STDMETHODCALLTYPE OptionallyTakeInitialFocus(BOOL* result); 27 | 28 | //IFrameNotificationClient 29 | virtual HRESULT STDMETHODCALLTYPE LayoutInitialized(); 30 | virtual HRESULT STDMETHODCALLTYPE Notify(WORD* param); 31 | virtual HRESULT STDMETHODCALLTYPE OnNavigateAway(); 32 | virtual HRESULT STDMETHODCALLTYPE OnInnerElementDestroyed(); 33 | 34 | //IFrameShellViewClient 35 | virtual HRESULT STDMETHODCALLTYPE OnSelectedItemChanged(); 36 | virtual HRESULT STDMETHODCALLTYPE OnSelectionChanged(); 37 | virtual HRESULT STDMETHODCALLTYPE OnContentsChanged(); 38 | virtual HRESULT STDMETHODCALLTYPE OnFolderChanged(); 39 | 40 | //IServiceProvider 41 | virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID guidService, REFIID riid, void** ppvObject); 42 | 43 | //IObjectWithSite 44 | virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown* pUnkSite); 45 | virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void** ppvSite); 46 | 47 | private: 48 | IUnknown* Site; 49 | }; 50 | -------------------------------------------------------------------------------- /Rectify11CPL/ElevationManager.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "undoc.h" 3 | #include "ElevationManager.h" 4 | #include "Guid.h" 5 | #include 6 | using namespace std; 7 | #include 8 | #include "CRectifyUtil.h" 9 | 10 | IRectifyUtil* ElevationManager::Initialize(HWND window) 11 | { 12 | GUID CLSID_MultiObjectElevationFactory = {0}, GUID_IMultiObjectElevationFactory = { 0 }; 13 | if (FAILED(CLSIDFromString(L"{36f0bd14-d84d-468c-b79c-9990f3fa897f}", (LPCLSID)&CLSID_MultiObjectElevationFactory))) 14 | { 15 | return NULL; 16 | }; 17 | if (FAILED(CLSIDFromString(L"{6fabda16-031e-47e3-b2a2-2339c05ccb9e}", (LPCLSID)&GUID_IMultiObjectElevationFactory))) 18 | { 19 | return NULL; 20 | }; 21 | 22 | IMultiObjectElevationFactory* ppv = NULL; 23 | IRectifyUtil* ppv2 = NULL; 24 | 25 | // Create an instance of MultiObjectElevation factory which allows us to run COM objects as administrator 26 | HRESULT hr = CoCreateInstance(CLSID_MultiObjectElevationFactory, NULL, CLSCTX_INPROC_SERVER, GUID_IMultiObjectElevationFactory, (LPVOID*)&ppv); 27 | if (SUCCEEDED(hr)) 28 | { 29 | // find explorer window 30 | HWND hwnd = FindWindow(TEXT("Progman"), TEXT("Program Manager")); 31 | 32 | // initalize 33 | hr = ppv->Initialize(window, CLSID_RectifyUtilServer); 34 | if (FAILED(hr)) 35 | { 36 | CHAR buffer[1024]; 37 | std::string message = std::system_category().message(hr); 38 | sprintf_s(buffer, 1024, "MultiObjectElevationFactory::Initialize() failed with 0x%x (%s)", hr, message.c_str()); 39 | MessageBoxA(window, buffer, "Error", MB_ICONERROR); 40 | return NULL; 41 | } 42 | 43 | // create CRectifyUtil as administrator 44 | hr = ppv->CreateElevatedObject(CLSID_CRectifyUtil, IID_IRectifyUtil, (void**)&ppv2); 45 | if (hr != S_OK) 46 | { 47 | std::string message = std::system_category().message(hr); 48 | CHAR buffer[1024]; 49 | sprintf_s(buffer, "CreateElevatedObject() failed with 0x%x (%s)", hr, message.c_str()); 50 | MessageBoxA(window, buffer, "Error", MB_ICONERROR); 51 | } 52 | ppv->Release(); 53 | if (SUCCEEDED(hr)) 54 | { 55 | return ppv2; 56 | } 57 | } 58 | return NULL; 59 | } -------------------------------------------------------------------------------- /Rectify11CPL/ElevationManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "CRectifyUtil.h" 4 | class ElevationManager 5 | { 6 | public: 7 | static IRectifyUtil* Initialize(HWND window); 8 | }; 9 | 10 | -------------------------------------------------------------------------------- /Rectify11CPL/FolderViewImpl.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | DirectUIRegister 11 | 12 | 13 | DirectUIRegister 14 | 15 | 16 | Elements 17 | 18 | 19 | NavPane 20 | 21 | 22 | NavPane 23 | 24 | 25 | NavPane 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | DirectUIRegister 38 | 39 | 40 | DirectUIRegister 41 | 42 | 43 | 44 | Elements 45 | 46 | 47 | NavPane 48 | 49 | 50 | NavPane 51 | 52 | 53 | NavPane 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | {3ab49b30-1de5-42f7-be6d-8ccd22f2c209} 73 | 74 | 75 | {08d315e0-4b77-460f-a865-249eb0fa8b1f} 76 | 77 | 78 | {712cae3b-234c-4430-a089-cd94c0fd803a} 79 | 80 | 81 | -------------------------------------------------------------------------------- /Rectify11CPL/Guid.h: -------------------------------------------------------------------------------- 1 | #define INITGUID 2 | #include 3 | #include 4 | 5 | //shell:::{542EEE1B-A254-46F7-B980-35BECF6076A4} 6 | 7 | // control /name Rectify11.SettingsCPL /page pageThemePref 8 | 9 | // {542EEE1B-A254-46F7-B980-35BECF6076A4} 10 | DEFINE_GUID(CLSID_FolderViewImpl, 0x542eee1b, 0xa254, 0x46f7, 0xb9, 0x80, 0x35, 0xbe, 0xcf, 0x60, 0x76, 0xa4); 11 | 12 | //NOTE: the guid must also be changed in tasks.xml 13 | // {EC8669E2-7F9F-42AC-A2D7-307E23CA9E20} 14 | DEFINE_GUID(CLSID_FolderViewImplElement, 0xec8669e2, 0x7f9f, 0x42ac, 0xa2, 0xd7, 0x30, 0x7e, 0x23, 0xca, 0x9e, 0x20); 15 | 16 | // {A7BCDC3B-C5A2-44BB-B8EC-560B24ACAAD8} 17 | DEFINE_GUID(IID_IRectifyUtil, 0xa7bcdc3b, 0xc5a2, 0x44bb, 0xb8, 0xec, 0x56, 0xb, 0x24, 0xac, 0xaa, 0xd8); 18 | 19 | // {9CD66066-9784-4DA6-A27A-D322FC96D02E} 20 | DEFINE_GUID(CLSID_CRectifyUtil, 0x9cd66066, 0x9784, 0x4da6, 0xa2, 0x7a, 0xd3, 0x22, 0xfc, 0x96, 0xd0, 0x2e); 21 | 22 | // {CA4F4753-3B80-4713-A13A-5885FC56DD8D} 23 | DEFINE_GUID(CLSID_RectifyUtilServer, 0xca4f4753, 0x3b80, 0x4713, 0xa1, 0x3a, 0x58, 0x85, 0xfc, 0x56, 0xdd, 0x8d); 24 | 25 | // {53387088-A8C4-4AE3-9CE7-536B90077D13} 26 | DEFINE_GUID(CLSID_PROXY, 0x53387088, 0xa8c4, 0x4ae3, 0x9c, 0xe7, 0x53, 0x6b, 0x90, 0x7, 0x7d, 0x13); 27 | -------------------------------------------------------------------------------- /Rectify11CPL/IRectifyUtil.idl: -------------------------------------------------------------------------------- 1 | import "oaidl.idl"; 2 | import "ocidl.idl"; 3 | 4 | typedef enum { 5 | Normal = 0, 6 | NilesoftSmall = 1, 7 | NilesoftFull = 2, 8 | Classic = 3, 9 | ClassicTransparent = 4 10 | } MenuCustomizationType; 11 | 12 | [ 13 | object, uuid(A7BCDC3B-C5A2-44BB-B8EC-560B24ACAAD8), 14 | version(1.0) 15 | ] 16 | interface IRectifyUtil : IUnknown 17 | { 18 | HRESULT GetMicaSettings([out] BOOL* pEnabled, [out] BOOL* pTabbed); 19 | HRESULT SetMicaForEveryoneEnabled([in] BOOL micaEnabled, [in] BOOL tabbed); 20 | HRESULT GetCurrentMenuIndex([out] DWORD* pMenuIndex); 21 | HRESULT SetCurrentMenuByIndex([in] DWORD pMenuIndex); 22 | 23 | // Utilities for rectify 11 installer 24 | HRESULT ApplyTheme([in] LPCWSTR pThemeName); 25 | HRESULT InstallThemeTool(); 26 | HRESULT UninstallThemeTool(); 27 | } 28 | -------------------------------------------------------------------------------- /Rectify11CPL/IRectifyUtil_h.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the definitions for the interfaces */ 4 | 5 | 6 | /* File created by MIDL compiler version 8.01.0628 */ 7 | /* at Mon Jan 18 22:14:07 2038 8 | */ 9 | /* Compiler settings for IRectifyUtil.idl: 10 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0628 11 | protocol : all , ms_ext, c_ext, robust 12 | error checks: allocation ref bounds_check enum stub_data 13 | VC __declspec() decoration level: 14 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 15 | DECLSPEC_UUID(), MIDL_INTERFACE() 16 | */ 17 | /* @@MIDL_FILE_HEADING( ) */ 18 | 19 | 20 | 21 | /* verify that the version is high enough to compile this file*/ 22 | #ifndef __REQUIRED_RPCNDR_H_VERSION__ 23 | #define __REQUIRED_RPCNDR_H_VERSION__ 500 24 | #endif 25 | 26 | #include "rpc.h" 27 | #include "rpcndr.h" 28 | 29 | #ifndef __RPCNDR_H_VERSION__ 30 | #error this stub requires an updated version of 31 | #endif /* __RPCNDR_H_VERSION__ */ 32 | 33 | #ifndef COM_NO_WINDOWS_H 34 | #include "windows.h" 35 | #include "ole2.h" 36 | #endif /*COM_NO_WINDOWS_H*/ 37 | 38 | #ifndef __IRectifyUtil_h_h__ 39 | #define __IRectifyUtil_h_h__ 40 | 41 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) 42 | #pragma once 43 | #endif 44 | 45 | #ifndef DECLSPEC_XFGVIRT 46 | #if defined(_CONTROL_FLOW_GUARD_XFG) 47 | #define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func)) 48 | #else 49 | #define DECLSPEC_XFGVIRT(base, func) 50 | #endif 51 | #endif 52 | 53 | /* Forward Declarations */ 54 | 55 | #ifndef __IRectifyUtil_FWD_DEFINED__ 56 | #define __IRectifyUtil_FWD_DEFINED__ 57 | typedef interface IRectifyUtil IRectifyUtil; 58 | 59 | #endif /* __IRectifyUtil_FWD_DEFINED__ */ 60 | 61 | 62 | /* header files for imported files */ 63 | #include "oaidl.h" 64 | #include "ocidl.h" 65 | 66 | #ifdef __cplusplus 67 | extern "C"{ 68 | #endif 69 | 70 | 71 | /* interface __MIDL_itf_IRectifyUtil_0000_0000 */ 72 | /* [local] */ 73 | 74 | typedef /* [public] */ 75 | enum __MIDL___MIDL_itf_IRectifyUtil_0000_0000_0001 76 | { 77 | Normal = 0, 78 | NilesoftSmall = 1, 79 | NilesoftFull = 2, 80 | Classic = 3, 81 | ClassicTransparent = 4 82 | } MenuCustomizationType; 83 | 84 | 85 | 86 | extern RPC_IF_HANDLE __MIDL_itf_IRectifyUtil_0000_0000_v0_0_c_ifspec; 87 | extern RPC_IF_HANDLE __MIDL_itf_IRectifyUtil_0000_0000_v0_0_s_ifspec; 88 | 89 | #ifndef __IRectifyUtil_INTERFACE_DEFINED__ 90 | #define __IRectifyUtil_INTERFACE_DEFINED__ 91 | 92 | /* interface IRectifyUtil */ 93 | /* [version][uuid][object] */ 94 | 95 | 96 | EXTERN_C const IID IID_IRectifyUtil; 97 | 98 | #if defined(__cplusplus) && !defined(CINTERFACE) 99 | 100 | MIDL_INTERFACE("A7BCDC3B-C5A2-44BB-B8EC-560B24ACAAD8") 101 | IRectifyUtil : public IUnknown 102 | { 103 | public: 104 | virtual HRESULT STDMETHODCALLTYPE GetMicaSettings( 105 | /* [out] */ BOOL *pEnabled, 106 | /* [out] */ BOOL *pTabbed) = 0; 107 | 108 | virtual HRESULT STDMETHODCALLTYPE SetMicaForEveryoneEnabled( 109 | /* [in] */ BOOL micaEnabled, 110 | /* [in] */ BOOL tabbed) = 0; 111 | 112 | virtual HRESULT STDMETHODCALLTYPE GetCurrentMenuIndex( 113 | /* [out] */ DWORD *pMenuIndex) = 0; 114 | 115 | virtual HRESULT STDMETHODCALLTYPE SetCurrentMenuByIndex( 116 | /* [in] */ DWORD pMenuIndex) = 0; 117 | 118 | virtual HRESULT STDMETHODCALLTYPE ApplyTheme( 119 | /* [in] */ LPCWSTR pThemeName) = 0; 120 | 121 | virtual HRESULT STDMETHODCALLTYPE InstallThemeTool( void) = 0; 122 | 123 | virtual HRESULT STDMETHODCALLTYPE UninstallThemeTool( void) = 0; 124 | 125 | }; 126 | 127 | 128 | #else /* C style interface */ 129 | 130 | typedef struct IRectifyUtilVtbl 131 | { 132 | BEGIN_INTERFACE 133 | 134 | DECLSPEC_XFGVIRT(IUnknown, QueryInterface) 135 | HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 136 | IRectifyUtil * This, 137 | /* [in] */ REFIID riid, 138 | /* [annotation][iid_is][out] */ 139 | _COM_Outptr_ void **ppvObject); 140 | 141 | DECLSPEC_XFGVIRT(IUnknown, AddRef) 142 | ULONG ( STDMETHODCALLTYPE *AddRef )( 143 | IRectifyUtil * This); 144 | 145 | DECLSPEC_XFGVIRT(IUnknown, Release) 146 | ULONG ( STDMETHODCALLTYPE *Release )( 147 | IRectifyUtil * This); 148 | 149 | DECLSPEC_XFGVIRT(IRectifyUtil, GetMicaSettings) 150 | HRESULT ( STDMETHODCALLTYPE *GetMicaSettings )( 151 | IRectifyUtil * This, 152 | /* [out] */ BOOL *pEnabled, 153 | /* [out] */ BOOL *pTabbed); 154 | 155 | DECLSPEC_XFGVIRT(IRectifyUtil, SetMicaForEveryoneEnabled) 156 | HRESULT ( STDMETHODCALLTYPE *SetMicaForEveryoneEnabled )( 157 | IRectifyUtil * This, 158 | /* [in] */ BOOL micaEnabled, 159 | /* [in] */ BOOL tabbed); 160 | 161 | DECLSPEC_XFGVIRT(IRectifyUtil, GetCurrentMenuIndex) 162 | HRESULT ( STDMETHODCALLTYPE *GetCurrentMenuIndex )( 163 | IRectifyUtil * This, 164 | /* [out] */ DWORD *pMenuIndex); 165 | 166 | DECLSPEC_XFGVIRT(IRectifyUtil, SetCurrentMenuByIndex) 167 | HRESULT ( STDMETHODCALLTYPE *SetCurrentMenuByIndex )( 168 | IRectifyUtil * This, 169 | /* [in] */ DWORD pMenuIndex); 170 | 171 | DECLSPEC_XFGVIRT(IRectifyUtil, ApplyTheme) 172 | HRESULT ( STDMETHODCALLTYPE *ApplyTheme )( 173 | IRectifyUtil * This, 174 | /* [in] */ LPCWSTR pThemeName); 175 | 176 | DECLSPEC_XFGVIRT(IRectifyUtil, InstallThemeTool) 177 | HRESULT ( STDMETHODCALLTYPE *InstallThemeTool )( 178 | IRectifyUtil * This); 179 | 180 | DECLSPEC_XFGVIRT(IRectifyUtil, UninstallThemeTool) 181 | HRESULT ( STDMETHODCALLTYPE *UninstallThemeTool )( 182 | IRectifyUtil * This); 183 | 184 | END_INTERFACE 185 | } IRectifyUtilVtbl; 186 | 187 | interface IRectifyUtil 188 | { 189 | CONST_VTBL struct IRectifyUtilVtbl *lpVtbl; 190 | }; 191 | 192 | 193 | 194 | #ifdef COBJMACROS 195 | 196 | 197 | #define IRectifyUtil_QueryInterface(This,riid,ppvObject) \ 198 | ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) 199 | 200 | #define IRectifyUtil_AddRef(This) \ 201 | ( (This)->lpVtbl -> AddRef(This) ) 202 | 203 | #define IRectifyUtil_Release(This) \ 204 | ( (This)->lpVtbl -> Release(This) ) 205 | 206 | 207 | #define IRectifyUtil_GetMicaSettings(This,pEnabled,pTabbed) \ 208 | ( (This)->lpVtbl -> GetMicaSettings(This,pEnabled,pTabbed) ) 209 | 210 | #define IRectifyUtil_SetMicaForEveryoneEnabled(This,micaEnabled,tabbed) \ 211 | ( (This)->lpVtbl -> SetMicaForEveryoneEnabled(This,micaEnabled,tabbed) ) 212 | 213 | #define IRectifyUtil_GetCurrentMenuIndex(This,pMenuIndex) \ 214 | ( (This)->lpVtbl -> GetCurrentMenuIndex(This,pMenuIndex) ) 215 | 216 | #define IRectifyUtil_SetCurrentMenuByIndex(This,pMenuIndex) \ 217 | ( (This)->lpVtbl -> SetCurrentMenuByIndex(This,pMenuIndex) ) 218 | 219 | #define IRectifyUtil_ApplyTheme(This,pThemeName) \ 220 | ( (This)->lpVtbl -> ApplyTheme(This,pThemeName) ) 221 | 222 | #define IRectifyUtil_InstallThemeTool(This) \ 223 | ( (This)->lpVtbl -> InstallThemeTool(This) ) 224 | 225 | #define IRectifyUtil_UninstallThemeTool(This) \ 226 | ( (This)->lpVtbl -> UninstallThemeTool(This) ) 227 | 228 | #endif /* COBJMACROS */ 229 | 230 | 231 | #endif /* C style interface */ 232 | 233 | 234 | 235 | 236 | #endif /* __IRectifyUtil_INTERFACE_DEFINED__ */ 237 | 238 | 239 | /* Additional Prototypes for ALL interfaces */ 240 | 241 | /* end of Additional Prototypes */ 242 | 243 | #ifdef __cplusplus 244 | } 245 | #endif 246 | 247 | #endif 248 | 249 | 250 | -------------------------------------------------------------------------------- /Rectify11CPL/IRectifyUtil_i.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* this ALWAYS GENERATED file contains the IIDs and CLSIDs */ 4 | 5 | /* link this file in with the server and any clients */ 6 | 7 | 8 | /* File created by MIDL compiler version 8.01.0628 */ 9 | /* at Mon Jan 18 22:14:07 2038 10 | */ 11 | /* Compiler settings for IRectifyUtil.idl: 12 | Oicf, W1, Zp8, env=Win64 (32b run), target_arch=AMD64 8.01.0628 13 | protocol : all , ms_ext, c_ext, robust 14 | error checks: allocation ref bounds_check enum stub_data 15 | VC __declspec() decoration level: 16 | __declspec(uuid()), __declspec(selectany), __declspec(novtable) 17 | DECLSPEC_UUID(), MIDL_INTERFACE() 18 | */ 19 | /* @@MIDL_FILE_HEADING( ) */ 20 | 21 | 22 | 23 | #ifdef __cplusplus 24 | extern "C"{ 25 | #endif 26 | 27 | 28 | #include 29 | #include 30 | 31 | #ifdef _MIDL_USE_GUIDDEF_ 32 | 33 | #ifndef INITGUID 34 | #define INITGUID 35 | #include 36 | #undef INITGUID 37 | #else 38 | #include 39 | #endif 40 | 41 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ 42 | DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) 43 | 44 | #else // !_MIDL_USE_GUIDDEF_ 45 | 46 | #ifndef __IID_DEFINED__ 47 | #define __IID_DEFINED__ 48 | 49 | typedef struct _IID 50 | { 51 | unsigned long x; 52 | unsigned short s1; 53 | unsigned short s2; 54 | unsigned char c[8]; 55 | } IID; 56 | 57 | #endif // __IID_DEFINED__ 58 | 59 | #ifndef CLSID_DEFINED 60 | #define CLSID_DEFINED 61 | typedef IID CLSID; 62 | #endif // CLSID_DEFINED 63 | 64 | #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \ 65 | EXTERN_C __declspec(selectany) const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} 66 | 67 | #endif // !_MIDL_USE_GUIDDEF_ 68 | 69 | MIDL_DEFINE_GUID(IID, IID_IRectifyUtil,0xA7BCDC3B,0xC5A2,0x44BB,0xB8,0xEC,0x56,0x0B,0x24,0xAC,0xAA,0xD8); 70 | 71 | #undef MIDL_DEFINE_GUID 72 | 73 | #ifdef __cplusplus 74 | } 75 | #endif 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /Rectify11CPL/Rectify11CPL.def: -------------------------------------------------------------------------------- 1 | EXPORTS 2 | DllCanUnloadNow PRIVATE 3 | DllGetClassObject PRIVATE 4 | DllRegisterServer PRIVATE 5 | DllUnregisterServer PRIVATE 6 | -------------------------------------------------------------------------------- /Rectify11CPL/Rectify11CPL.h: -------------------------------------------------------------------------------- 1 | //Core APIS 2 | #pragma once 3 | #pragma comment(lib,"dui70.lib") 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include "undoc.h" 14 | #include "resource.h" 15 | #include "dllmain.h" 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include "..\dui70\DirectUI\DirectUI.h" 22 | using namespace DirectUI; 23 | using namespace std; 24 | namespace fs = std::filesystem; 25 | 26 | #include "CControlPanelNavLinkCommand.h" 27 | #include "CControlPanelNavLink.h" 28 | #include "CControlPanelNavLinks.h" 29 | 30 | #include "theme.h" 31 | 32 | #define NOT_IMPLEMENTED MessageBox(NULL, TEXT(__FUNCTION__), TEXT("Non implementented function in some class"), MB_ICONERROR) 33 | #define SHOW_ERROR(x) MessageBox(NULL, TEXT(x), TEXT("Error"), MB_ICONERROR) -------------------------------------------------------------------------------- /Rectify11CPL/Rectify11CPL.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "Windows.h" 11 | 12 | ///////////////////////////////////////////////////////////////////////////// 13 | #undef APSTUDIO_READONLY_SYMBOLS 14 | 15 | ///////////////////////////////////////////////////////////////////////////// 16 | // German (Germany) resources 17 | 18 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) 19 | LANGUAGE LANG_GERMAN, SUBLANG_GERMAN 20 | #pragma code_page(1252) 21 | 22 | ///////////////////////////////////////////////////////////////////////////// 23 | // 24 | // String Table 25 | // 26 | 27 | STRINGTABLE 28 | BEGIN 29 | IDS_THEMEHOOKFAIL "Fehler beim laden von SecureUXTheme ThemeTool. Designinformationen werden nicht geladen." 30 | IDS_CPLTITLE "Rectify11 Einstellungen" 31 | IDS_THEME "Design:" 32 | IDS_ThemePref "Design-Einstellungen" 33 | IDS_CPLNAME "Rectify11-Einstellungen" 34 | IDS_THEMESHEADER "Designs" 35 | IDS_INFORMATIONHEADER "Informationen" 36 | IDS_ENABLEMICA "Mica aktivieren" 37 | IDS_TABBED "Mica Alt aktivieren" 38 | END 39 | 40 | STRINGTABLE 41 | BEGIN 42 | IDS_WIN11DEFAULT "Windows 11 (Standard)" 43 | IDS_FLUENTCTX "Nilesoft Shell (Weitere Optionen Anzeigen)" 44 | IDS_NILESHELLALL "Nilesoft Shell (Alle Optionen Anzeigen)" 45 | IDS_CLASSICCTX "Klassisches Kontextmenü" 46 | IDS_CLASSICTRANSPARENTCTX "Klassiches Kontextmenü (Transparent)" 47 | IDS_RESTARTEXPLORER "Starte den Explorer neu um die Änderungen zu übernehmen" 48 | IDS_ELEVATIONNEEDED "Einstellungen ändern, die momentan nicht verfügbar sind" 49 | IDS_VERSION "Rectify11 version:" 50 | IDS_Save "Ok" 51 | IDS_CANCEL "Abbrechen" 52 | IDS_IGNOREBG "Desktophintergrund behalten" 53 | IDS_IGNORECURSOR "Mauszeiger behalten" 54 | IDS_IGNOREIGONS "Desktopsymbole behalten" 55 | IDS_IGNOREACCENT "Akzentfarben behalten" 56 | IDS_IGNORESOUNDS "Soundschema behalten" 57 | IDS_IGNORESCREENSAVER "Bildschirmschoner behalten (falls eingestellt)" 58 | END 59 | 60 | STRINGTABLE 61 | BEGIN 62 | IDS_NA "N/V" 63 | IDS_MENUS "Kontextmenü" 64 | IDS_CPLTHEMEPREF "Design von Rectify11 ändern" 65 | IDS_CPLTIP "Rectify11-Einstellungen anpassen, so auch die Design-Einstellungen" 66 | IDS_SYSINFO "Systeminformationen" 67 | IDS_UNINSTALL "Rectify11 Deinstallieren" 68 | IDS_THEMETOOLSTATUS "SecureUXThemePatcher status: " 69 | IDS_OK "Ok" 70 | IDS_OUTDATED "Veraltet" 71 | IDS_NOTINSTALLED "Nicht installiert" 72 | IDS_THEMETOOLWARN "Unbekannter Status. Bitte neu installieren." 73 | IDS_THEMETOOLINSTALL "SecureUxTheme-Patcher neu installieren" 74 | IDS_THEMETOOLALT "Installiert den SecureUxThemePatcher neu. Dies ist erforderlich, wenn das Rectify11-Design nicht angewendet wird." 75 | IDS_ADVANCEDOPTIONS "Erweiterte Optionen" 76 | END 77 | 78 | #endif // German (Germany) resources 79 | ///////////////////////////////////////////////////////////////////////////// 80 | 81 | 82 | ///////////////////////////////////////////////////////////////////////////// 83 | // English (United States) resources 84 | 85 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 86 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 87 | #pragma code_page(1252) 88 | 89 | #ifdef APSTUDIO_INVOKED 90 | ///////////////////////////////////////////////////////////////////////////// 91 | // 92 | // TEXTINCLUDE 93 | // 94 | 95 | 1 TEXTINCLUDE 96 | BEGIN 97 | "resource.h\0" 98 | END 99 | 100 | 2 TEXTINCLUDE 101 | BEGIN 102 | "#include ""Windows.h""\r\n" 103 | "\0" 104 | END 105 | 106 | 3 TEXTINCLUDE 107 | BEGIN 108 | "\r\n" 109 | "\0" 110 | END 111 | 112 | #endif // APSTUDIO_INVOKED 113 | 114 | 115 | ///////////////////////////////////////////////////////////////////////////// 116 | // 117 | // Icon 118 | // 119 | 120 | // Icon with lowest ID value placed first to ensure application icon 121 | // remains consistent on all systems. 122 | IDI_ICON1 ICON "icon.ico" 123 | 124 | 125 | ///////////////////////////////////////////////////////////////////////////// 126 | // 127 | // XMLFILE 128 | // 129 | 130 | IDR_PAGEDEF XMLFILE "pages.xml" 131 | 132 | 133 | ///////////////////////////////////////////////////////////////////////////// 134 | // 135 | // XML 136 | // 137 | 138 | IDR_TASK XML "taskslist.xml" 139 | 140 | 141 | ///////////////////////////////////////////////////////////////////////////// 142 | // 143 | // UIFILE 144 | // 145 | 146 | IDR_MAINPAGE UIFILE "RectifyMainPage.xml" 147 | 148 | IDR_UPDATEPAGE UIFILE "RectifyThemeCfgPage.xml" 149 | 150 | 151 | ///////////////////////////////////////////////////////////////////////////// 152 | // 153 | // Bitmap 154 | // 155 | 156 | IDB_LIGHTPREVIEW BITMAP "preview_light.bmp" 157 | 158 | IDB_DARKPREVIEW BITMAP "preview_dark.bmp" 159 | 160 | 161 | ///////////////////////////////////////////////////////////////////////////// 162 | // 163 | // String Table 164 | // 165 | 166 | STRINGTABLE 167 | BEGIN 168 | IDS_THEMEHOOKFAIL "Failed to initialize SecureUXTheme ThemeTool. Theme information will not be loaded." 169 | IDS_CPLTITLE "Change Rectify11 Settings" 170 | IDS_THEME "Theme:" 171 | IDS_ThemePref "Theme preferences" 172 | IDS_CPLNAME "Rectify11 Settings" 173 | IDS_THEMESHEADER "Themes" 174 | IDS_INFORMATIONHEADER "Information" 175 | IDS_ENABLEMICA "Enable Mica" 176 | IDS_TABBED "Use tabbed instead of Mica" 177 | END 178 | 179 | STRINGTABLE 180 | BEGIN 181 | IDS_WIN11DEFAULT "Windows 11 default" 182 | IDS_FLUENTCTX "Nilesoft Shell" 183 | IDS_NILESHELLALL "Nilesoft Shell (all items in root)" 184 | IDS_CLASSICCTX "Classic menus" 185 | IDS_CLASSICTRANSPARENTCTX "Classic menus with transparency" 186 | IDS_RESTARTEXPLORER "Restart explorer to apply changes" 187 | IDS_ELEVATIONNEEDED "Change settings that are unavailable" 188 | IDS_VERSION "Rectify11 version:" 189 | IDS_Save "Save" 190 | IDS_CANCEL "Cancel" 191 | IDS_IGNOREBG "Preserve my desktop background" 192 | IDS_IGNORECURSOR "Preserve my mouse cursors" 193 | IDS_IGNOREIGONS "Preserve my desktop icons" 194 | IDS_IGNOREACCENT "Preserve my accent color" 195 | IDS_IGNORESOUNDS "Preserve my system sounds" 196 | IDS_IGNORESCREENSAVER "Preserve my screensaver (if one is applied)" 197 | END 198 | 199 | STRINGTABLE 200 | BEGIN 201 | IDS_NA "N/A" 202 | IDS_MENUS "Menus" 203 | IDS_CPLTHEMEPREF "Change the theme of Rectify11" 204 | IDS_CPLTIP "Customize Rectify11 settings such as theme settings" 205 | IDS_SYSINFO "System Information" 206 | IDS_UNINSTALL "Uninstall Rectify11" 207 | IDS_THEMETOOLSTATUS "SecureUXThemePatcher status: " 208 | IDS_OK "OK" 209 | IDS_OUTDATED "Outdated" 210 | IDS_NOTINSTALLED "Not installed" 211 | IDS_THEMETOOLWARN "Unknown status. Please reinstall." 212 | IDS_THEMETOOLINSTALL "Reinstall SecureUxTheme patcher" 213 | IDS_THEMETOOLALT "Reinstalls the SecureUxThemePatcher. This is needed if the Rectify11 visual style is not being applied." 214 | IDS_ADVANCEDOPTIONS "Advanced options" 215 | END 216 | 217 | #endif // English (United States) resources 218 | ///////////////////////////////////////////////////////////////////////////// 219 | 220 | 221 | ///////////////////////////////////////////////////////////////////////////// 222 | // Arabic (Saudi Arabia) resources 223 | 224 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ARA) 225 | LANGUAGE LANG_ARABIC, SUBLANG_ARABIC_SAUDI_ARABIA 226 | #pragma code_page(1256) 227 | 228 | ///////////////////////////////////////////////////////////////////////////// 229 | // 230 | // String Table 231 | // 232 | 233 | STRINGTABLE 234 | BEGIN 235 | IDS_THEMEHOOKFAIL "فشل في تحميل SecureUXTheme ولن يتم تحميل معلومات النسق. " 236 | IDS_CPLTITLE "تغيير إعدادات Rectify11" 237 | IDS_THEME "النسق:" 238 | IDS_ThemePref "تفضيلاتي" 239 | IDS_CPLNAME "إعدادات Rectify11" 240 | IDS_THEMESHEADER "السمات" 241 | IDS_INFORMATIONHEADER "معلومات أخرى" 242 | IDS_ENABLEMICA "تفعيل Mica" 243 | IDS_TABBED "استخدام Mica Alt بدل Mica" 244 | END 245 | 246 | STRINGTABLE 247 | BEGIN 248 | IDS_WIN11DEFAULT "قوائم Windows 11 الافتراضية" 249 | IDS_FLUENTCTX "قوائم Nilesoft Shell مصغرة" 250 | IDS_NILESHELLALL "قوائم Nilesoft Shell كاملة" 251 | IDS_CLASSICCTX "قوائم Windows 10" 252 | IDS_CLASSICTRANSPARENTCTX "قوائم Windows 10 شفافة" 253 | IDS_RESTARTEXPLORER "أعد تشغيل Explorer لحفظ البيانات" 254 | IDS_ELEVATIONNEEDED "تغيير الإعدادات الغير متاحة" 255 | IDS_VERSION "الإصدار:" 256 | IDS_Save "حفظ" 257 | IDS_CANCEL "إلغاء" 258 | IDS_IGNOREBG "حافظ على خلفيتي" 259 | IDS_IGNORECURSOR "حافظ على شكل الماوس" 260 | IDS_IGNOREIGONS "حافظ على شكل الأيقونات" 261 | IDS_IGNOREACCENT "حافظ على لوني المفضل" 262 | IDS_IGNORESOUNDS "حافظ على أصوات النظام الخاصة بي" 263 | IDS_IGNORESCREENSAVER "حافظ على شاشة الخمول الخاصة بي (في حالة وجودها)" 264 | END 265 | 266 | STRINGTABLE 267 | BEGIN 268 | IDS_NA "غير محدد" 269 | IDS_MENUS "القوائم" 270 | IDS_CPLTHEMEPREF "تغيير السمات في Rectify11" 271 | IDS_CPLTIP "تخصيص الإعدادات في Rectify11" 272 | IDS_SYSINFO "معلوات عن الجهاز" 273 | IDS_UNINSTALL "إزالة Rectify11" 274 | IDS_THEMETOOLSTATUS "حالة SecureUXTheme: " 275 | IDS_OK "مثالية" 276 | IDS_OUTDATED "إصدار قديم" 277 | IDS_NOTINSTALLED "غير مثبت" 278 | IDS_THEMETOOLWARN "مجهولة، برجاء إعادة التثبيت" 279 | IDS_THEMETOOLINSTALL "إعادة التثبيت" 280 | IDS_THEMETOOLALT "إعادة تثبيت SecureUXTheme في حالة عدم تطبيق النسق" 281 | IDS_ADVANCEDOPTIONS "خيارات متقدمة" 282 | END 283 | 284 | #endif // Arabic (Saudi Arabia) resources 285 | ///////////////////////////////////////////////////////////////////////////// 286 | 287 | 288 | 289 | #ifndef APSTUDIO_INVOKED 290 | ///////////////////////////////////////////////////////////////////////////// 291 | // 292 | // Generated from the TEXTINCLUDE 3 resource. 293 | // 294 | 295 | 296 | ///////////////////////////////////////////////////////////////////////////// 297 | #endif // not APSTUDIO_INVOKED 298 | 299 | -------------------------------------------------------------------------------- /Rectify11CPL/Rectify11CPL.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 17.0 23 | {50A4AEC2-9A0D-4F1C-8F38-EE7542BBE81A} 24 | Win32Proj 25 | 26 | 27 | 28 | DynamicLibrary 29 | v143 30 | MultiByte 31 | 32 | 33 | DynamicLibrary 34 | v143 35 | Unicode 36 | 37 | 38 | DynamicLibrary 39 | v143 40 | MultiByte 41 | 42 | 43 | DynamicLibrary 44 | v143 45 | Unicode 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | <_ProjectFileVersion>17.0.33312.129 69 | 70 | 71 | Debug\ 72 | Debug\ 73 | true 74 | 75 | 76 | true 77 | 78 | 79 | Release\ 80 | Release\ 81 | false 82 | 83 | 84 | false 85 | 86 | 87 | 88 | Disabled 89 | WIN32;_DEBUG;_WINDOWS;_USRDLL;FOLDERVIEWIMPL_EXPORTS;%(PreprocessorDefinitions) 90 | true 91 | Default 92 | MultiThreadedDebug 93 | true 94 | 95 | Level3 96 | EditAndContinue 97 | 98 | 99 | $(OutDir)Rectify11CPL.dll 100 | Rectify11CPL.def 101 | true 102 | $(OutDir)Rectify11CPL.pdb 103 | Windows 104 | $(OutDir)Rectify11CPL.lib 105 | MachineX86 106 | 107 | 108 | 109 | 110 | Disabled 111 | WIN32;_DEBUG;_WINDOWS;_USRDLL;FOLDERVIEWIMPL_EXPORTS;PROXY_CLSID=a;PROXY_CLSID_IS=b;%(PreprocessorDefinitions) 112 | Default 113 | MultiThreadedDebug 114 | true 115 | 116 | 117 | Level3 118 | ProgramDatabase 119 | stdcpp20 120 | 121 | 122 | $(OutDir)Rectify11CPL.dll 123 | Rectify11CPL.def 124 | true 125 | $(OutDir)Rectify11CPL.pdb 126 | Windows 127 | $(OutDir)Rectify11CPL.lib 128 | Comctl32.lib;rpcns4.lib;rpcrt4.lib;uuid.lib;ntdll.lib;%(AdditionalDependencies) 129 | 130 | 131 | copy /Y $(OutDir)Rectify11CPL.dll $(SolutionDir)\Rectify11Installer\Resources\ 132 | 133 | 134 | 135 | 136 | true 137 | 138 | 139 | 140 | 141 | MaxSpeed 142 | OnlyExplicitInline 143 | true 144 | WIN32;NDEBUG;_WINDOWS;_USRDLL;FOLDERVIEWIMPL_EXPORTS;%(PreprocessorDefinitions) 145 | true 146 | MultiThreaded 147 | true 148 | Use 149 | Level3 150 | ProgramDatabase 151 | 152 | 153 | $(OutDir)Rectify11CPL.dll 154 | true 155 | Windows 156 | true 157 | true 158 | $(OutDir)Rectify11CPL.lib 159 | MachineX86 160 | 161 | 162 | 163 | 164 | MaxSpeed 165 | OnlyExplicitInline 166 | true 167 | WIN32;NDEBUG;_WINDOWS;_USRDLL;FOLDERVIEWIMPL_EXPORTS;%(PreprocessorDefinitions) 168 | true 169 | MultiThreaded 170 | true 171 | NotUsing 172 | Level3 173 | EditAndContinue 174 | stdcpp20 175 | 176 | 177 | $(OutDir)Rectify11CPL.dll 178 | true 179 | Windows 180 | true 181 | true 182 | $(OutDir)Rectify11CPL.lib 183 | Comctl32.lib;rpcns4.lib;rpcrt4.lib;uuid.lib;ntdll.lib;%(AdditionalDependencies) 184 | Rectify11CPL.def 185 | 186 | 187 | copy /Y $(OutDir)Rectify11CPL.dll $(SolutionDir)\Rectify11Installer\Resources\ 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | {0b7de49a-33c6-41b1-a9ce-d353031f8454} 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /Rectify11CPL/Rectify11CPL.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | Navpane 9 | 10 | 11 | Navpane 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Pages 20 | 21 | 22 | Pages 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Navpane 34 | 35 | 36 | Navpane 37 | 38 | 39 | Navpane 40 | 41 | 42 | 43 | 44 | 45 | 46 | Pages 47 | 48 | 49 | Pages 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | Pages 61 | 62 | 63 | 64 | 65 | Resources 66 | 67 | 68 | Resources 69 | 70 | 71 | Resources 72 | 73 | 74 | 75 | 76 | 77 | Pages 78 | 79 | 80 | 81 | 82 | {8b73cde0-0b02-48cb-8cf1-398e18cf959a} 83 | 84 | 85 | {d80f80cc-b6fb-44dd-a072-8e5b17ed81be} 86 | 87 | 88 | {efa0e6bc-fb45-4e7c-968b-72eb63c837a3} 89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Rectify11CPL/RectifyMainPage.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectify11CPL.h" 2 | #include "RectifyMainPage.h" 3 | #include "CRectifyUtil.h" 4 | #include "ElevationManager.h" 5 | #include "CControlPanelNavLinkCommand.h" 6 | #include "CControlPanelNavLink.h" 7 | #include "CControlPanelNavLinks.h" 8 | #include 9 | 10 | IClassInfo* RectifyMainPage::Class = NULL; 11 | 12 | 13 | RectifyMainPage::RectifyMainPage() 14 | { 15 | 16 | } 17 | 18 | RectifyMainPage::~RectifyMainPage() 19 | { 20 | 21 | } 22 | 23 | HRESULT RectifyMainPage::CreateInstance(Element* rootElement, unsigned long* debug_variable, Element** newElement) 24 | { 25 | int hr = E_OUTOFMEMORY; 26 | 27 | // Using HeapAlloc instead of new() is required as DirectUI::Element::_DisplayNodeCallback calls HeapFree() with the element 28 | RectifyMainPage* instance = (RectifyMainPage*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RectifyMainPage)); 29 | 30 | if (instance != NULL) 31 | { 32 | new (instance) RectifyMainPage(); 33 | hr = instance->Initialize(0, rootElement, debug_variable); 34 | if (SUCCEEDED(hr)) 35 | { 36 | *newElement = instance; 37 | } 38 | else 39 | { 40 | if (instance != NULL) 41 | { 42 | instance->Destroy(TRUE); 43 | instance = NULL; 44 | } 45 | } 46 | } 47 | 48 | return hr; 49 | } 50 | 51 | IClassInfo* RectifyMainPage::GetClassInfoW() 52 | { 53 | return RectifyMainPage::Class; 54 | } 55 | 56 | void RectifyMainPage::OnEvent(Event* iev) 57 | { 58 | if (iev->flag != GMF_BUBBLED) 59 | return; 60 | if (!iev->handled) 61 | Element::OnEvent(iev); 62 | 63 | if (initializing) return; 64 | if (iev->target->GetID() == StrToID((UCString)L"Link_EnableAdmin")) 65 | { 66 | if (iev->type == TouchButton::Click) 67 | { 68 | IRectifyUtil* utility = ElevationManager::Initialize(GetMainHwnd()); 69 | TouchCheckBox* MicaForEveryoneCheckbox = (TouchCheckBox*)FindDescendent(StrToID((UCString)L"MicaChk")); 70 | TouchCheckBox* TabbedCheckbox = (TouchCheckBox*)FindDescendent(StrToID((UCString)L"TabChk")); 71 | TouchButton* ThemetoolInstall = (TouchButton*)FindDescendent(StrToID((UCString)L"ThemetoolInstall")); 72 | if (utility != NULL) 73 | { 74 | // Destroy old class 75 | if (RectifyUtil != NULL) 76 | { 77 | RectifyUtil->Release(); 78 | } 79 | 80 | RectifyUtil = utility; 81 | HasAdmin = TRUE; 82 | 83 | ULONG key = 0; 84 | this->StartDefer(&key); 85 | iev->target->SetLayoutPos(-3); 86 | iev->target->SetVisible(FALSE); 87 | ThemetoolInstall->SetEnabled(TRUE); 88 | 89 | MicaForEveryoneCheckbox->SetEnabled(TRUE); 90 | if (MicaForEveryoneCheckbox->GetCheckedState() != CheckedStateFlags_NONE) 91 | TabbedCheckbox->SetEnabled(TRUE); 92 | 93 | 94 | CCRadioButton* Win11DefaultMenus = (CCRadioButton*)FindDescendent(StrToID((UCString)L"Win11DefaultMenus")); 95 | CCRadioButton* NilesoftSmall = (CCRadioButton*)FindDescendent(StrToID((UCString)L"NilesoftSmall")); 96 | CCRadioButton* NilesoftFull = (CCRadioButton*)FindDescendent(StrToID((UCString)L"NilesoftFull")); 97 | CCRadioButton* Classic = (CCRadioButton*)FindDescendent(StrToID((UCString)L"Classic")); 98 | CCRadioButton* ClassicTransparent = (CCRadioButton*)FindDescendent(StrToID((UCString)L"ClassicTransparent")); 99 | 100 | CCRadioButton* Options[] = { Win11DefaultMenus, NilesoftSmall, NilesoftFull, Classic, ClassicTransparent }; 101 | for (size_t i = 0; i < 5; i++) 102 | { 103 | Options[i]->SetEnabled(TRUE); 104 | } 105 | 106 | this->EndDefer(key); 107 | } 108 | } 109 | } 110 | else if (iev->target->GetID() == StrToID((UCString)L"BtnRestartExplorer")) 111 | { 112 | if (iev->type == TouchButton::Click) 113 | { 114 | CRectifyUtil::RestartExplorer(); 115 | 116 | // hide restart explorer button 117 | iev->target->SetLayoutPos(-3); 118 | iev->target->SetVisible(FALSE); 119 | } 120 | } 121 | else if (iev->target->GetID() == StrToID((UCString)L"ThemeCmb")) 122 | { 123 | if (iev->type == Combobox::SelectionChange) 124 | { 125 | TouchCheckBox* MicaForEveryoneCheckbox = (TouchCheckBox*)FindDescendent(StrToID((UCString)L"MicaChk")); 126 | TouchCheckBox* TabbedCheckbox = (TouchCheckBox*)FindDescendent(StrToID((UCString)L"TabChk")); 127 | int selection = ((Combobox*)iev->target)->GetSelection(); 128 | 129 | ULONG apply_flags = 0; 130 | 131 | // load appy flags 132 | HKEY Rectify11; 133 | if (RegCreateKey(HKEY_CURRENT_USER, Rectify11PrefsKey, &Rectify11)) 134 | { 135 | SHOW_ERROR("Failed to create Rectify11Prefs key"); 136 | return; 137 | } 138 | 139 | DWORD size = 4; 140 | 141 | DWORD IgnoreBgVal = 0; 142 | DWORD IgnoreCursorsVal = 0; 143 | DWORD IgnoreIconsVal = 0; 144 | DWORD IgnoreColorsVal = 0; 145 | DWORD IgnoreSoundsVal = 0; 146 | DWORD IgnoreScreensaversVal = 0; 147 | 148 | RegQueryValueExW(Rectify11, L"IgnoreBg", 0, NULL, (LPBYTE)&IgnoreBgVal, &size); 149 | RegQueryValueExW(Rectify11, L"IgnoreCursors", 0, NULL, (LPBYTE)&IgnoreCursorsVal, &size); 150 | RegQueryValueExW(Rectify11, L"IgnoreIcons", 0, NULL, (LPBYTE)&IgnoreIconsVal, &size); 151 | RegQueryValueExW(Rectify11, L"IgnoreColors", 0, NULL, (LPBYTE)&IgnoreColorsVal, &size); 152 | RegQueryValueExW(Rectify11, L"IgnoreSounds", 0, NULL, (LPBYTE)&IgnoreSoundsVal, &size); 153 | RegQueryValueExW(Rectify11, L"IgnoreScreensavers", 0, NULL, (LPBYTE)&IgnoreScreensaversVal, &size); 154 | RegCloseKey(Rectify11); 155 | 156 | if (IgnoreBgVal) 157 | { 158 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_BACKGROUND; 159 | } 160 | if (IgnoreCursorsVal) 161 | { 162 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_CURSOR; 163 | } 164 | if (IgnoreIconsVal) 165 | { 166 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_DESKTOP_ICONS; 167 | } 168 | if (IgnoreColorsVal) 169 | { 170 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_COLOR; 171 | } 172 | if (IgnoreSoundsVal) 173 | { 174 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_SOUND; 175 | } 176 | if (IgnoreSoundsVal) 177 | { 178 | apply_flags |= THEMETOOL_APPLY_FLAG_IGNORE_SCREENSAVER; 179 | } 180 | 181 | // apply the theme 182 | themetool_set_active(NULL, themes[selection], TRUE, apply_flags, 0); 183 | UpdateThemeGraphic(); 184 | 185 | // update mica 186 | if (HasAdmin) 187 | { 188 | BOOL hasMica = FALSE; 189 | BOOL hasTabbed = FALSE; 190 | RectifyUtil->GetMicaSettings(&hasMica, &hasTabbed); 191 | RectifyUtil->SetMicaForEveryoneEnabled(hasMica, hasTabbed); 192 | 193 | // update checkboxes in case we aren't using a mica theme anymore 194 | MicaForEveryoneCheckbox->SetCheckedState(hasMica ? CheckedStateFlags_CHECKED : CheckedStateFlags_NONE); 195 | TabbedCheckbox->SetCheckedState(hasTabbed ? CheckedStateFlags_CHECKED : CheckedStateFlags_NONE); 196 | } 197 | } 198 | } 199 | else if (iev->target->GetID() == StrToID((UCString)L"buttonHelp")) 200 | { 201 | if (iev->type == Button::Click) 202 | { 203 | ShellExecute(0, 0, TEXT("http://rectify11.net"), 0, 0, SW_SHOW); 204 | } 205 | } 206 | else if (iev->target->GetID() == StrToID((UCString)L"MicaChk")) 207 | { 208 | TouchCheckBox* MicaForEveryoneCheckbox = (TouchCheckBox*)iev->target; 209 | TouchCheckBox* TabbedCheckbox = (TouchCheckBox*)GetRoot()->FindDescendent(StrToID((UCString)L"TabChk")); 210 | Combobox* ThemeCombo = (Combobox*)GetRoot()->FindDescendent(StrToID((UCString)L"ThemeCmb")); 211 | if (iev->type == TouchButton::Click) 212 | { 213 | CheckedStateFlags MicaEnabled2 = MicaForEveryoneCheckbox->GetCheckedState(); 214 | CheckedStateFlags TabbedEnabled = TabbedCheckbox->GetCheckedState(); 215 | 216 | RectifyUtil->SetMicaForEveryoneEnabled(MicaEnabled2 == CheckedStateFlags_CHECKED ? TRUE : FALSE, TabbedEnabled ? CheckedStateFlags_CHECKED : CheckedStateFlags_NONE); 217 | 218 | // Enable/disable the tabbed checkbox 219 | if (TabbedCheckbox != NULL) 220 | TabbedCheckbox->SetEnabled(MicaEnabled2 == CheckedStateFlags_CHECKED ? TRUE : FALSE); 221 | } 222 | } 223 | else if (iev->target->GetID() == StrToID((UCString)L"TabChk")) 224 | { 225 | TouchCheckBox* TabbedCheckbox = (TouchCheckBox*)iev->target; 226 | Combobox* ThemeCombo = (Combobox*)FindDescendent(StrToID((UCString)L"ThemeCmb")); 227 | 228 | if (iev->type == TouchButton::Click) 229 | { 230 | RectifyUtil->SetMicaForEveryoneEnabled(TRUE, TabbedCheckbox->GetCheckedState() == CheckedStateFlags_CHECKED ? TRUE : FALSE); 231 | } 232 | } 233 | else if (iev->target->GetID() == StrToID((UCString)L"ThemetoolInstall")) 234 | { 235 | iev->target->SetEnabled(FALSE); 236 | HRESULT hr = RectifyUtil->InstallThemeTool(); 237 | if (FAILED(hr)) 238 | { 239 | CHAR buffer[1024]; 240 | std::string message = std::system_category().message(hr); 241 | 242 | snprintf(buffer, sizeof(buffer), "Failed to install SecureUxTheme. Error code is %x, which translates to %s.", hr, message.c_str()); 243 | MessageBoxA(GetMainHwnd(), buffer, "Error during SecureUxTheme install", MB_ICONERROR); 244 | } 245 | 246 | UpdateThemetoolStatus(); 247 | iev->target->SetEnabled(TRUE); 248 | } 249 | // handle menu section 250 | if (iev->type == Button::Click && !wcscmp((const wchar_t*)iev->target->GetClassInfoW()->GetName(), (const wchar_t*)CCRadioButton::GetClassInfoPtr()->GetName())) 251 | { 252 | CCRadioButton* chkbox = (CCRadioButton*)iev->target; 253 | if (chkbox->GetSelected()) 254 | { 255 | HRESULT hr = E_ACTIVATIONDENIED_SHELLERROR; 256 | if (chkbox->GetID() == StrToID((UCString)L"Win11DefaultMenus")) 257 | { 258 | hr = RectifyUtil->SetCurrentMenuByIndex(Normal); 259 | } 260 | else if (chkbox->GetID() == StrToID((UCString)L"NilesoftSmall")) 261 | { 262 | hr = RectifyUtil->SetCurrentMenuByIndex(NilesoftSmall); 263 | } 264 | else if (chkbox->GetID() == StrToID((UCString)L"NilesoftFull")) 265 | { 266 | hr = RectifyUtil->SetCurrentMenuByIndex(NilesoftFull); 267 | } 268 | else if (chkbox->GetID() == StrToID((UCString)L"Classic")) 269 | { 270 | hr = RectifyUtil->SetCurrentMenuByIndex(Classic); 271 | } 272 | else if (chkbox->GetID() == StrToID((UCString)L"ClassicTransparent")) 273 | { 274 | hr = RectifyUtil->SetCurrentMenuByIndex(ClassicTransparent); 275 | } 276 | 277 | if (FAILED(hr)) 278 | { 279 | WCHAR buffer[200]; 280 | swprintf(buffer, 199, L"Failed to update menu settings. HRESULT is %x", hr); 281 | MessageBox(NULL, buffer, TEXT("ClassicTransparent_OnEvent"), MB_ICONERROR); 282 | } 283 | else 284 | { 285 | ShowRestartExplorer(); 286 | } 287 | } 288 | } 289 | } 290 | 291 | void RectifyMainPage::ShowRestartExplorer() 292 | { 293 | TouchButton* BtnRestartExplorer = (TouchButton*)FindDescendent(StrToID((UCString)L"BtnRestartExplorer")); 294 | BtnRestartExplorer->SetLayoutPos(0); 295 | BtnRestartExplorer->SetVisible(TRUE); 296 | } 297 | 298 | void RectifyMainPage::UpdateThemeGraphic() 299 | { 300 | LPCWSTR id = IsDarkTheme() ? MAKEINTRESOURCE(IDB_DARKPREVIEW) : MAKEINTRESOURCE(IDB_LIGHTPREVIEW); 301 | HBITMAP bmp = (HBITMAP)LoadImage(g_hInst, id, IMAGE_BITMAP, 256, 256, 0); 302 | if (bmp == NULL) 303 | { 304 | return; 305 | } 306 | Value* bitmap = DirectUI::Value::CreateGraphic(bmp, 3, 0xffffffff, false, false, false); 307 | Element* PreviewElement = FindDescendent(StrToID((UCString)L"ThemePreview")); 308 | if (PreviewElement != NULL) 309 | PreviewElement->SetValue(Element::ContentProp, 1, bitmap); 310 | bitmap->Release(); 311 | } 312 | 313 | void RectifyMainPage::InitNavLinks() 314 | { 315 | auto links = new CControlPanelNavLinks(); 316 | 317 | WCHAR themePrefString[1024]; 318 | if (FAILED(LoadStringW(g_hInst, IDS_UPDATE, themePrefString, 1023))) 319 | { 320 | wcscpy_s(themePrefString, L"[ THEME APPLY PREF ]"); 321 | } 322 | WCHAR sysInfoString[1024]; 323 | if (FAILED(LoadStringW(g_hInst, IDS_SYSINFO, sysInfoString, 1023))) 324 | { 325 | wcscpy_s(sysInfoString, L"[ SYS INFO ]"); 326 | } 327 | WCHAR uninstallString[1024]; 328 | if (FAILED(LoadStringW(g_hInst, IDS_UNINSTALL, uninstallString, 1023))) 329 | { 330 | wcscpy_s(uninstallString, L"[ UNINSTALL ]"); 331 | } 332 | 333 | links->AddLinkControlPanel(themePrefString, L"Rectify11.SettingsCPL", L"pageThemePref", CPNAV_Normal, NULL); 334 | links->AddLinkShellEx(uninstallString, L"C:\\Windows\\Rectify11\\Uninstall.exe", L"", CPNAV_Normal, NULL); 335 | links->AddLinkControlPanel(sysInfoString, L"Microsoft.System", L"", CPNAV_SomethingElse, NULL); 336 | 337 | 338 | GUID SID_PerLayoutPropertyBag = {}; 339 | HRESULT hr = CLSIDFromString(L"{a46e5c25-c09c-4ca8-9a53-49cf7f865525}", (LPCLSID)&SID_PerLayoutPropertyBag); 340 | if (SUCCEEDED(hr)) 341 | { 342 | IPropertyBag* bag = NULL; 343 | int hr = IUnknown_QueryService(site, SID_PerLayoutPropertyBag, IID_IPropertyBag, (LPVOID*)&bag); 344 | if (SUCCEEDED(hr)) 345 | { 346 | if (SUCCEEDED(PSPropertyBag_WriteUnknown(bag, L"ControlPanelNavLinks", links))) 347 | { 348 | 349 | } 350 | else { 351 | MessageBox(NULL, TEXT("Failed to write property bag for navigation links"), TEXT("CElementProvider::InitNavLinks"), 0); 352 | } 353 | bag->Release(); 354 | } 355 | else { 356 | MessageBox(NULL, TEXT("Failed to get property bag for navigation links"), TEXT("CElementProvider::InitNavLinks"), 0); 357 | } 358 | } 359 | else 360 | { 361 | MessageBox(NULL, TEXT("Failed to parse hardcoded GUID (SID_PerLayoutPropertyBag)"), TEXT("CElementProvider::InitNavLinks"), 0); 362 | } 363 | } 364 | 365 | void RectifyMainPage::UpdateThemetoolStatus() 366 | { 367 | Element* status = (TouchButton*)FindDescendent(StrToID((UCString)L"ThemetoolStatus")); 368 | 369 | ULONG flags = secureuxtheme_get_state_flags(); 370 | wstring statusText; 371 | 372 | WCHAR buffer1[1024]; 373 | if (FAILED(LoadStringW(g_hInst, IDS_THEMETOOLSTATUS, buffer1, 1023))) 374 | { 375 | wcscpy_s(buffer1, L"[SECURE UX STATUS STRING MISSING]: "); 376 | } 377 | 378 | statusText += buffer1; 379 | 380 | 381 | if (flags & SECUREUXTHEME_STATE_INSTALLED) 382 | { 383 | if (flags & SECUREUXTHEME_STATE_CURRENT) 384 | { 385 | if (FAILED(LoadStringW(g_hInst, IDS_OK, buffer1, 1023))) 386 | { 387 | wcscpy_s(buffer1, L"OK STRING MISSING"); 388 | } 389 | 390 | statusText += buffer1; 391 | 392 | status->SetForegroundStdColor(44); // forest green 393 | } 394 | else { 395 | if (FAILED(LoadStringW(g_hInst, IDS_OUTDATED, buffer1, 1023))) 396 | { 397 | wcscpy_s(buffer1, L"OUTDATED STRING MISSING"); 398 | } 399 | 400 | statusText += buffer1; 401 | 402 | status->SetForegroundStdColor(138); // yellow 403 | } 404 | } 405 | else { 406 | if (FAILED(LoadStringW(g_hInst, IDS_NOTINSTALLED, buffer1, 1023))) 407 | { 408 | wcscpy_s(buffer1, L"NOT INSTALLED STRING MISSING"); 409 | } 410 | 411 | statusText += buffer1; 412 | 413 | status->SetForegroundStdColor(113); // red 414 | } 415 | 416 | status->SetContentString((UCString)statusText.c_str()); 417 | } 418 | 419 | void RectifyMainPage::OnInit() 420 | { 421 | Element* root = GetRoot(); 422 | RectifyUtil = (IRectifyUtil*)new CRectifyUtil(); 423 | InitNavLinks(); 424 | 425 | Combobox* ThemeCombo = (Combobox*)root->FindDescendent(StrToID((UCString)L"ThemeCmb")); 426 | Button* HelpButton = (Button*)root->FindDescendent(StrToID((UCString)L"buttonHelp")); 427 | TouchCheckBox* MicaForEveryoneCheckbox = (TouchCheckBox*)root->FindDescendent(StrToID((UCString)L"MicaChk")); 428 | TouchCheckBox* TabbedCheckbox = (TouchCheckBox*)root->FindDescendent(StrToID((UCString)L"TabChk")); 429 | Element* version = (Element*)root->FindDescendent(StrToID((UCString)L"RectifyVersion")); 430 | TouchButton* enableAdmin = (TouchButton*)root->FindDescendent(StrToID((UCString)L"Link_EnableAdmin")); 431 | TouchButton* BtnRestartExplorer = (TouchButton*)root->FindDescendent(StrToID((UCString)L"BtnRestartExplorer")); 432 | TouchButton* ThemetoolInstall = (TouchButton*)root->FindDescendent(StrToID((UCString)L"ThemetoolInstall")); 433 | 434 | CCRadioButton* Win11DefaultMenus = (CCRadioButton*)root->FindDescendent(StrToID((UCString)L"Win11DefaultMenus")); 435 | CCRadioButton* NilesoftSmall = (CCRadioButton*)root->FindDescendent(StrToID((UCString)L"NilesoftSmall")); 436 | CCRadioButton* NilesoftFull = (CCRadioButton*)root->FindDescendent(StrToID((UCString)L"NilesoftFull")); 437 | CCRadioButton* Classic = (CCRadioButton*)root->FindDescendent(StrToID((UCString)L"Classic")); 438 | CCRadioButton* ClassicTransparent = (CCRadioButton*)root->FindDescendent(StrToID((UCString)L"ClassicTransparent")); 439 | 440 | CCRadioButton* Options[] = { Win11DefaultMenus, NilesoftSmall, NilesoftFull, Classic, ClassicTransparent }; 441 | 442 | if (ThemeCombo != NULL) 443 | { 444 | WCHAR value[255] = { 0 }; 445 | PVOID pvData = value; 446 | DWORD size = sizeof(value); 447 | RegGetValue(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\ThemeManager", L"DllName", RRF_RT_REG_SZ, 0, pvData, &size); 448 | std::wstring msstylePath = std::wstring((LPCWSTR)pvData); 449 | int k = 0; 450 | ULONG themeCount = 0; 451 | if (SUCCEEDED(themetool_get_theme_count(&themeCount))) 452 | { 453 | for (ULONG i = 0; i < themeCount; i++) 454 | { 455 | ITheme* theme = NULL; 456 | if (SUCCEEDED(themetool_get_theme(i, &theme))) 457 | { 458 | std::wstring nameBuffer = std::wstring(255, '\0'); 459 | theme->GetDisplayName(nameBuffer); 460 | 461 | if (nameBuffer.starts_with(L"Rectify11")) 462 | { 463 | ThemeCombo->AddString((UString)nameBuffer.c_str()); 464 | std::wstring pathBuff = std::wstring(); 465 | theme->GetVisualStyle(pathBuff); 466 | std::wstring msstylePath = std::wstring((LPCWSTR)pvData); 467 | 468 | std::wstring msstylePathClean = msstylePath; 469 | 470 | const size_t last_slash_idx = msstylePathClean.find_last_of(L"\\/"); 471 | if (std::string::npos != last_slash_idx) 472 | { 473 | msstylePathClean.erase(0, last_slash_idx + 1); 474 | } 475 | 476 | // Remove extension if present. 477 | const size_t period_idx = msstylePathClean.rfind('.'); 478 | if (std::string::npos != period_idx) 479 | { 480 | msstylePathClean.erase(period_idx); 481 | } 482 | 483 | ThemesMap[k] = msstylePathClean; 484 | if (pathBuff == msstylePath) 485 | { 486 | ThemeCombo->SetSelection(k); 487 | } 488 | themes.push_back(i); 489 | k++; 490 | } 491 | } 492 | themetool_theme_release(theme); 493 | } 494 | } 495 | else { 496 | MessageBox(NULL, TEXT("Failed to count the amount of themes"), TEXT("CElementProvider::LayoutInitialized"), MB_ICONERROR); 497 | } 498 | 499 | if (version != NULL) 500 | { 501 | WCHAR value[255] = { 0 }; 502 | PVOID pvData = value; 503 | DWORD size = sizeof(value); 504 | LONG result = RegGetValue(HKEY_LOCAL_MACHINE, L"Software\\Rectify11", L"Version", RRF_RT_REG_SZ, 0, pvData, &size); 505 | std::wstring vstr = std::wstring(L""); 506 | if (result == 0) 507 | { 508 | WCHAR versionstr[1024]; 509 | if (FAILED(LoadStringW(g_hInst, IDS_VERSION, versionstr, 1023))) 510 | { 511 | wcscpy_s(versionstr, L"[VERSION STRING MISSING]: "); 512 | } 513 | vstr += versionstr; 514 | vstr += L" "; 515 | vstr += value; 516 | } 517 | else 518 | { 519 | WCHAR versionstr[1024]; 520 | WCHAR notapplicable[1024]; 521 | if (FAILED(LoadStringW(g_hInst, IDS_VERSION, versionstr, 1023))) 522 | { 523 | wcscpy_s(versionstr, L"[VERSION STRING MISSING]: "); 524 | } 525 | if (FAILED(LoadStringW(g_hInst, IDS_NA, notapplicable, 1023))) 526 | { 527 | wcscpy_s(notapplicable, L"[N/A STRING MISSING]: "); 528 | } 529 | 530 | vstr += versionstr; 531 | vstr += L" "; 532 | vstr += notapplicable; 533 | } 534 | version->SetContentString((UCString)vstr.c_str()); 535 | } 536 | } 537 | 538 | if (MicaForEveryoneCheckbox != NULL) 539 | { 540 | MicaForEveryoneCheckbox->SetToggleOnClick(true); 541 | BOOL MicaEnabled; 542 | BOOL TabbedEnabled; 543 | RectifyUtil->GetMicaSettings(&MicaEnabled, &TabbedEnabled); 544 | 545 | MicaForEveryoneCheckbox->SetCheckedState(MicaEnabled ? CheckedStateFlags_CHECKED : CheckedStateFlags_NONE); 546 | 547 | if (!MicaEnabled && TabbedCheckbox != NULL) 548 | { 549 | TabbedCheckbox->SetEnabled(FALSE); 550 | } 551 | } 552 | 553 | if (TabbedCheckbox != NULL) 554 | { 555 | BOOL MicaEnabled; 556 | BOOL TabbedEnabled; 557 | RectifyUtil->GetMicaSettings(&MicaEnabled, &TabbedEnabled); 558 | 559 | TabbedCheckbox->SetToggleOnClick(true); 560 | TabbedCheckbox->SetCheckedState(MicaEnabled ? CheckedStateFlags_CHECKED : CheckedStateFlags_NONE); 561 | } 562 | 563 | if (BtnRestartExplorer != NULL) 564 | { 565 | BtnRestartExplorer->SetLayoutPos(-3); 566 | BtnRestartExplorer->SetVisible(FALSE); 567 | } 568 | 569 | DWORD menuIndex; 570 | 571 | for (size_t i = 0; i < 5; i++) 572 | { 573 | if (!HasAdmin) 574 | Options[i]->SetEnabled(FALSE); 575 | else 576 | Options[i]->SetEnabled(TRUE); 577 | } 578 | if (SUCCEEDED(RectifyUtil->GetCurrentMenuIndex(&menuIndex))) 579 | { 580 | Options[menuIndex]->SetSelected(true); 581 | } 582 | 583 | if (HasAdmin) 584 | { 585 | enableAdmin->SetLayoutPos(-3); 586 | enableAdmin->SetVisible(FALSE); 587 | ThemetoolInstall->SetEnabled(TRUE); 588 | } 589 | else 590 | { 591 | MicaForEveryoneCheckbox->SetEnabled(FALSE); 592 | TabbedCheckbox->SetEnabled(FALSE); 593 | ThemetoolInstall->SetEnabled(FALSE); 594 | } 595 | 596 | UpdateThemetoolStatus(); 597 | 598 | UpdateThemeGraphic(); 599 | initializing = false; 600 | } 601 | 602 | HWND RectifyMainPage::GetMainHwnd() 603 | { 604 | GUID SID_STopLevelBrowser = {}, IID_IFrameManager = {}; 605 | HRESULT hr = CLSIDFromString(L"{4c96be40-915c-11cf-99d3-00aa004ae837}", (LPCLSID)&SID_STopLevelBrowser); 606 | HWND result = NULL; 607 | if (SUCCEEDED(hr)) 608 | { 609 | hr = CLSIDFromString(L"{31e4fa78-02b4-419f-9430-7b7585237c77}", (LPCLSID)&IID_IFrameManager); 610 | if (SUCCEEDED(hr)) 611 | { 612 | IShellBrowser* browser = NULL; 613 | if (SUCCEEDED(IUnknown_QueryService(site, SID_STopLevelBrowser, IID_IShellBrowser, (LPVOID*)&browser))) 614 | { 615 | browser->GetWindow(&result); 616 | browser->Release(); 617 | } 618 | } 619 | } 620 | 621 | return result; 622 | } 623 | 624 | void RectifyMainPage::OnDestroy() 625 | { 626 | if (RectifyUtil != NULL) 627 | { 628 | RectifyUtil->Release(); 629 | RectifyUtil = NULL; 630 | } 631 | 632 | Element::OnDestroy(); 633 | } -------------------------------------------------------------------------------- /Rectify11CPL/RectifyMainPage.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "IRectifyUtil_h.h" 4 | typedef std::map ThemesMapBase; 5 | 6 | class RectifyMainPage : public Element 7 | { 8 | public: 9 | 10 | RectifyMainPage(); 11 | virtual ~RectifyMainPage() override; 12 | 13 | static DirectUI::IClassInfo* Class; 14 | static HRESULT CreateInstance(Element* a, unsigned long* b, Element** c); 15 | 16 | //Element 17 | virtual IClassInfo* GetClassInfoW() override; 18 | 19 | // Element overrides 20 | virtual void OnEvent(Event* iev) override; 21 | virtual void OnDestroy() override; 22 | 23 | // Important methods 24 | virtual void OnInit(); 25 | virtual void SetSite(IUnknown* site) { this->site = site; } 26 | 27 | static inline DirectUI::IClassInfo* GetClassInfoPtr() { return Class; } 28 | static inline UCString DoGetClassName() { return (UCString)L"RectifyMainPage"; } 29 | private: 30 | bool HasAdmin = false; 31 | IRectifyUtil* RectifyUtil = NULL; 32 | vector themes; 33 | ThemesMapBase ThemesMap; 34 | IUnknown* site = NULL; 35 | bool initializing = true; 36 | 37 | void UpdateThemeGraphic(); 38 | void ShowRestartExplorer(); 39 | void InitNavLinks(); 40 | void UpdateThemetoolStatus(); 41 | HWND GetMainHwnd(); 42 | }; -------------------------------------------------------------------------------- /Rectify11CPL/RectifyMainPage.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 224 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 |