Click here to Skip to main content
13,096,399 members (69,454 online)
Click here to Skip to main content
Add your own
alternative version

Stats

184.7K views
1.3K downloads
85 bookmarked
Posted 29 Feb 2004

MenuItem Extender - add images and font support to your menu

, 29 Feb 2004
Rate this:
Please Sign up or sign in to vote.
An extender provider component that provides Image and Font properties to a MenuItem class.

Sample context menu without XP theme applied

Figure 1.

Sample menu with XP theme applied

Figure 2.

Introduction

No need to say that many of us tried to decorate downcast appearance of standard menus. And so did I. First of all, I tried to find something suitable amongst already written code. And the best code that I've found belongs to Chris Beckett: Menu Images using C# and IExtenderProvider - a better mousetrap!, published on The Code Project.

Then I tried to make the code a bit more flexible: enable owner drawing for some menu items, not all, allow to use custom fonts for menu text and make an ImageIndex selector for VS Designer. Although not all problems were solved - I'll say about it below - you can use this code and I hope to improve it.

Using the MenuExtender

Because this article has appeared as a remaking of Chris' MenuImageLib class, I refer you to his article if you wish to know how to extend standard class behavior with IExtenderProvider. He clearly demonstrates how to add owner drawn menus without overriding OnMeasureItem and OnDrawItem for every menu item.

My version of the MenuExtender provides following properties to the MenuItem:

  • Draw an icon of any size
  • Draw a text with a custom Font or SystemInformation.MenuFont
  • Enable/disable the extender for particular menu items

The MenuExtender is applicable for non-top menu items and context menus. In order to use it in your project, add it to your VS toolbox:

  • Right-click on the "Windows Forms" tab in the Toolbox
  • Choose "Add/Remove Items..."
  • On the ".NET Framework Components", press the "Browse..." button and find a MenuExtender.dll

That will add a "MenuExtender" icon to the Windows Forms tab. Drag this icon to your form. By this action, you will add the MenuExtender component to your project:

private MenuExtender.MenuExtender menuExtender;
// :
this.menuExtender = new MenuExtender.MenuExtender(this.components);

Now you should set some properties for the MenuExtender. Using the Properties window, set an ImageList (if you have one) with images for icons on your menu items:

Figure 3.

If SystemFont is true, it means that texts on your menus will be displayed with the SystemInformation.MenuFont. If you wish to use some other font - just select it for the Font property and set SystemFont to false. That will generate the following code:

this.menuExtender.Font = new System.Drawing.Font("Tahoma", 9.75F,
    System.Drawing.FontStyle.Regular,
    System.Drawing.GraphicsUnit.Point,
    ((System.Byte)(204)));
this.menuExtender.ImageList = this.imageList;
this.menuExtender.SystemFont = false;

But I don't advice to do it in the beginning of your application. If a user's computer doesn't have the specified font installed - you'll get an exception. You can write this piece of code somewhere in "Customize your application" class. If you have already set some font and wish to return to default settings - right-click on the "Font" field and select "Reset".

And, at last, we can tune our menu items. Select one and find the "Menu Extender" category in the Property window:

Figure 4.

If ExtEnable is true - the menu item will be drawn by the MenuExtender. The ImageIndex is the index of the image item in the ImageList associated with the MenuExtender. Pay attention to OwnerDraw property - it is set to true automatically. Final code for a menu item looks like the following:

this.menuExtender.SetExtEnable(this.menuItem4, true);
this.menuExtender.SetImageIndex(this.menuItem4, 2);
this.menuItem4.OwnerDraw = true;

Now it's time to start the engine! Compile the test project and run it.

Tips & Tricks

If you compare the menu separators on Figure 1 and Figure 2, you can see that the left separator has a custom 3D look. It's because the MenuExtender was not enabled for this separator. I think it's better than to track XP theme switching.

Known Problems

I've found one serious limitation - this class cannot be used in a MDI application. The reason lies out of my class - it's a common problem for the framework. You can easily ascertain that your owner drawn menu items in a MainMenu of a MDI parent form can disappear. Create a MDI child form with its own menus added/merged to the parent. Open a few child forms and close them. Look at your MainMenu with owner drawn items - they are blank. The similar problem with owner drawn menus attached to a NotifyIcon component is described in the Knowledge Base article 827043.

Acknowledgements

I used a great many sources for my work. But the first one was Menu Images using C# and IExtenderProvider - a better mousetrap! by Chris Beckett.

Another good resource is Dino Esposito's article in the MSDN Magazine - Cutting Edge: Owner-Drawing in .NET.

History

February 23rd, 2004 - First release.

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

Share

About the Author

Jevgenij lives in Riga, Latvia. He started his programmer's career in 1983 developing software for radio equipment CAD systems. Created computer graphics for TV. Developed Internet credit card processing systems for banks.
Now he is System Analyst in Accenture.

You may also be interested in...

