Click here to Skip to main content
15,893,668 members
Articles / Programming Languages / C#
Article

Creating a Form, that can only be maximized and minimized

Rate me:
Please Sign up or sign in to vote.
2.27/5 (9 votes)
10 Feb 20062 min read 31.6K   10   3
This article shows, how to create a Form, that can only be maximized and minimized

Introduction

Have you ever tried to create a form in .NET, that can only be maximized and minimized? Using the standard options available this is quite a cumbersome task. But there is a simple way to disable the Normal window state using the windows message loop. This article will show you, how simple it actually is.

Overriding the form's WndProc method

When a window is maximized, minimized, or restored to its original size and location, the windows message loop send the appropriate commands to the form. The .NET Form object usually takes care of all these messages for you. In this case, we want to override the standard handling to ignore the restore command. This is done by overriding the Form's WndProc method.

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

You should always(!) leave in the call to the base implementation for all messages, you are not going to handle yourself. Now we must check the message, if it is of the type, we want to handle. The type can be found in the Msg property of the Message parameter. When the window is maximized, minimized or restored, we will receive a WM_SYSCOMMAND message. Using the WParam parameter, we can determine, whether it is a restore message. We must check for the value SC_RESTORE, but be careful: the last 4 bits are used internally, so you must mask the parameter with 0xFFF0 when comparing. Also, you must cast the IntPtr to int to be able to compare it at all.

When we receive a restore message, we can simple do nothing at all and set result to the appropriate value, in this case 0. This leaves us with the following implementation:

C#
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_SYSCOMMAND)
    {
        if (((int)m.WParam & 0xFFF0) == SC_RESTORE)
        {
            m.Result = new IntPtr(0);
            return;
        }
    }
    base.WndProc(ref m);
}

This is basically it, if it weren't for the minimized state. When you reopen a minimized window, it is also "restored". Since we ignore this message, we will never be able to see our window again. Therefore we must extend our method with a check of the current WindowState. If the state is minimized, or better yet not maximized, we should maximize our window instead of restoring it.This leads us to our final implementation:

C#
protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_SYSCOMMAND)
    {
        if (((int)m.WParam & 0xFFF0) == SC_RESTORE)
        {
            if (this.WindowState != FormWindowState.Maximized)
            {
                this.WindowState = FormWindowState.Maximized;
            }
            m.Result = new IntPtr(0);
            return;
        }
    }
    base.WndProc(ref m);
}

The two Windows API constants used in this method (WM_SYSCOMMAND = 0x0112, SC_RESTORE = 0xF120) can be found in the file WinUser.h of the Platform SDK.

Conclusion

When you have understood the windows message loop, modifying a form's default behavior can be quite easy. Once in a while, it can be useful to have a look at what's going on under the hood of the .NET framework, to be able to create such simple, yet useful code.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Germany Germany
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralThanks !! Pin
CJ van Niekerk18-Mar-06 10:11
professionalCJ van Niekerk18-Mar-06 10:11 
I required a form where the user would be unable to move or size the form.

With a simple change to your example I managed to get this going!!

using System.Runtime.InteropServices;


// Handle Resize Event of Window
private static int WM_SYSCOMMAND = 0x0112;
private static int SC_RESTORE = 0xF120;

protected override void WndProc(ref Message m)
{
if (m.Msg == WM_SYSCOMMAND)
{
if (((int)m.WParam & 0xFFF0) == SC_RESTORE)
{
if (this.WindowState != FormWindowState.Maximized)
{
this.WindowState = FormWindowState.Maximized;
}
m.Result = new IntPtr(0);
return;
}
}
base.WndProc(ref m);

if (m.Msg == 0x0046)
{ // WM_WINDOWPOSCHANGING
_WINDOWPOS pos = new _WINDOWPOS();
Marshal.PtrToStructure(m.LParam, pos);
pos.flags |= 0x2; // SWP_NOSIZE
Marshal.StructureToPtr(pos, m.LParam, false);

}
}

[StructLayout(LayoutKind.Sequential)]
public class _WINDOWPOS
{
public IntPtr hwnd;
public IntPtr hwndInsertAfter;
public int x;
public int y;
public int cx;
public int cy;
public uint flags;
}
GeneralA litle question... Pin
Stanciu Vlad10-Feb-06 10:28
Stanciu Vlad10-Feb-06 10:28 
GeneralRe: A litle question... Pin
Christoph Herold10-Feb-06 10:53
Christoph Herold10-Feb-06 10:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.