It is currently October 9th, 2024, 3:16 pm

Win10 AppliedDPI Registry Value for Scaling (Single Monitor)

Tips and Tricks from the Rainmeter Community
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5538
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Win10 AppliedDPI Registry Value for Scaling (Single Monitor)

Post by eclectic-tech »

With the increase in HD displays, it is more common to see Win10 DPI display settings above the recommended 100% (96 Dots Per Inch).

This can have an undesirable effect on Rainmeter skins because most skins were (and are) created using 100% DPI settings.
Letting Windows "scale up" your skins is not desirable because they are usually blurry and/or distorted.

There is a way to obtain the current 'AppliedDPI' from a Win10 registry value to use to scale your skins to match an end users display.
For this to work as expected, the end user must follow the steps described here to 'Override high DPI scaling behavior' for Rainmeter.exe.. This way, Rainmeter will always display skins at 100%.

Then the author can use a variable to scale their meters and avoid the distortion introduced when letting Windows10 do the scaling.

Here is a sample skin that shows how to get the value and use it in a skin.

Code: Select all

[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
Group=#RootConfig#

; ========= Metadata ==========
[Metadata]
Name=Win10 DPI Scale Registry Value
Author=Eclectic Tech
Information=Returns the current DPI setting in Win10. This value can be used to automatically scale your skins to match the end user display settings. Rainmeter.exe compatibility Change high DPI behavior should be set to 'Override high DPI scaling by this application'. The value is stored when the skin is loaded. ** NOTE: If the DPI setting is changed, users MUST logoff and back on, to see the change in the registry value. ** 
License=Creative Commons Share-Alike NC 4
Version=1.2019.02.11

; ========= Variables ==========
[Variables]
Scaler=1.00

; ========= Measures ==========
[MeasureRegistry]
Measure=Registry
RegHKey=HKEY_CURRENT_USER
RegKey=Control Panel\Desktop\WindowMetrics
RegValue=AppliedDPI
UpdateDivider=-1

IfCondition=(#CurrentSection#>=96) && (#CurrentSection#<108)
IfTrueAction=[!SetVariable Scaler 1.00]

IfCondition2=(#CurrentSection#>=108) && (#CurrentSection#<132)
IfTrueAction2=[!SetVariable Scaler 1.25]

IfCondition3=(#CurrentSection#>=132) && (#CurrentSection#<156)
IfTrueAction3=[!SetVariable Scaler 1.50]

IfCondition4=(#CurrentSection#>=156) && (#CurrentSection#<180)
IfTrueAction4=[!SetVariable Scaler 1.75]

IfCondition5=(#CurrentSection#>=180) && (#CurrentSection#<204)
IfTrueAction5=[!SetVariable Scaler 2.00]

IfCondition6=(#CurrentSection#>=204) && (#CurrentSection#<228)
IfTrueAction6=[!SetVariable Scaler 2.25]

; These 6 conditiions handle 100% ~ 225%, more IfConditions can be added if higher values are needed

; ========= Meters ==========

[MeterString]
Meter=String
FontSize=(12*#Scaler#)
FontColor=255,255,255
Text=Win10 Scale: #Scaler# ([MeasureRegistry] DotsPerInch)
DynamicVariables=1
[MeasureRegistry] will return the actual dots per inch being used in the current session. That value can be used in IfCondition statements to set the value of a 'Scaler' variable in your skin.

Be aware that if the end user changes his DPI, the registry value will not change until they logoff and back on.
Refreshing Rainmeter, or the skins, will not update the value.

Converting an existing skin can be time-consuming because the 'Scaler' multiplier must be added to almost every X, Y, W, and H value of every meter, and to TransformationMatrix formulas for meters that use W and H to define other values (instead of meter size) such as Roundline meters, Rotators, etc.

Once you know the DPI setting, you can adjust your skins for the best possible end user experience. :rosegift:
User avatar
jsmorley
Developer
Posts: 22847
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Win10 AppliedDPI Registry Value for AutoScaling

Post by jsmorley »

The only rub I see with this is that if you have multiple monitors, you can set DPI scaling on them individually. I suspect you can access the individual settings in the Registry somehow, but I'm not sure where.
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5538
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Win10 AppliedDPI Registry Value for AutoScaling

Post by eclectic-tech »

jsmorley wrote: February 12th, 2019, 12:29 am The only rub I see with this is that if you have multiple monitors, you can set DPI scaling on them individually. I suspect you can access the individual settings in the Registry somehow, but I'm not sure where.
Well then, this is not a "cure-all" I guess... Haven't looked to see if multiple monitor settings are exposed in the registry (came across this one while trying several other "plugins" that locked up Rainmeter :o ).

I am going to change the Title and remove the 'automatic' phrase, since this gives you a value, but authors still need to incorporate it in their skins.
User avatar
jsmorley
Developer
Posts: 22847
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Win10 AppliedDPI Registry Value for Scaling (Single Monitor)

Post by jsmorley »

Sorry to be the skunk at a garden party...
User avatar
eclectic-tech
Rainmeter Sage
Posts: 5538
Joined: April 12th, 2012, 9:40 pm
Location: Cedar Point, Ohio, USA

Re: Win10 AppliedDPI Registry Value for Scaling (Single Monitor)

Post by eclectic-tech »

jsmorley wrote: February 12th, 2019, 12:43 am Sorry to be the skunk at a garden party...
No problem! Stink it up as much as you want! :lol:

This helped me with a skin that broke when high DPI was set.
So hopefully it may helps someone else (aside from the "stinky" multi-monitor issue!) ;-)
User avatar
SilverAzide
Rainmeter Sage
Posts: 2744
Joined: March 23rd, 2015, 5:26 pm

Re: Win10 AppliedDPI Registry Value for AutoScaling

Post by SilverAzide »

jsmorley wrote: February 12th, 2019, 12:29 am The only rub I see with this is that if you have multiple monitors, you can set DPI scaling on them individually. I suspect you can access the individual settings in the Registry somehow, but I'm not sure where.
There are Windows APIs GetDpiForMonitor or -- even better -- GetDpiForWindow that might work, or by using GetDeviceCaps for the desktop and dividing the physical screen height by the logical screen height. If so, this could be a nice enhancement to Rainmeter to expose the DPI as a built-in variable. I suppose this value would change if you dragged a skin between scaled and unscaled monitors...
Gadgets Wiki GitHub More Gadgets...