none
On the display settings page Change the size of text, applications, and other items. How do I find the selected value with code? RRS feed

  • Question

  • Hi

    On the display settings page

    Change the size of text, applications, and other items. How do I find the selected value with code?

    Friday, December 6, 2019 1:37 AM

All replies

  • Hi HakanÇtn,
    You can use GetDeviceCaps function to retrieves device-specific information for the specified device.
    Here is a code example you can refer to.
    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
    public enum DeviceCap
    {
        VERTRES = 10,
        DESKTOPVERTRES = 117
    }
    private float getScalingFactor()
    {
        Graphics g = Graphics.FromHwnd(IntPtr.Zero);
        IntPtr desktop = g.GetHdc();
        int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
        int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
    
        float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
        Console.WriteLine(ScreenScalingFactor);
        return ScreenScalingFactor; // 1.25 = 125%
    }
    private void button1_Click(object sender, EventArgs e)
    {
        getScalingFactor();
    }
    Best Rgards,
    Daniel Zhang

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, December 6, 2019 6:37 AM
  • GetDpiForWindow

    with dpiAwareness = PerMonitor in Manifest

    Friday, December 6, 2019 8:24 AM
  • Hi HakanÇtn,
    You can use GetDeviceCaps function to retrieves device-specific information for the specified device.
    Here is a code example you can refer to.
    [DllImport("gdi32.dll")]
    static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
    public enum DeviceCap
    {
        VERTRES = 10,
        DESKTOPVERTRES = 117
    }
    private float getScalingFactor()
    {
        Graphics g = Graphics.FromHwnd(IntPtr.Zero);
        IntPtr desktop = g.GetHdc();
        int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
        int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
    
        float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
        Console.WriteLine(ScreenScalingFactor);
        return ScreenScalingFactor; // 1.25 = 125%
    }
    private void button1_Click(object sender, EventArgs e)
    {
        getScalingFactor();
    }
    Best Rgards,
    Daniel Zhang

    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Daniel et al,

    I get ScreenScalingFactor = 1 from the example when the scaling is set on 125% in the control panel?

    Is that what you get? Both log and physical size is the same.

    Friday, December 6, 2019 8:48 PM
  • GetDeviceCaps is not a correct method

    GetDpiForWindow works on my Windows 10 OS, with the right manifest or SetProcessDpiAwareness in C++ =>

    // 100% : 96  
    // 125% : 120  
    // 150% : 144  
    // 175% : 168



    • Edited by Castorix31 Friday, December 6, 2019 9:05 PM
    Friday, December 6, 2019 9:04 PM
  • Castor,

    That's new I have not tried it. I have to go in the other room for Win 10.  :)

    Yeah but what about win 7? And that is dpi, what about images and controls? And oh yes is it not .net 4.7 only?

    Seems we have different scaling with different objects?

    Here is a GetDevCaps example and for the last factor I multiply the scalefactor by the dpi to get the true dpi.

    However images and controls are different? And then yes the app has dpi aware settings etc. Plus the form autoscale etc.

    What a nightmare. I am not claiming to understand.

    Here are bitmap captures of each (win 7). See how the text size, controls (ie close, max, min), Picturebox, form, all change differently with the three scalings 100, 125, 150.

    I think my project is not set on any dpiaware.

    Edit: Here is the example I made to practice with. The example makes the controls. To make the example just copy and paste the code into an empty form. Change the form name as required .

    There is a label (blue) and picturebox (apple) control on the form. The ruler is drawn gdi+.

    You can see that the text is changing size with the dpi 100, 120, 144. The form control box is changing with dpi.

    However, the gdi line drawing, form, label and picture box with image controls only change size with the 150 percent control panel scaling.

    .

        public partial class Form5 : Form
        {
            [System.Runtime.InteropServices.DllImport("gdi32.dll")]
            static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
    
            public Form5()
            {
                InitializeComponent();
            }
    
            private void Form5_Load(object sender, EventArgs e)
            {
                ClientSize = new Size(300, 300);
                Location = new Point(20, 20);
                Text = "Screen Resolution";
    
                var Label1 = new Label
                {
                    Name = "label1",
                    BackColor = Color.AliceBlue,
                    Location=new Point(20,60),
                    Size = new Size(260,220),
                    Font = new Font ("Arial",10,FontStyle.Bold)
                };
                this.Controls.Add(Label1);
    
                var PictureBox1 = new PictureBox
                {
                    Name = "pictureBox1",
                    BackColor = Color.White,
                    Location = new Point(180, 180),
                    Size = new Size(100, 100),
                    BackgroundImage = Image.FromFile(@"c:\bitmaps\apple100.png"),
                    BackgroundImageLayout = ImageLayout.None,
                };
                
                this.Controls.Add(PictureBox1);
                PictureBox1.BringToFront();
    
                Paint += new PaintEventHandler(this.Form2_Paint);
    
                Label1.Text = getScreenData();
    
            }
    
            private void Form2_Paint(object sender, PaintEventArgs e)
            {
    
                e.Graphics.Clear(Color.White);
                e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
    
    
                Font f = new Font("consolas", 10, FontStyle.Bold);
    
                // draw ruler
                e.Graphics.FillRectangle(Brushes.Maroon, 0, 10, ClientSize.Width, 40);
    
                int xCount = 0;
                for (float x = 0; x <= ClientSize.Width; x += 96)
                {
                    e.Graphics.DrawLine(new Pen(Color.White, 1), x, 10, x, 50);
                    if (x > 0)
                    {
                        e.Graphics.DrawString(x.ToString(), f, Brushes.AntiqueWhite, x, 12);
                        e.Graphics.DrawString(xCount.ToString(), f, Brushes.AntiqueWhite, x, 32);
                    }
    
                    xCount += 1;
                }
    
                e.Graphics.DrawString(" pixels", f, Brushes.AntiqueWhite, 10, 12);
                e.Graphics.DrawString(" inches", f, Brushes.AntiqueWhite, 10, 32);
    
                f.Dispose();
            }
    
            private string getScreenData()
            {
                Graphics g = Graphics.FromHwnd(IntPtr.Zero);
                IntPtr desktop = g.GetHdc();
                int LogicalScreenWidth = GetDeviceCaps(desktop, (int)DeviceCap.HORZRES);
                int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
    
                int PhysicalScreenWidth = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPHORZRES);
                int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);
    
                float ScreenScalingFactor = (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
    
                int LogicalDPIX = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSX);
                int LogicalDPIY = GetDeviceCaps(desktop, (int)DeviceCap.LOGPIXELSY);
    
                string Str =
                    "Log Pixels: " + LogicalScreenWidth.ToString() + " x " +
                                     LogicalScreenHeight.ToString() + "\n" +
    
                    "Pys Pixels: " + PhysicalScreenWidth.ToString() + " x " +
                                     PhysicalScreenHeight.ToString() + "\n\n" +
    
                    "Size Factor: " + ScreenScalingFactor.ToString() + "\n\n" +
    
                    "DPI: " + LogicalDPIX.ToString() + " x " +
                              LogicalDPIY.ToString() + "\r" +
    
                    "Scale DPI: " + (ScreenScalingFactor * LogicalDPIX).ToString() + "\n\n";
    
                return Str;
    
            }
    
            public enum DeviceCap
            {
                HORZRES = 8,
                VERTRES = 10,
                LOGPIXELSX = 88,
                LOGPIXELSY = 90,
                SCALINGFACTORX = 114,
                SCALINGFACTORY = 115,
                DESKTOPVERTRES = 117,
                DESKTOPHORZRES = 118,
            }
        }



    • Edited by tommytwotrain Saturday, December 7, 2019 10:00 AM add graphics etc
    Friday, December 6, 2019 10:01 PM
  • PS What is confusing is how the various dpi aware settings affect what we see now in various OS versions etc.

    Isnt there like 3 ways now from over the years to set dpi aware? and what should it be for latest win10 etc. For win10 you need this and then that etc...

    Do you understand that part Castor I think you mentioned it earlier (and Daniel and everone et al)? I would like to add it to the example somehow.

    Did you try my example and do you see the same thing?

    My project is the default vs2015 on win7 but I dont think that changes anything from the newest? .net 4.5

    PS then there is the core 3.2 I am not sure how that comes to play...



    Saturday, December 7, 2019 10:32 AM