Michael Würthner
Michael Würthner

Reputation: 353

Prevent MaxSized C# WinForm from moving when being maximized

I have a WinForm Form that has a constrained MaxSize. If I press maximize button, this window pops to position 0,0 (the upper left corner), with the correct MaxSize. Is there a way to prevent the form from moving?

I can set a new position after the form was being moved (by OS), but the user can see the form popping around on the screen, which is not very neat. (I changed the FormName to post the code here). SuspendLayout does not help here, and I do not necessarily want to disable the maximize button.

void frmWinForm_SizeChanged(object sender, EventArgs e)
{
    if (WindowState == FormWindowState.Maximized)
    {
        var x = ... // some calculated or original x position
        var y = ... // some calculated or original y position
        WindowState = FormWindowState.Normal;
        SetBounds(x, y, MaxSize.X, MaxSize.Y);
    }
}

Upvotes: 1

Views: 536

Answers (1)

Norman
Norman

Reputation: 3479

Override the WndProc function. Check for the maximize event. Set your preferred max size manually and return from the function. That way you are overriding the predefined maximize behaviour:

protected override void WndProc(ref Message m)
{
    if (m.Msg == 0x0112) // WM_SYSCOMMAND
    {
        if (m.WParam == new IntPtr(0xF030)) // Maximize event
        {
            Size = MaximumSize; //Set size manually and return
            return;
        }
    }
    base.WndProc(ref m);
}

This will prevent the maximize button from changing into a normalize button. Using the following code won't prevent the button from changing:

struct MinMaxInfo
{
    public Point ptReserved;
    public Point ptMaxSize;
    public Point ptMaxPosition;
    public Point ptMinTrackSize;
    public Point ptMaxTrackSize;
}

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m); //do that first: "'Who is the boss' applies. You'd typically want to be the one that has the last say in this case."
    if (m.Msg == 0x0024) //WM_GETMINMAXINFO
    {
        MinMaxInfo minMaxInfo = (MinMaxInfo)m.GetLParam(typeof(MinMaxInfo));
        minMaxInfo.ptMaxSize.X = MaximumSize.Width; //Set size manually
        minMaxInfo.ptMaxSize.Y = MaximumSize.Height;
        minMaxInfo.ptMaxPosition.X = Location.X; //Stay at current position
        minMaxInfo.ptMaxPosition.Y = Location.Y;
        Marshal.StructureToPtr(minMaxInfo, m.LParam, true);
    }
}

Upvotes: 3

Related Questions