WinForms:找到最小化表单的大小而不使用FormWindowState.Normal

时间:2010-05-20 17:24:59

标签: c# .net winforms

是否有一种简单的方法来确定它在WindowState = Normal中具有的Form的大小,而不实际更改Form状态?

这是我现在所做的(C#代码):

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;
          //  ...
     }
}

这就是我希望代码看起来像:

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

事实上,Windows窗体中没有NormalStateLocationNormalStateSize属性。

5 个答案:

答案 0 :(得分:8)

我想做同样的事情并且没有人真正回答你的问题我现在正在发布我的解决方案,即使你已经满意了。也许有人需要它。

    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);
        }
    }

答案 1 :(得分:5)

从.NET 2.0开始,有一个属性RestoreBounds包含您需要的值。

答案 2 :(得分:3)

Load事件是找出表单“正常”大小的最早时刻。此时,已应用由AutoSizeMode和任何用户覆盖边框和标题大小引起的任何缩放。但是,只有在设计器中未将WindowState设置为Minimized时,该大小才有效。您必须等到表格至少在正常状态下显示一次。

另外要注意,如果您在启用Aero胖边框的情况下运行,那么您将获得的大小是假的。如果早期的操作系统运行您的程序,Vista和Win7会故意返回一个窗口大小。如果这真的很重要,您将不得不使用Editbin.exe来标记您的程序Vista兼容。

熊陷阱,尽量避免问这个问题。获得Resize事件时,您始终可以更改窗口位置或大小。


如果这只是为了记住表单的位置和大小,那么您将需要使用“设置”。使用“项目+属性”,“设置”选项卡添加它们。您不能使用自动ApplicationSettings绑定,因为您不希望在最小化或最大化时保存表单的位置和大小。看起来像这样:

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);
    }
}

答案 3 :(得分:1)

试试这个

    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;
        }
    }

答案 4 :(得分:0)

为什么在第一次加载表单时不只是节省表单的大小和位置?当然,它必须从正常开始:

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