Click here to Skip to main content
Click here to Skip to main content

Iconized MenuItem

By , 28 Nov 2005
 

Sample Image - wpm_ss.gif

Introduction

This is a simple application and was written only as an example for using the iconized menu items written in C#. The main thing this app can do is restart a service or process if it was stopped or killed. Also it can show some information about a process or service and can act with it - kill a process, start a new process or start/stop/pause/resume/restart a Windows service if possible.

Iconized Menu Items

There are only two methods to override to implement an iconized menu item: OnDrawItem and OnMeasureItem. Here is how to do it:

protected override void OnDrawItem(DrawItemEventArgs e)
{
    try
    {
        e.Graphics.FillRectangle(sbBackground, e.Bounds.X, 
                   e.Bounds.Y, e.Bounds.Width+1, e.Bounds.Height+1);
        e.Graphics.FillRectangle(sbIconBackground, e.Bounds.X, 
                   e.Bounds.Y, 20, e.Bounds.Height+1);
        if(base.Text == "-")
        {
            e.Graphics.FillRectangle(sbIconBackground, e.Bounds.X+20, 
                       e.Bounds.Y+2, e.Bounds.Width-20, e.Bounds.Height-2);
        }
        else
        {
            Rectangle rIcon = new Rectangle(e.Bounds.X+1, e.Bounds.Y+2, 16, 16);
            if(iImage != null) e.Graphics.DrawIconUnstretched(iImage, rIcon);
            if((base.Checked)&&(iChecked != null))
                e.Graphics.DrawIconUnstretched(iChecked, rIcon);
            e.Graphics.DrawString(base.Text, fnt, sbTextColor, 
                                 e.Bounds.X+22, e.Bounds.Y+2);
            if((e.State & DrawItemState.Selected) != 0)
            {
                e.Graphics.FillRectangle(sbSelected, e.Bounds);
                e.Graphics.DrawRectangle(pBorder, e.Bounds.X, 
                           e.Bounds.Y, e.Bounds.Width-1, e.Bounds.Height-1);
            }
        }
    }
    catch(Exception x)
    {
        System.Diagnostics.Trace.WriteLine(x.ToString(), 
                           "WpmMenuItem ("+this.Text+"): Drawing ");
    }
}

protected override void OnMeasureItem(MeasureItemEventArgs e)
{
    try
    {
        if(base.Text == "-")
        {
            e.ItemHeight = 4;
        }
        else
        {
            e.ItemHeight = 18;
            e.ItemWidth = Convert.ToInt32(e.Graphics.MeasureString(this.Text, 
                                                              fnt).Width)+30;
        }
    }
    catch(Exception x)
    {
        System.Diagnostics.Trace.WriteLine(x.ToString(), 
               "WpmMenuItem ("+this.Text+"): Measuring ");
    }
}

All the properties used are private class members.

private Font fnt;
private Icon iImage;
private Icon iChecked;
private SolidBrush sbSelected;
private SolidBrush sbIconBackground;
private SolidBrush sbBackground;
private SolidBrush sbTextColor;
private Pen pBorder;

These properties are used to change background color, fore color, font, etc. In our case only the icon and the "checked" icon properties have been made public.

public System.Drawing.Icon Icon
{
    get { return iImage; }
    set
    {
        try
        {
            if(value != null)
            {
                iImage = new Icon(value, 16, 16);
            }
        }
        catch
        {
            iImage = null;
        }
    }
}

public System.Drawing.Icon CheckedIcon
{
    get { return iChecked; }
    set
    {
        try
        {
            if(value != null) iChecked = new Icon(value, 16, 16);
        }
        catch
        {
            iChecked = null;
        }
    }
}

Another thing to implement is the standard MenuItem behavior - make it act as a separator, or as checked or enabled, etc. We also implement a new feature - to be able to make it a "header" (line with some right-aligned text).

There is only one problem I did find with the class - I had an exception from the System.Drawing.Icon class when creating too many icons. But for static menus the class is really customizable and useful.

Thanks to Joel Matthias for his NotifyIconEx class.

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

About the Author

Nikita D. Sinelnikoff
Web Developer
Russian Federation Russian Federation
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWhat version of .Net?memberPaul A. Howes6 Dec '05 - 0:24 

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

Permalink | Advertise | Privacy | Mobile
Web02 | 2.6.130516.1 | Last Updated 28 Nov 2005
Article Copyright 2005 by Nikita D. Sinelnikoff
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid