开发者

WinForms: finding the size of a minimized form without going to FormWindowState.Normal

开发者 https://www.devze.com 2022-12-30 20:40 出处:网络
Is there an easy way to determine the size of a Form it does have in WindowState=Normal, without actually changing the Form state?

Is there an easy way to determine the size of a Form it does have in WindowState=Normal, without actually changing the Form state?

Here is what I do now (C# code):

public class MyForm: Form
{
     public void MyMethod()
     {
          // ...
          FormWindowState oldState = this.WindowState;
          this.WindowState = FormWindowState.Normal;

          Point windowLocation = this.Location;
          Size windowSize = this.Size;

          this.WindowState = oldState;
          //  ...
     }
}

This is what I would like the code to loo开发者_StackOverflow中文版k like:

public class MyForm: Form
{
     public void MyMethod()
     {
          // no state change here
          Point windowLocation = this.NormalStateLocation;
          Size windowSize = this.NormalStateSize;
     }
}

In fact there are no NormalStateLocation or NormalStateSize properties in Windows Forms.


Since .NET 2.0, there is a property RestoreBounds that contains values you need.


I wanted to do the exact same thing and as nobody actually answered your question I'm posting my solution now even though you were already satisfied. Maybe somebody needs it sometime.

    class NativeMethods
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        [return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
        static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

        /// <summary>
        /// See MSDN RECT Structure http://msdn.microsoft.com/en-us/library/dd162897(v=VS.85).aspx
        /// </summary>
        private struct RECT
        {
            public int left;
            public int top;
            public int right;
            public int bottom;
        } 

        /// <summary>
        /// See MSDN WINDOWPLACEMENT Structure http://msdn.microsoft.com/en-us/library/ms632611(v=VS.85).aspx
        /// </summary>
        private struct WINDOWPLACEMENT
        {
            public int length;
            public int flags;
            public int showCmd;
            public Point ptMinPosition;
            public Point ptMaxPosition;
            public RECT rcNormalPosition;
        }

        /// <summary>
        /// Gets the window placement of the specified window in Normal state.
        /// </summary>
        /// <param name="handle">The handle.</param>
        /// <returns></returns>
        public static Rectangle GetPlacement(IntPtr handle)
        {
            WINDOWPLACEMENT placement = new WINDOWPLACEMENT();
            placement.length = System.Runtime.InteropServices.Marshal.SizeOf(placement);
            GetWindowPlacement(handle, ref placement);
            var rect = placement.rcNormalPosition;
            return new Rectangle(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
        }
    }


The Load event is the earliest possible moment to find out what the "normal" size of the form will be. At that point, any scaling induced by AutoSizeMode and any user overrides to border and caption sizes have been applied. However, that size will only be valid if the WindowState is not set to Minimized in the designer. You'll have to wait until the form is at least shown once in the Normal state.

Also beware that the size you'll get is faked if you run with Aero fat borders enabled. Vista and Win7 intentionally return a window size that would be reported if earlier operating systems ran your program. If this really matters, you'll have to use Editbin.exe to mark your program Vista compatible.

Bear traps out there, try to avoid having to ask the question. You can always change the window location or size when you get the Resize event.


If this is only to memorize the form location and size then you'll want to use Settings. Use Project + Properties, Settings tab to add them. You cannot use the automatic ApplicationSettings binding because you don't want to save the location and size of the form when it is minimized or maximized. Make it look like this:

public partial class Form1 : Form {
    public Form1() {
        InitializeComponent();
    }
    protected override void OnLoad(EventArgs e) {
        if (Properties.Settings.Default.Form1Size.Width > 0) {  // Valid?
            this.Size = Properties.Settings.Default.Form1Size;
            this.Location = Properties.Settings.Default.Form1Location;
        }
        base.OnLoad(e);
    }
    protected override void OnLocationChanged(EventArgs e) {
        if (this.WindowState == FormWindowState.Normal) 
            Properties.Settings.Default.Form1Location = this.Location;
        base.OnLocationChanged(e);
    }
    protected override void OnResize(EventArgs e) {
        if (this.WindowState == FormWindowState.Normal)
            Properties.Settings.Default.Form1Size = this.Size;
        base.OnResize(e);
    }
    protected override void OnFormClosed(FormClosedEventArgs e) {
        Properties.Settings.Default.Save();
        base.OnFormClosed(e);
    }
}


try this

    private Size _normalSize;
    private Point _location;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        this.LocationChanged += new EventHandler(Form1_LocationChanged);
        this.SizeChanged += new EventHandler(Form1_SizeChanged);
    }

    void Form1_SizeChanged(object sender, EventArgs e)
    {
        if (this.WindowState == FormWindowState.Normal)
        {
            this._normalSize = this.Size;
        }
    }

    void Form1_LocationChanged(object sender, EventArgs e)
    {
        if (this.WindowState == FormWindowState.Normal)
        {
            this._location = this.Location;
        }
    }


Why not just save off the size and location of the form when the form is first loaded? Of course, it would have to start out normal:

form.Shown += (s, e1) =>
{
    // Save off the size and location
    form.SaveSizeAndLocation();
};
0

精彩评论

暂无评论...
验证码 换一张
取 消