Comments and Discussions

 
RantFont change does not apply to all Pin
Member 145798523-Jun-09 22:47
memberMember 145798523-Jun-09 22:47 
GeneralAdding menu items dynamically in vb6 Pin
S.M..kanerkar17-Jan-09 1:39
memberS.M..kanerkar17-Jan-09 1:39 
GeneralTo install sql server 2000 on vista Pin
S.M..kanerkar17-Jan-09 1:33
memberS.M..kanerkar17-Jan-09 1:33 
GeneralExtEnable = True Default for ALL items Pin
Mr.Jinky30-Jul-08 23:42
memberMr.Jinky30-Jul-08 23:42 
QuestionProblems doing menuExtender.SetExtEnable(item, false) Pin
Manfred Weigl27-Aug-07 5:24
memberManfred Weigl27-Aug-07 5:24 
GeneralI can't found MenuExtender.dll Pin
rooh5720015-Feb-07 23:36
memberrooh5720015-Feb-07 23:36 
Generaldon't work in trayicon context menu Pin
Deemc29-Jan-07 6:09
memberDeemc29-Jan-07 6:09 
GeneralRe: don't work in trayicon context menu Pin
Deemc29-Jan-07 7:44
memberDeemc29-Jan-07 7:44 
GeneralMenuExtender Right-To-Left Pin
czaval28-Oct-06 22:33
memberczaval28-Oct-06 22:33 
GeneralNever Mind Pin
smokingbrat29-Dec-05 12:07
membersmokingbrat29-Dec-05 12:07 
GeneralRe: Never Mind Pin
Marcelo Miorelli18-Sep-06 0:02
memberMarcelo Miorelli18-Sep-06 0:02 
QuestionQuestion Pin
smokingbrat29-Dec-05 10:35
membersmokingbrat29-Dec-05 10:35 
GeneralFONT IN APPLICATION Pin
datvpsc776-Dec-05 15:11
memberdatvpsc776-Dec-05 15:11 
GeneralProblems when using it with combobox Pin
ExXon31-Oct-05 4:38
memberExXon31-Oct-05 4:38 
GeneralExcellent ! Pin
kim.hauser25-Oct-05 4:50
memberkim.hauser25-Oct-05 4:50 
GeneralNot only MDI Pin
Alexey A. Popov20-Oct-05 1:22
memberAlexey A. Popov20-Oct-05 1:22 
GeneralRe: Not only MDI Pin
datvpsc776-Dec-05 16:41
memberdatvpsc776-Dec-05 16:41 
GeneralRe: Not only MDI Pin
Alexey A. Popov8-Dec-05 19:32
memberAlexey A. Popov8-Dec-05 19:32 
GeneralRe: Not only MDI Pin
datvpsc7712-Dec-05 17:22
memberdatvpsc7712-Dec-05 17:22 
GeneralRe: Not only MDI Pin
datvpsc7714-Dec-05 22:28
memberdatvpsc7714-Dec-05 22:28 
GeneralMenuItem Mouseover Pin
Jacques Crocker24-May-05 11:53
memberJacques Crocker24-May-05 11:53 
QuestionHow can I add a "name" as property ??? Pin
AgnesCheng27-Mar-05 17:45
memberAgnesCheng27-Mar-05 17:45 
GeneralI'm getting an error "Does not have a strong name" Pin
dakrin17-Mar-05 13:31
memberdakrin17-Mar-05 13:31 
GeneralRe: I'm getting an error "Does not have a strong name" Pin
dakrin18-Mar-05 7:56
memberdakrin18-Mar-05 7:56 
GeneralmenuItem.Checked Doesn't work Pin
id10t20-Feb-05 7:23
memberid10t20-Feb-05 7:23 
Generaldataset in dotnet Pin
assisi19-Feb-05 0:34
memberassisi19-Feb-05 0:34 
GeneralAdd MenuItem in VC++ 7.1 Pin
Len202025-Oct-04 13:06
memberLen202025-Oct-04 13:06 
GeneralA simple improvement Pin
daima(nt)30-Sep-04 23:35
memberdaima(nt)30-Sep-04 23:35 
GeneralProperties not present on inherited forms Pin
sssuthe28-Sep-04 10:15
membersssuthe28-Sep-04 10:15 
GeneralRe: Properties not present on inherited forms Pin
Eugene Pankov28-Sep-04 22:37
memberEugene Pankov28-Sep-04 22:37 
GeneralRe: Properties not present on inherited forms Pin
sssuthe29-Sep-04 5:37
membersssuthe29-Sep-04 5:37 
GeneralRe: Properties not present on inherited forms Pin
sssuthe29-Sep-04 7:12
membersssuthe29-Sep-04 7:12 
GeneralGreat code, but one question Pin
luo hao28-Aug-04 22:29
memberluo hao28-Aug-04 22:29 
GeneralGreat code, one question though. Pin
davegalligher1-Jun-04 13:10
memberdavegalligher1-Jun-04 13:10 
GeneralRe: Great code, one question though. Pin
Eugene Pankov2-Jun-04 0:50
sussEugene Pankov2-Jun-04 0:50 
GeneralRe: Great code, one question though. Pin
davegalligher2-Jun-04 4:37
memberdavegalligher2-Jun-04 4:37 
GeneralRe: Great code, one question though. Pin
Eugene Pankov3-Jun-04 3:06
memberEugene Pankov3-Jun-04 3:06 
GeneralOwnerDraw for NotifyIcon Pin
Le(Ge)228-May-04 15:55
memberLe(Ge)228-May-04 15:55 
GeneralThanks again Pin
-=MaXiMuS=-17-Mar-04 4:12
member-=MaXiMuS=-17-Mar-04 4:12 
GeneralThanks Pin
Yuri Ovchinnikov9-Mar-04 8:07
memberYuri Ovchinnikov9-Mar-04 8:07 

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.

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.170813.1 | Last Updated 1 Mar 2004
Article Copyright 2004 by Jevgenij Pankov
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid