Event when a window gets maximized/un-maximized

C#Winforms

C# Problem Overview


Is there an event that is fired when you maximize a Form or un-maximize it?

Before you say Resize or SizeChanged: Those get only fired if the Size actually changes. If your window happens to be equal in size to the maximized window, they do not fire. Location looks like the next best bet, but that again feels like gambling on a coincidence.

C# Solutions


Solution 1 - C#

Suprising that no one mentioned the inbuilt .NET method.

This way you don't need to override the Window Message Processing handler.

It even captures maximize/restore events caused by double-clicking the window titlebar, which the WndProc method does not.

Copy this in and link it to the "Resize" event handler on the form.

	FormWindowState LastWindowState = FormWindowState.Minimized;
	private void Form1_Resize(object sender, EventArgs e) {

		// When window state changes
		if (WindowState != LastWindowState) {
			LastWindowState = WindowState;


			if (WindowState == FormWindowState.Maximized) {

				// Maximized!
			}
			if (WindowState == FormWindowState.Normal) {

				// Restored!
			}
		}

	}

Solution 2 - C#

You can do this by overriding WndProc:

protected override void WndProc( ref Message m )
{
    if( m.Msg == 0x0112 ) // WM_SYSCOMMAND
    {
        // Check your window state here
        if (m.WParam == new IntPtr( 0xF030 ) ) // Maximize event - SC_MAXIMIZE from Winuser.h
        {
              // THe window is being maximized
        }
    }
    base.WndProc(ref m);
}

This should handle the event on any window. SC_RESTORE is 0xF120, and SC_MINIMIZE is 0XF020, if you need those constants, too.

Solution 3 - C#

Another little addition in order to check for the restore to the original dimension and position after the maximization:

protected override void WndProc(ref Message m)
{
	base.WndProc(ref m);

	// WM_SYSCOMMAND
	if (m.Msg == 0x0112)
	{
		if (m.WParam == new IntPtr(0xF030) // Maximize event - SC_MAXIMIZE from Winuser.h
			|| m.WParam == new IntPtr(0xF120)) // Restore event - SC_RESTORE from Winuser.h
		{
			UpdateYourUI();
		}
	}
}

Hope this help.

Solution 4 - C#

I believe the code is even simpler than that. You don't need to save the lastState because the WindowState is checked anytime when the event is fired.

 private void MainForm_Resize(object sender, EventArgs e)
    {
        if (WindowState == FormWindowState.Maximized)
        {
            spContainer.SplitterDistance = 1000;
        }
        if (WindowState == FormWindowState.Normal)
            spContainer.SplitterDistance = 500;
    }

Solution 5 - C#

I had the same problem, and I could solve it without overriding. Because I have a PictureBox in dock mode "Fill" I could use it's SizeChanged event, which fired also on maximizing the window.

Solution 6 - C#

I hope this part of code will be useful.

            if (m.Msg == User32.WM_WINDOWPOSCHANGING && IsHandleCreated)
            {
                User32.WINDOWPLACEMENT wp = new User32.WINDOWPLACEMENT();
                wp.length = Marshal.SizeOf(typeof(User32.WINDOWPLACEMENT));
                User32.GetWindowPlacement(Handle, ref wp);

                switch (wp.showCmd)
                {
                    case User32.SW_RESTORE:
                    case User32.SW_NORMAL:
                    case User32.SW_SHOW:
                    case User32.SW_SHOWNA:
                    case User32.SW_SHOWNOACTIVATE:
                        _windState = FormWindowState.Normal;
                        if (wp.showCmd == User32.SW_RESTORE)
                            Update();
                        break;

                    case User32.SW_SHOWMAXIMIZED:
                        _windState = FormWindowState.Maximized;
                        SetMaximumSize();

                        break;

                    case User32.SW_SHOWMINIMIZED:
                    case User32.SW_MINIMIZE:
                    case User32.SW_SHOWMINNOACTIVE:
                        _windState = FormWindowState.Minimized;
                        break;
                }
            }

    private void SetMaximumSize()
    {
        Screen screen = Screen.FromControl(this);
        if (screen != null && !screen.WorkingArea.IsEmpty)
        {
            int sizeDiff = this.Size.Width - this.ClientSize.Width;
            var maxSize = new Size(screen.WorkingArea.Width + sizeDiff, screen.WorkingArea.Height + sizeDiff);
            this.MaximumSize = maxSize;
        }
    }

    #region Window State

    public const int SW_NORMAL = 1,
        SW_SHOWMINIMIZED = 2,
        SW_SHOWMAXIMIZED = 3,
        SW_SHOWNOACTIVATE = 4,
        SW_SHOW = 5,
        SW_MINIMIZE = 6,
        SW_SHOWMINNOACTIVE = 7,
        SW_SHOWNA = 8,
        SW_RESTORE = 9;

    #endregion Window State

