WinForms: поиск размера свернутой формы без перехода к FormWindowState.Normal - PullRequest
5 голосов
/ 20 мая 2010

Есть ли простой способ определить размер формы, который он имеет в WindowState = Normal, без фактического изменения состояния формы?

Вот что я делаю сейчас (код 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 Forms отсутствуют свойства NormalStateLocation или NormalStateSize.

Ответы [ 5 ]

8 голосов
/ 29 ноября 2010

Я хотел сделать то же самое, и поскольку никто не ответил на ваш вопрос, я публикую свое решение сейчас, даже если вы уже удовлетворены. Может, кому-нибудь когда-нибудь понадобится.

    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);
        }
    }
5 голосов
/ 27 мая 2013

Начиная с .NET 2.0, существует свойство RestoreBounds , которое содержит необходимые значения.

3 голосов
/ 20 мая 2010

Событие Load - это самый ранний из возможных моментов, чтобы узнать, каким будет «нормальный» размер формы. В этот момент было применено любое масштабирование, вызванное AutoSizeMode, и любые пользовательские переопределения для размеров границ и заголовков. Однако этот размер будет действительным только в том случае, если в конструкторе WindowState не установлено значение Minimized. Вам придется подождать, пока форма хотя бы один раз не отобразится в нормальном состоянии.

Также помните, что размер, который вы получите, будет подделан, если вы запускаете с включенными рамками Aero fat. Vista и Win7 преднамеренно возвращают размер окна, о котором сообщалось бы, если ваша программа работала в более ранних операционных системах. Если это действительно имеет значение, вам придется использовать Editbin.exe, чтобы пометить вашу программу как совместимую с Vista.

Медведь там ловушек, постарайтесь не задавать вопрос. Вы всегда можете изменить расположение или размер окна при получении события Resize.


Если это только для того, чтобы запомнить местоположение и размер формы, вам нужно использовать Настройки. Используйте Project + Properties, вкладку Settings, чтобы добавить их. Вы не можете использовать автоматическую привязку 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);
    }
}
1 голос
/ 20 мая 2010

попробуйте

    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;
        }
    }
0 голосов
/ 07 декабря 2018

Почему бы просто не сохранить размер и расположение формы при первой загрузке формы? Конечно, все должно начаться нормально:

form.Shown += (s, e1) =>
{
    // Save off the size and location
    form.SaveSizeAndLocation();
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...