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.
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:
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:
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.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.