Solution 7 - C#

If there's no obvious event to listen for, you're probably going to need to hook into the Windows API and catch the appropriate message (Google turns up that you'll want to intercept the WM_SYSCOMMAND message: http://www.codeguru.com/forum/archive/index.php/t-234554.html).

Solution 8 - C#

I'm a newbie here so comments not allowed, but this IS a comment to the clean answer by GeoTarget:

The first line OUGHT to be slightly changed to nullable, to catch if the form is started Minimized:

FormWindowState? LastWindowState = null;

And a banal suggestion: Move the assignment of LastWindowState to after the "if"s, so the user can easily check not only what you go to, but also what it came from:

FormWindowState? LastWindowState = null;
private void Form1_Resize(object sender, EventArgs e) {
    // When window state changes
    if (WindowState != LastWindowState) {
        if (WindowState == FormWindowState.Maximized) {
            // Maximized!
        }
        if (WindowState == FormWindowState.Normal) {
            // Restored!
        }
        LastWindowState = WindowState;
    }
}

Solution 9 - C#

A complete solution with maximize, minimize, restore and correct remove of the lower bits which are used for internal purposes only.

protected override void WndProc(ref Message m)
{
	const int WM_SYSCOMMAND = 0x0112;
	const int SC_MAXIMIZE = 0xF030;
	const int SC_MINIMIZE = 0xF020;
	const int SC_RESTORE = 0xF120;

    // Call beofre - don't use when "call after" is used
	// dependig on the needs may be called before, after or even never (see below)
	// base.WndProc(ref m);

	if (m.Msg == WM_SYSCOMMAND)
	{
		/// <see cref="https://docs.microsoft.com/en-us/windows/win32/menurc/wm-syscommand"/>
		/// Quote:
		/// In WM_SYSCOMMAND messages, the four low - order bits of the wParam parameter 
		/// are used internally by the system.To obtain the correct result when testing 
		/// the value of wParam, an application must combine the value 0xFFF0 with the 
		/// wParam value by using the bitwise AND operator.
		int wParam = (m.WParam.ToInt32() & 0xFFF0);

		Debug.WriteLine($"Received param: { Convert.ToString(wParam, 16) } ");

		if (wParam == SC_MAXIMIZE)
		{
			
		}

		if (wParam == SC_MINIMIZE)
		{
			
		}

		if (wParam == SC_RESTORE)
		{
			
		}
	}

    // Call after - don't use when "call before" is used
	base.WndProc(ref m);
}

Solution 10 - C#

' Great tip. So if it helps to VisualBasic In Code
Private Const WM_SYSCOMMAND As Integer = &H112
Private Const SC_MAXIMIZE As Integer = &HF030
' # WndProcess 루프함수
Protected Overrides Sub WndProc(ByRef m As Message)
    If m.Msg.Equals(WM_SYSCOMMAND) Then
        If (m.WParam.ToInt32.Equals(SC_MAXIMIZE)) Then
            Me.p_FullScreen()
            Return
        End If
    End If

    MyBase.WndProc(m)
End Sub

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichael StumView Question on Stackoverflow
Solution 1 - C#Robin RodricksView Answer on Stackoverflow
Solution 2 - C#Reed CopseyView Answer on Stackoverflow
Solution 3 - C#Lorenzo MelatoView Answer on Stackoverflow
Solution 4 - C#Gabriel Marius PopescuView Answer on Stackoverflow
Solution 5 - C#816-8055View Answer on Stackoverflow
Solution 6 - C#TrackView Answer on Stackoverflow
Solution 7 - C#MattView Answer on Stackoverflow
Solution 8 - C#Eske RahnView Answer on Stackoverflow
Solution 9 - C#marsh-wiggleView Answer on Stackoverflow
Solution 10 - C#HobisView Answer on Stackoverflow