ARTICLE AD BOX
I'm trying to write a program that I can fire off from a button on my MOBA mouse that will toggle Windows 11's "Text Size" setting (Settings app > Accessibility > Text Size > the slider at the top of the page) between 100% and my preferred value. I figured out what registry entry I need to change (HKEY_CURRENT_USER\SOFTWARE\Microsoft\Accessibility\TextScaleFactor) and how to change it in C++ (which seems to be the only language that has all of the necessary APIs and things as far as I can tell) by doing a lot of Googling, but it still doesn't work quite right.
Specifically, when I change the setting through the Settings app, Windows shows a "Please wait" screen for a few seconds, and then every open window has redrawn itself to account for the changed text size, but when I manually edit the registry entry using my program as I have written it so far, none of this happens, and most windows don't recognize the change, except for Microsoft Edge which redraws itself, but only once I switch back to it (i.e. with alt-tab).
I read that I need to broadcast a WM_SETTINGCHANGE message on this Reddit comment and on the Stack Overflow thread that it links to, which I tried, but that doesn't seem to have done anything. I also tried restarting Windows Explorer after running the program, and that didn't do anything helpful either. I also read on this forum post that there are some other registry entries that I might need to worry about, and I tested and found that only the ones from that list that are related to fonts (and of course the TextScaleFactor one) actually changed when I changed the setting through the Settings app, so I could try changing those registry keys too, but I am burned out enough from working on this (while not having much experience with C++) that I just want to be done with it.
Am I doing anything wrong? Is there even a good way to do what I'm trying to do?
Here is my code (created and tested with Visual Studio 2022):
#ifndef UNICODE #define UNICODE #endif #include <windows.h> #include <malloc.h> #include <iostream> // ToggleTextScale.cpp : This file contains the 'main' function. Program execution begins and ends there. // // Constants constexpr auto PREFERRED_TEXT_SCALE = 175; // Should be replaced with a command line arg. constexpr auto DEFAULT_TEXT_SCALE = 100; int main() { // Declaring a bunch of variables that I'm gonna need later. LONG lResult; DWORD dwRet; DWORD cbData; HKEY hKey; DWORD_PTR broadcastResult; LPBYTE textScaleFactor_ptr = (LPBYTE)malloc(sizeof REG_DWORD); // <- This is the important one! // Check for if the ptr is null so Visual Studio doesn't yell at me about it. if (textScaleFactor_ptr) { // Open the Reg key that has the value I need. lResult = RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Accessibility"), 0, KEY_READ | KEY_SET_VALUE, &hKey); // Get the value. cbData = 4; dwRet = RegQueryValueEx(hKey, TEXT("TextScaleFactor"), NULL, NULL, textScaleFactor_ptr, &cbData); // If the text scaling is 100%, change to preferred value. // Otherwise, change to 100%. if ((int)*textScaleFactor_ptr == 100) { DWORD preferredVal = PREFERRED_TEXT_SCALE; lResult = RegSetValueEx(hKey, TEXT("TextScaleFactor"), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&preferredVal), sizeof(preferredVal)); } else { DWORD defaultVal = DEFAULT_TEXT_SCALE; lResult = RegSetValueEx(hKey, TEXT("TextScaleFactor"), 0, REG_DWORD, reinterpret_cast<const BYTE*>(&defaultVal), sizeof(defaultVal)); } // Broadcast a message so Windows knows something changed and can do its thing. SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, (LPARAM)TEXT("TextScaleFactor"), 0, 1000, &broadcastResult); // Close the registry key. RegCloseKey(hKey); // Free the important pointer to clean up. free(textScaleFactor_ptr); // Final return. return ERROR_SUCCESS; } else { // Clean up if the important pointer didn't work. free(textScaleFactor_ptr); return ERROR_NOT_ENOUGH_MEMORY; } }