SystemMenu
These two screenshots show the new SystemMenu item, Always On Top that was added to the System menu, in both unchecked and checked states.


Introduction
I was writing a Desktop Wallpaper changing utility in C# and I wanted to force the MainForm to remain on-top of all the other Windows when I clicked a menu item on the Form's System Menu.
I wrote this code so that I could interact with the Form's System Menu but it can be used with any other menu in your C# application.
SystemMenu is a simple wrapper class using pInvoke to manipulate menus, you can add or remove items (including separators) to an existing menu but cannot create a new menu as yet, I will be adding support for this in a future release.
Methods
These are the methods that the class supports.
// Gets a handle to the system menu of a Form and stores it in the class
public SystemMenu(Form form);
// Reset the system menu (To the default)
public static void ResetSystemMenu(Form form);
// Inserts a separator at the specified index (from 0)
public bool InsertSeparator(uint index);
// Inserts a menu item at the specified index (from 0, MF_BYPOSITION)
public bool InsertMenu(uint index, uint id, String item);
// Inserts a menu item at the specified index (flags: MF_BYPOSITION or MF_BYCOMMAND)
public bool InsertMenu(uint index, MenuFlags flags, uint id, String newItem);
// Append a separator to the end of the menu
public bool AppendSeparator();
// Appends a menu item, uses MF_STRING flag
public bool AppendMenu(uint id, String newItem);
// Check / Uncheck a menu item (MF_CHECKED | MF_UNCHECKED)
// Supports MF_BYPOSITION or MF_BYCOMMAND
public uint CheckMenuItem(uint index, MenuFlags flags);
// Deletes a menu item, can be MF_BYPOSITION or MF_BYCOMMAND
public bool RemoveMenu(uint index, uint flags);
Where these methods have a MenuFlags parameter you can use any of the following supported options which are taken from the WinUser.h header file. You can check the MSDN library for full details on these options.
public enum MenuFlags // Our menu flags (Taken from "WinUser.h")
{
MF_INSERT = 0x00000000,
MF_CHANGE = 0x00000080,
MF_APPEND = 0x00000100,
MF_DELETE = 0x00000200,
MF_REMOVE = 0x00001000,
MF_BYCOMMAND = 0x00000000,
MF_BYPOSITION = 0x00000400,
MF_SEPARATOR = 0x00000800,
MF_ENABLED = 0x00000000,
MF_GRAYED = 0x00000001,
MF_DISABLED = 0x00000002,
MF_UNCHECKED = 0x00000000,
MF_CHECKED = 0x00000008,
MF_USECHECKBITMAPS = 0x00000200,
MF_STRING = 0x00000000,
MF_BITMAP = 0x00000004,
MF_OWNERDRAW = 0x00000100,
MF_POPUP = 0x00000010,
MF_MENUBARBREAK = 0x00000020,
MF_MENUBREAK = 0x00000040,
MF_UNHILITE = 0x00000000,
MF_HILITE = 0x00000080
}
Error Handling
This class has limited error handling support, it simply returns true or false as necessary and can throw an NoSystemMenuException exception if the constructor fails to find the Form's System Menu.
Using the SystemMenu class
It is very easy to integrate SystemMenu into your own C# applications, simple follow these instructions:
Step 1 - Including the SystemMenu class
Create a new C# Windows Forms project and double click on the form so that you can edit the underlying code.
We need to add a using statement to include the darka namespace, see the following code.
using darka; // Reference the namespacStep 2 - Add supporting variables
We need to add two variables; one for the class instance, and one for the enumeration containing the Windows SDK WM_SYSCOMMAND Identifier so that we can detect when the SystemMenu has been clicked on.
using darka; // Reference our namespace
namespace SystemMenuTest
{
public partial class MainForm : Form
{
// Define some constants/variables for the SystemMenu
public enum SystemCommands
{
WM_SYSCOMMAND = 0x0112 // The WM_SYSCOMMAND id, from
}
private SystemMenu _sysMenu = null;
// ... Code removed for brevity
}
}Step 3 - Create an instance of the class
We can now create an instance of the class in the MainForm_Load() method (Double click on the Load method on the Events tab of the Form Properties) and then copy/paste the code from the following sample.

private void MainForm_Load(object sender, EventArgs e)
{
try
{
// Create an instance of the class
_sysMenu = new SystemMenu(this);
// Set up the system menu (Always on top item)
_sysMenu.AppendSeparator();
_sysMenu.AppendMenu(IDC_ALWAYS_ON_TOP, "Always On Top");
}
catch (NoSystemMenuException ex)
{
String error = "Error: GetSystemMenuW() Failed - (";
error += ex.Message;
error += ")";
MessageBox.Show(error, "TestApp");
}
}Step 4 - Override WndProc
Then we need to override the WndProc method so that we can process messages received from the system menu, as shown below (See the sample code for a fully working implementation).
namespace SystemMenuTest
{
public partial class MainForm : Form
{
//
// ... Code removed for brevity
// Override the forms virtual WndProc function
protected override void WndProc(ref Message msg)
{
// Only look at WM_SYSCOMMAND messages
if (msg.Msg == (int)SystemCommands.WM_SYSCOMMAND)
{
// Is this our new menu item ?
if (msg.WParam.ToInt32() == IDC_ALWAYS_ON_TOP)
{
SetAlwaysOnTop(); // Yes, so set the form on top of all other windows
return;
}
}
base.WndProc(ref msg); // Call the default WndProc for other messages
}
}
}
Step 5 - Write our menu handler
We are actually done adding the SystemMenu class to the project, all we need to do now is create our menu handling code SetAlwaysOnTop() to toggle between on top and normal positions.
namespace SystemMenuTest
{
public partial class MainForm : Form
{
//
// ... Code removed for brevity
// Set the main form always on top (or not)
private void SetAlwaysOnTop()
{
alwaysOnTop_ = !alwaysOnTop_;
this.TopMost = alwaysOnTop_; // Toggle the ontop state
// Check/Uncheck the menu item appropriately
sysMenu_.CheckMenuItem(Constants.IDC_ALWAYS_ON_TOP, SystemMenu.MenuFlags.MF_BYCOMMAND
| ((alwaysOnTop_) ? SystemMenu.MenuFlags.MF_CHECKED : SystemMenu.MenuFlags.MF_UNCHECKED));
}
}
}
Change History (
New,
BugFix,
Updated)
Nov 2010 (v1.1) - Improved the article and sample code.
Feb 2008 (v1.0) - Initial Public Release.