How to detect the Windows 10 scale factor using C#?

Steven Young 261 Reputation points
2021-05-20T11:28:30.35+00:00

If you are having trouble reading text, recognizing icons and navigating apps because your high-resolution display makes everything look so tiny, then you need to check out Windows 10's scaling options. Go to Settings > System > Display and you'll find an option for Scale and layout. Windows will recommend a percentage. I want to use C# to get this value for "Scale and layout", I found that it's not the old DPI value (The LogPixels located on HKEY_CURRENT_USER\Control Panel\Desktop).

Developer technologies C#
{count} votes

3 answers

Sort by: Most helpful
  1. Timon Yang-MSFT 9,606 Reputation points
    2021-05-21T06:00:01.92+00:00

    Please try the following code to get this percentage value.

            public static int GetWindowsScaling()  
            {  
                return (int)(100 * Screen.PrimaryScreen.Bounds.Width / SystemParameters.PrimaryScreenWidth);  
            }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

  2. Steven Young 261 Reputation points
    2021-09-03T01:34:18.29+00:00

    No, it return 100 if restart program.


  3. Matthias Kläy 0 Reputation points
    2023-09-01T12:42:21.9533333+00:00

    Also being late in the game, I would like to hint on two approaches that also work with WinForms. Which approach to take depends on the use case.

    Approach A: Control.PreferredSize

    Each control has a "designed" size, typically done with default scaling, i.e. 100%. Let's take a simple auto-sized label, e.g. 116 pixels wide and 13 pixels in height. Break the first time the parent's Paint event is invoked: At 125%, the label's PreferredSize reports e.g. {Width = 155 Height = 17}. Hmm... 133% rather than 125%? AutoScaleMode.Font apparently takes other things into account.

    Now let's do the same with a control that has no text, e.g. 245 pixels wide and 295 pixels in height. After InitializeComponent() , the control's constructor will still state these values. Again break the first time the parent's Paint event is invoked: At 125%, the control's PreferredSize report e.g. {Width = 342 Height = 363}. The width is limited by the parent, by the height is free to scale, 363/295 = 1.23, i.e. pretty close to the 125% settings.

    While this approach doesn't give the exact scaling value, it gives exact values how controls get scaled by WinForms.

    Approach B: Control.DeviceDpi

    According to https://learn.microsoft.com/en-us/windows/win32/learnwin32/dpi-and-device-independent-pixels, 100% scaling is 96 DPI:

    const int DefaultDpi = 96;

    Any form or control can easily calculate the current scaling:

    var scaling = (float)DeviceDpi / DefaultDpi; // = 1.25 with a 125% setting

    The default of 96 DPI should also works on Linux, e.g. https://wiki.archlinux.org/title/HiDPI.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.