display settings - scaling

Started by Lmcomputers, June 27, 2024, 04:57:53 AM

Previous topic - Next topic

Lmcomputers

Hi,

I want to be able to control the scaling on a windows 10 display.

Ideally during dymanically i would like to change from 100% to 175% and then back again. so screen setting resolution would be 1920x1080 scaling 175% or 1920x1080 scaling 100%

I have found some code which shows how to change the resolution but not the scaling can you help please

thanks in advance
Andrew

td

Unfortunately, there is not a straightforward way to make the change. You would need to either edit the registry or use DllCall to call the SystemParametersInfoA function using an undocumented setting SPI_SETLOGICALDPIOVERRIDE. It is a bit tricky because the second parameter is a set value relative to the system's preferred scaling. For example, to go from a recommended scaling of 125% to 150% the second parameter would be set to 1. Also, the setting affects both monitors in a multi-monitor system and does not take effect until the current user logs out and logs back in.

; This is not tested so likely contains bugs!!!!

SPI_SETLOGICALDPIOVERRIDE = 159 ; 0x009F
relativeIndex = 1
DllCall('user32.dll', long:'SystemParametersInfoA', long:SPI_SETLOGICALDPIOVERRIDE, long:relativeIndex, lpnull, long:1)
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

JTaylor

I can't take credit and I haven't tried it but would something like this avoid the need to logout or am I reading it wrong?



 SPI_SETLOGICALDPIOVERRIDE = 159; // 0x009F
    relativeIndex = 1;
    SPIF_UPDATEINIFILE = 0x01;
    SPIF_SENDCHANGE = 0x02;
    WM_SETTINGCHANGE = 0x001A;
    HWND_BROADCAST = 0xFFFF;
    SMTO_ABORTIFHUNG = 0x2;

    // Change the DPI setting
    result = DllCall("user32.dll", "long: SystemParametersInfoA", "long", SPI_SETLOGICALDPIOVERRIDE, "long", relativeIndex, "lpnull", 0, "long", SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);

    if (result) {
        // Broadcast the WM_SETTINGCHANGE message
        DllCall("user32.dll", "long: SendMessageTimeoutA", "long", HWND_BROADCAST, "long", WM_SETTINGCHANGE, "long", 0, "long", 0, "long", SMTO_ABORTIFHUNG, "long", 5000, "long", 0);
    } else {
        Message("Note","Failed to change DPI setting.");
    }



td

I am not sure if that would work or not because not all running processes will respond or understand how to respond to the message. I guess you would need to try it to find out.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

This is speculation but changing scaling changes the Windows low-level graphics API output. Given that Windows processes hold copies of much of the kernel in their process space, a process may need to stop and restart to reload its copy of the kernel to get the change to take effect.

Again, the above is speculative and may be worth no more than a pile of the proverbial.

 
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade