Nick
Nick

Reputation: 3965

Windows display settings is causing Screen.PrimaryScreen.Bounds.Width to be incorrect

We have made a terms of use application that fills the user's entire screen, and centres the text in the middle of the screen.

We have achieved these by setting the Location to Screen.PrimaryScreen.Bounds.X + 10 and then the width to Width = Screen.PrimaryScreen.Bounds.Width - 10, - this gives effectively 10px padding and otherwise perfectly central text.

The problem however, is when users change the 'Make it easier to read what's on your screen' option to 125%, the Bounds.Width value is incorrect, and the text goes way off the screen.

Make it easier to read what's on your screen, set to 125%

Interestingly if you set it to 'Larger - 150%' it calculates the screen width just fine.

I've tried using Screen.PrimaryScreen.WorkingArea.Width too, but that just gives the same (incorrect) result.

Is there anyway of resolving this please? Thank you

(edit) Here is the full code which generates the element:

protected override void OnLoad(System.EventArgs e) {
    this._webBrowser = new WebBrowser {
      IsWebBrowserContextMenuEnabled = false,
      AllowWebBrowserDrop = false,
      Location = new Point(Screen.PrimaryScreen.Bounds.X + 10, Screen.PrimaryScreen.Bounds.Y + 150),
      Width = Screen.PrimaryScreen.Bounds.Width - 20,
      ScrollBarsEnabled = true,
      DocumentText = "<html><body><div>" + agreement.Terms + "</div></body></html>"
    };
}

Upvotes: 2

Views: 2363

Answers (1)

Hans Passant
Hans Passant

Reputation: 941455

Sight unseen (always post a code snippet), this happened because you put the code in the wrong place. You are setting the size in the constructor of your Form class. Then, since the form was originally designed at 96 DPI, your form gets auto-scaled to accommodate the larger DPI setting. Which grows the form by 125%, now making it too big.

You must set the size after the form is rescaled. The Load event handler is the best opportunity, in fact one of the few reasons to actually need Load. At that point, the scaling is already applied but the window not yet visible. Therefore the best place to override Size and Location properties. Fix:

    protected override void OnLoad(EventArgs e) {
        var scr = Screen.FromPoint(this.Location);
        this.Bounds = new Rectangle(
            scr.WorkingArea.Left + 10, scr.WorkingArea.Top,
            scr.WorkingArea.Width - 20, scr.WorkingArea.Bottom);
        base.OnLoad(e);
    }

After edit, you should not use screen coordinates to set the control's Location and Size property. A child control's location is relative from it's Parent's client area and must fit inside it. Fix:

this._webBrowser = new WebBrowser {
    Location = new Point(10, 10),
    Width = this.ClientSize.Width - 20,
    Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Top,
    // etc...
};

Setting the Anchor ensures it resizes along with the parent, probably what you want. This code belongs in the constructor, not OnLoad() since now you do want the browser to get rescaled along with the form. If you had used the designer then you'd automatically would have gotten the correct code.

Upvotes: 3

Related Questions